我有一个坚持的任务。我需要创建一个程序来读取输入文件,并将每个单词与该单词被读取的次数一起存储到 vector 中(因此构造该结构)。然后,这些值需要按字母顺序打印。
我想出了一些我认为正确的方法:
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语句中,但是我对其进行修复的尝试并不理想。任何帮助表示赞赏。干杯。
编辑:我忘了提及,我们必须使用 vector 类,并且我们只能使用有限的东西,而排序不是一种选择:(
最佳答案
if (word < uwords[i].text) {
uwords.push_back(WordInfo());
WordInfo temp = {word, 1};
uwords.insert(uwords.begin() + i, temp);
}
看一下这段代码:
首先,它实际上会在您的列表中插入2个单词;一次用
push_back
来“清空”,一次用insert
来。只要当前单词小于i
位置的单词,它就会这样做。插入后,有2个新元素需要遍历。一个实际上位于
i
的当前位置,因此在下一次迭代中,我们将再次比较相同的单词-这样,您的循环将陷入困境,因为索引i
每次迭代均增加1,但是i
的增加仅遍历刚插入的元素!快速解决方案是,您要(1)搜索比当前单词“小”但下一个单词大的位置。就像是
if (uwords[i-1].text < word && word < uwords[i].text) {
(2)并且您想要摆脱
push_back
调用。此外,(3)您可以在if条件为true之后中断循环-您已经插入了then,而无需进一步迭代。和(4),通过一些条件调整,
count == 1
实际上可以合并到循环中。修改后的代码部分(将替换整个if (code == false)
块-警告,尚未测试):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;
}
}
}