1

我有一串单词,它们按相关性排序。相关性是存储在单独向量中的浮点数,但我认为这两个向量的位置相互关联。

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

我建议您使用 astruct来存储有关单个事物的所有信息(例如,单词,它的相关性等),然后std::sort与函数一起使用或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

使用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 回答
0

你的方法有几个不同层次的问题。

问题 #1,i+1 可能超过 PlayList.size()。

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

我认为你有你的条件 m 和 i 循环错误的方式。

问题#2,你从一个地方复制两个值,然后将它们复制回其他地方,当你只需要“停放”其中一个时:

            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::sortstd::map

于 2013-09-16T19:51:23.330 回答