C++ 简单';对于';最终迭代中的循环崩溃程序
下面的程序似乎每次都会在最后崩溃,我假设这是因为一旦我达到I=(size-1),wordList[I+1]将不会返回任何内容、返回null或类似的内容。有办法吗?我认为这是我问题的根源,对吗C++ 简单';对于';最终迭代中的循环崩溃程序,c++,loops,C++,Loops,下面的程序似乎每次都会在最后崩溃,我假设这是因为一旦我达到I=(size-1),wordList[I+1]将不会返回任何内容、返回null或类似的内容。有办法吗?我认为这是我问题的根源,对吗 #include <iostream> #include <string> #include <vector> #include <algorithm> #include <iomanip> using std::cin; using std::
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <iomanip>
using std::cin;
using std::cout; using std::endl;
using std::sort;
using std::string; using std::vector;
// Obtain a list of words and return the de-duped list
// with an accompanying word count
int main()
{
cout << "Enter a series of words separated by spaces, "
"followed by end-of-file: ";
vector<string> wordList;
string x;
while (cin >> x)
wordList.push_back(x);
typedef vector<string>::size_type vec_sz;
vec_sz size = wordList.size();
if (size == 0) {
cout << endl << "This list appears empty. "
"Please try again." << endl;
return 1;
}
sort(wordList.begin(), wordList.end());
cout << "Your word count is as follows:" << endl;
int wordCount = 1;
for (int i = 0; i != size; i++) {
if (wordList[i] == wordList[i+1]) {
wordCount++;
}
else {
cout << wordList[i] << " " << wordCount << endl;
wordCount = 1;
}
}
return 0;
}
#包括
#包括
#包括
#包括
#包括
使用std::cin;
使用std::cout;使用std::endl;
使用std::sort;
使用std::string;使用std::vector;
//获取单词列表并返回重复数据消除列表
//附带字数
int main()
{
cout>x)
单词列表。推回(x);
typedef vector::size_type vec_sz;
vec_sz size=wordList.size();
如果(大小==0){
你可能想试试
for (int i = 0; i < size; i++)
for(int i=0;i
这将阻止循环尝试寻址超出边界的索引。是。边界条件失败。vector[size()]
是未定义的值
if (wordList[i] == wordList[i+1]) ---> out of bounds
解决方法可能是迭代size()-1
,这正是问题所在。您的向量包含“大小”项,但您试图访问向量的末尾
您需要做的是在最后一项之前停止for循环,以便i+1只访问最后一项
例如:
for (int i = 0; i < (size - 1); i++) {
for(int i=0;i<(大小-1);i++){
更改
for (int i = 0; i != size; i++) {
到
这是因为对于i==size-1,i+1==size。而wordList[size]不在列表的末尾。您可能需要将for循环条件更改为“i您应该将代码更改为for(int i=0;i
因为在wordList[i+1]
i+1
的值必须小于size
。这意味着i
Is C/C++数组可以具有从
0
到size-1
的索引。它不是空的,超出范围。在进行比较之前,至少应该检查iif (wordList[i] == wordList[i+1])
您需要提前一次停止循环(ifor(int i = 1; i < size; i++) {
if(wordList[i - 1] == wordList[i]) {
/* same as before */
}
/* everything else the same */
}
for(int i=1;i
这将防止您需要额外的if语句,但仍将保护您不离开数组的边界
编辑:
正如在注释中提到的,如果您使用所有原始代码,并像我提到的那样更改循环,将出现off-by-1错误,但很容易修复
从1开始计算字数,而不是从0开始。您知道,您将始终至少有一个唯一的字数。循环每次看到一个新词时都会增加该计数,因此您将得到正确的计数
您需要的唯一额外处理是当单词列表为空时。因此,您需要快速检查单词列表是否为空,在这种情况下,计数为0。您可以检查i==单词列表长度并退出/跳过if。您需要两个更改。如前面的注释所述,您的结束条件应为<大小为1以防止读取超出范围。您还需要打印最后一项的计数,这将是wordCount,因为如果它的唯一wordCount为1,则已添加。更正代码:
for (int i = 0; i < size-1; i++) {
if (wordList[i] == wordList[i+1]) {
wordCount++;
}
else {
cout << wordList[i] << " " << wordCount << endl;
wordCount = 1;
}
}
cout << wordList[size-1] << " " << wordCount << endl;
for(int i=0;i cout有时候,如果您使用其他工具,代码可能会简单得多
问题陈述:返回一个重复数据消除后的单词列表,每个单词对应一个计数
就我个人而言,我会为这样一个声明选择一个std::map
// Yeah it feels stupid, but I want default construction to initialize...
struct MyCount
{
MyCount() : _count(0) {}
size_t _count;
};
std::ostream& operator<<(std::ostream& out, const MyCount& rhs)
{
return out << rhs._count;
}
int main()
{
cout << "Enter a series of words separated by spaces, "
"followed by end-of-file: ";
typedef std::map<std::string, MyCount> map_type;
map_type wordList;
std::string x;
while (std::cin >> x)
wordList[x] += 1; // This is why I have a struct instead of a plain size_t
if (wordList.empty()) {
cout << endl << "This list appears empty. "
"Please try again." << endl;
return 1;
}
cout << "Your word count is as follows:" << endl;
for (map_type::const_iterator it = wordList.begin(), end = wordList.end(); it != end; ++ it) {
std::cout << it->first << " " << it->second << std::endl;
}
return 0;
}
//是的,这感觉很愚蠢,但我希望默认构造能够初始化。。。
结构MyCount
{
MyCount():_count(0){}
大小和数量;
};
std::ostream&operatorWhile<优于!=,这实际上并不是问题所在。他正在访问wordList[i+1],当i==size-1时,它将失败。但这难道不意味着wordList[0]不在计数范围内,因为else语句下的cout命令从wordList[1]开始并从那里递增吗?还有一系列单词,例如“a b c c d”它将从第一个“b”开始,发现b!=a,然后打印“b 1”,不是吗?当正确的输出将从“a 1”开始,然后是“b 2”"?棒极了。看起来你抓住了我的两个顾虑-出界问题以及如何抓住列表中的最后一个词。仅仅更改为“i// Yeah it feels stupid, but I want default construction to initialize...
struct MyCount
{
MyCount() : _count(0) {}
size_t _count;
};
std::ostream& operator<<(std::ostream& out, const MyCount& rhs)
{
return out << rhs._count;
}
int main()
{
cout << "Enter a series of words separated by spaces, "
"followed by end-of-file: ";
typedef std::map<std::string, MyCount> map_type;
map_type wordList;
std::string x;
while (std::cin >> x)
wordList[x] += 1; // This is why I have a struct instead of a plain size_t
if (wordList.empty()) {
cout << endl << "This list appears empty. "
"Please try again." << endl;
return 1;
}
cout << "Your word count is as follows:" << endl;
for (map_type::const_iterator it = wordList.begin(), end = wordList.end(); it != end; ++ it) {
std::cout << it->first << " " << it->second << std::endl;
}
return 0;
}