1

一連の単語があり、関連性によってランク付けされています。Relevance は別のベクトルに格納された float ですが、2 つのベクトルの位置が互いに相関していることがわかります。

float floatTemp1, floatTemp2;
string stringTemp1, stringTemp2;
for(int m=0; m<PlayList.size()-1; m++){
    for(int i=0; i<PlayList.size(); i++){
        if(storedRelevance[i+1]>storedRelevance[i]){
            floatTemp1 = storedRelevance[i];
            floatTemp2 = storedRelevance[i+1];
            storedRelevance[i]= floatTemp2;
            storedRelevance[i+1] = floatTemp1;
            stringTemp1 = relevantPlays[i];
            stringTemp2 = relevantPlays[i+2];
            relevantPlays[i]= stringTemp2;
            relevantPlays[i+1]= stringTemp1;
        }
    }
}

基本的に、位置 [1] のベクトルの関連性が [0] の関連性よりも大きい場合、関連性ベクトルと文字列ベクトルの両方で要素の位置を入れ替えます。実行するたびにセグメンテーション違反が発生します。

4

5 に答える 5

11

structa を使用して 1 つのことに関するすべての情報 (たとえば、単語、関連性など) を保存してから、関連性の値を比較std::sortする関数 orを使用することをお勧めします。functor

于 2013-09-16T19:08:03.517 に答える
1

元の配列を同じ順序に保つことができますが、ソートされた間接性を持つことができます。

std::vector<int>    sorted(PlayList.size());
for(int loop=0;loop < sorted.size();++loop) { sorted[loop] = loop;}

std::sort(sorted.begin(), sorted.end(),
           [](int lhs, int rhs){return storedRelevance[lhs]<storedRelevance[rhs]});


// Now you can access your playlist in order via the sorted vector.

// First Item
std::cout << relevantPlays[sorted[0]] << " " << storedRelevance[sorted[0]] << "\n";
于 2013-09-16T19:26:43.217 に答える
1

[i+1] および [i+2] インデックスは、ベクトル ストレージのどこかを呼び出すことがあります。

そのため、セグメンテーション違反があります。

これを行うより良い理由は、構造体を使用してデータをカプセル化することです

Struct Play {
    float score;
    string name;
}

そして、あなたのベクトルでは、呼び出すだけです

std::sort(Playlist.begin(), Playlist.end());

std::sort は <アルゴリズム> に含まれています

于 2013-09-16T19:28:56.843 に答える
0

あなたのアプローチにはさまざまなレベルの問題がいくつかあります。

問題 #1、i+1 は PlayList.size() を超える可能性があります。

 for ( ... i < storedRelevance.size() ... )
        if(storedRelevance[i+1]>storedRelevance[i]){

m と i の条件が間違っていると思います。

問題#2、1つの場所から両方の値をコピーしてから、それらの1つだけを「パーク」する必要がある場合に、それらを別の場所にコピーします。

            floatTemp1 = storedRelevance[i];
            floatTemp2 = storedRelevance[i+1];
            storedRelevance[i]= floatTemp2;
            storedRelevance[i+1] = floatTemp1;

より良い

            floatTemp = storedRelevance[i];
            storedRelevance[i] = storedRelevance[i+1];
            storedRelevance[i+1] = floatTemp;

またはまだ良い

            std::swap(storedRelevance[i], storedRelevance[i+1]);

ただし、i+1 は現在の実装で PlayList.size() を超える可能性があります。

大問題:

            stringTemp1 = relevantPlays[i];
            stringTemp2 = relevantPlays[i+2];

その +2 は...間違った文字列のように見え、間違いなく配列サイズを超えます。

            relevantPlays[i]= stringTemp2;
            relevantPlays[i+1]= stringTemp1;

また、ソートが常に O(N^2) の複雑さを要することを確認する以外に、外側の「m」ループの目的を理解していませんか?

ソートの実装方法を理解するための演習としてこれを行っているだけの場合は、次の代替アプローチのいずれかを検討することをお勧めします。

方法 1: 構造体/クラスを使用して値の局所性を与える (これC++ です)

struct PlayListSearchResult {
    int m_relevance;
    const string& m_word; // a reference, so a short lifetime for these objects.

    PlayListSearchResult(int relevance_, const std::string& word_)
        : m_relevance(relevance_)
        , m_word(word_)
    {}
};

typedef std::vector<PlayListSearchResult> PlayListSearchResults;

// the sort:
     // given PlayListSearchResults results or &results:

     const numResults = results.size();
     bool needsRedo;
     do {
         needsRedo = false;
         for (size_t i = 0; i < numResults - 1; ++i) {
             if (!(results[i + 1].m_relevance < results[i].m_relevance))
                 continue;
             std::swap(results[i], results[i + 1]);
             needsRedo = true;
         }
     } while (needsRedo);

方法 2: インデックスの配列を作成します。

std::vector<size_t> indexes;
for (size_t i = 0; i < results.size(); ++i) {
    indexes.push_back(i);
}

// do the sort, but instead of swapping relevance/word, just swap the index.

それ以外の場合は、std::sortまたはstd::mapを調べてください

于 2013-09-16T19:51:23.330 に答える
0

std::map<float, std::string>要素が追加されるとデータがソートされるため、使用します。

std::map<float, std::string> relevance_mapping;
std::vector<std::string> words;
std::vector<float> relevance;
//...

for(std::size_t i = 0; i < words.size(); i++) {
    relevance_mapping[relevance[i]] = words[i];
}

これで反復処理が可能relevance_mappingになり、関連性でソートされたデータが得られます。

于 2013-09-16T19:19:43.790 に答える