对某些代码有些麻烦。规则是如果两个字符必须匹配,则必须删除重复的字母。因此,例如“通常”将更改为“Usualy”。
代码确实有效,但它没有按照上面提到的那样做。
我将在下面发布代码,评论在问题点上方发表评论。
#include <iostream>
#include <list>
#include <ctype.h>
#include <fstream>
using namespace std;
void printList(const list<char> &myList);
void fillList(list<char> &myList);
void change(list <char> &myList);
void printList(const list<char> &myList)
{
list<char>::const_iterator itr;
for (itr = myList.begin(); itr != myList.end(); itr++ )
{
cout <<*itr;
}
cout << '\n' << endl;
}
void fillList(list<char> &myList)
{
ifstream file("test.txt");
string print;
while(file >> print)
{
for (int i = 0; i<=print.length(); i++)
{
myList.push_back(print[i]);
}
myList.push_back(' ');
}
}
void change(list <char> &myList)
{
list<char>::iterator itr;
//rules are as follows
//change w with v
for (itr = myList.begin(); itr != myList.end(); itr++ )
{
if (*itr == 'w')
{
*itr = 'v';
}
}
// double letter become single letter here
//PROBLEM IS HERE!
for (itr = myList.begin(); itr != myList.end(); itr++ )
{
std::list<char>::iterator itr2 = itr;
if(*(++itr2) == *itr)
{
myList.remove(*itr);
}
}
}
int main ()
{
list<char> myList;
ifstream file("test.txt");
const string print;
fillList(myList);
printList(myList);
change(myList);
printList(myList);
return 0;
}
答案 0 :(得分:-1)
问题是你在使用相同的迭代器遍历它时修改列表:
for (itr = myList.begin(); itr != myList.end(); itr++ )
{
std::list<char>::iterator itr2 = itr;
if(*(++itr2) == *itr)
{
myList.remove(*itr);
}
}
你想做更像这样的事情:
for (itr = myList.begin(); itr != myList.end(); )
{
std::list<char>::iterator before = itr++;
if(*itr != myList.end() && *before == *itr)
{
myList.erase(before);
}
}
答案 1 :(得分:-1)
list
中的第二个循环正在修改iterator
,同时迭代它,但您没有更新循环list::erase()
来解释它。删除指定的项目后,iterator
会向列表中的下一个项目返回++itr2
。
您也没有考虑到end()
可以生成#include <algorithm>
void change(std::list<char> &myList)
{
//rules are as follows
//change w with v
std::replace(myList.begin(), myList.begin(), 'w', 'v');
// double letter become single letter here
list<char>::iterator itr = myList.begin();
while (itr != myList.end())
{
std::list<char>::iterator itr2 = itr++;
if ((itr != myList.end()) && (*itr2 == *itr))
{
myList.erase(itr2);
// or: itr = myList.erase(itr);
}
}
}
迭代器,这种取消引用是不安全的。
请改为尝试:
#include <algorithm>
void change(std::list<char> &myList)
{
//rules are as follows
//change w with v
std::replace(myList.begin(), myList.begin(), 'w', 'v');
// multiple letter become single letter here
std::list<char>::iterator itr = std::unique(myList.begin(), myList.end());
myList.erase(itr, myList.end());
}
更简单的解决方案是使用std::unique()
代替(如果您不介意一次删除3个以上的重复项):
从[first,last]范围中删除所有连续的重复元素,并返回范围的新逻辑结尾的过去的迭代器。
<access origin="*" />
<access origin="*://*.googleapis.com/*" subdomains="true" />
<access origin="*://*.gstatic.com/*" subdomains="true" />
<access origin="*://*.google.com/*" subdomains="true" />
<access origin="*://*.googleusercontent.com/*" subdomains="true" />