我有一个我坚持的任务。我需要创建一个程序来读取输入文件,将每个单词存储到一个向量中以及该单词被读取的次数(因此结构)。然后,这些值需要按字母顺序打印出来。
我想出了一些我认为正确的方法:
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语句中,但我尝试修复它并不好。任何帮助表示赞赏。干杯。
编辑:我忘了提及,我们必须使用矢量类,我们的限制在于我们可以使用的东西,并且排序不是一个选项:(答案 0 :(得分:2)
if (word < uwords[i].text) {
uwords.push_back(WordInfo());
WordInfo temp = {word, 1};
uwords.insert(uwords.begin() + i, temp);
}
仔细看看这段代码:
首先,它会在您的列表中插入2个单词;一次&#34;空&#34;一个push_back
,一个insert
。只要当前单词小于i
位置的单词,它就会这样做。
一旦插入,就会有2个新元素走过去;一个实际上位于i
的当前位置,所以在下一次迭代中,我们将再次比较同一个单词 - 因此你的循环被卡住,因为索引i
每次迭代增加1,但增加i
仅覆盖刚刚插入的元素!
对于快速解决方案,您希望(1)搜索之前单词的位置是&#34;较小的&#34;比现在的,但下一个更大。像
这样的东西if (uwords[i-1].text < word && word < uwords[i].text) {
(2)你想摆脱push_back
电话。
此外,(3)你可以在if条件为真之后中断循环 - 你已经插入了,不需要进一步迭代。并且(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;
}
}
}
答案 1 :(得分:2)
你不应该把你的单词推到向量中,而是在地图中
std::map<std::string,int>
由于map在地图上具有可比较的键迭代器,因此自动返回已排序的范围,如果需要,可以稍后将其推入向量中。