我输入来自文件input.txt作为两列字符串,例如:
string1 string2
string3 string4
etc.
我正在尝试从0开始按升序对字符串进行编号,但这样的方式是重复字符串不会被赋予新值,但保留已经分配给它们的一次。 我决定使用set :: find操作来做到这一点,但我很难让它工作。这是我到目前为止所做的:
int main(int argc, char* argv[]) {
std::ifstream myfile ("input.txt");
std::string line;
int num = 0; // num is the total number of input strings
if (myfile.is_open()) {
while(std::getline(myfile, line)) {
++num;
}
}
std::string str1, str1; // strings form input
int str1Num, str2Num; // numbers assigned to strings
int i = 0; // used to assign values to strings
StringInt si;
std::vector<StringInt> saveStringInts(num);
std::set<std::string> alreadyCounted(num, 0);
std::set<std::string>::iterator sit;
std::ifstream myfile2 ("input.txt");
if (myfile2.is_open()) {
while(myfile2.good()) {
// read in input, put it in vars below
myfile2 >> str1 >> str2;
// if strings are not already assigned numbers, assign them
if ((*(sit = alreadyCounted.find(str1)).compare(str1) != 0) { // doesn't work
str1Num = i++;
alreadyCounted.insert(str1);
saveStringInts.push_back(StringInt(str1Num));
}
else {
str1Num = si->getNum(str1);
}
if ((*(sit = alreadyCounted.find(str2)).compare(str2) != 0) {
str2Num = i++;
alreadyCounted.insert(str2);
saveStringInts.push_back(StringInt(str2Num));
}
else {
str2Num = si->getNum(str2);
}
// use str1 and str2 in the functions below before the next iteration
}
}
不幸的是,我尝试了其他方法,现在完全卡住了。如果您知道如何修复我的代码或建议更好的方法来完成我的任务,我将非常感谢您的帮助。
答案 0 :(得分:5)
您需要将std::set<int>::iterator
与集合的end()
迭代器进行比较,而不是取消引用迭代器并将其值与某些内容进行比较!实际上,对end()
迭代器的引用是未定义的行为:
if ((*(sit = alreadyCounted.find(str1)).compare(str1) != 0) // WRONG: don't do that!
应该是
if (alreadyCounted.find(str1) != alreadyCounted.end())
......同样是另一个字符串。就个人而言,我会使用不同的技术:当insert()
进入std::set<T>
时,你会得到一对迭代器和指示对象是否被插入的指示符。后者与当前集合的大小一起给出了下一个值,例如:
bool result = alreadyCounted.insert(str1).second;
strNum1 = result? alreadyCounted.size() - 1: si->getNum(str1);