C按字母顺序对结构向量排序

 2021-04-08 

C++ Sorting a struct vector alphabetically

我有一个坚持的任务。我需要创建一个程序来读取输入文件,并将每个单词与该单词被读取过多少次一起存储到一个向量中(因此该结构)。然后,这些值需要按字母顺序打印。

我想出了一些我认为正确的方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
struct WordInfo {
string text;
int count;
} uwords, temp;

string word;
int count = 0; //ignore this. For a different part of the task
vector<WordInfo> uwords;

while (cin >> word) {
    bool flag = false;
    count += 1;
    for (int i = 0; i < uwords.size(); i++) {
        if (uwords[i].text == word) {
            flag = true;
            uwords[i].count += 1;
        }
    }
    if (flag == false) {
        if (count == 1) { //stores first word into vector
            uwords.push_back(WordInfo());
            uwords[0].count = 1;
            uwords[0].text = word;
        } else {
            for (int i = 0; i < uwords.size(); i++) {
                if (word < uwords[i].text) {
                    uwords.push_back(WordInfo());
                    WordInfo temp = {word, 1};
                    uwords.insert(uwords.begin() + i, temp);
                }
            }
        }
    }
}

现在我遇到的问题是,当我运行该程序时,它似乎陷入了无限循环,而我看不到为什么。尽管我已经进行了足够的测试以意识到可能在最后的if语句中,但是我对其进行修复的尝试并不理想。任何帮助表示赞赏。干杯。

编辑:我忘了提,我们必须使用向量类,并且我们只能使用向量,而排序不是一种选择:(


您不应在矢量中压入单词,而应在地图中压入

1
std::map<std::string,int>

由于map在map上具有可比较的键迭代器,因此自动返回排序后的范围,如果需要,可以稍后将其推入vector中。


1
2
3
4
5
            if (word < uwords[i].text) {
                uwords.push_back(WordInfo());
                WordInfo temp = {word, 1};
                uwords.insert(uwords.begin() + i, temp);
            }

看一下这段代码:

首先,它实际上会在您的列表中插入2个单词;一次使用"空"使用push_back,一次使用insert。只要当前单词小于位置i

的单词,它就会这样做。

插入后,有两个新元素可以遍历;一个实际上位于i的当前位置,因此在下一次迭代中,我们将再次比较相同的单词-这样,由于索引i每次迭代增加1,而您的循环陷入困境,但i的增加仅跨过刚刚插入的元素!

作为一种快速解决方案,您想要(1)搜索前一个单词比当前单词"小"但下一个更大的位置。

之类的东西

1
if (uwords[i-1].text < word && word < uwords[i].text) {

(2),您想摆脱push_back调用。

此外,(3)您可以在if条件为true之后中断循环-您已经插入了then,而无需进一步迭代。和(4),通过一些条件调整,count == 1实际上可以合并到循环中。修改后的代码部分(将替换整个if (code == false)块-警告,尚未测试):

1
2
3
4
5
6
7
8
9
10
if (!flag) {
    for (int i = 0; i <= uwords.size(); ++i) {
        if ((i == 0 || uwords[i-1].text < word) &&
            (i == uwords.size() || word < uwords[i].text)) {
            WordInfo temp = {word, 1};
            uwords.insert(uwords.begin() + i, temp);
            break;
        }
    }
}