先看看问题:输入一个字符串,输出删除了重复的字符后的字符串。在之前的文章中,我写了一篇《输入一个字符串,输出第一个重复的字符》(不过,这个算法只限于两个重复字符!哎,还是散列表好啊!)。我们就可以借鉴那篇文章,先看看实现:
首先呢,我们将重复的元素的索引传递给一个数组。刚开始的时候,我尝试利用string类的erase函数来移除重复的元素,装逼失败。很简单,我没有考虑移除元素之后,string的长度会变化,这样的话,当我们在进行删除操作的时候,有可能我们需要删除的元素的索引值大于了已经删除了元素的string字符串现在的长度!这样的话,编译器就会报错!那么怎么弄呢?利用string迭代器就行了!可是呢,当我们定义了itrerator后就要注意一个问题了。我们需要在每次删除元素是,都给这个迭代器赋初值,而且是迭代器刚开始的位置。这是需要注意的哦!要不然,还会是有之前那个索引与长度不和的问题,编译器依旧报错。解决了这些问题之后,我们就可以利用advance来移动iterator迭代器来移动指针,指向我们要删除的元素的索引位置。下面看看源代码:
//删除string重复的元素
#include "iostream"
#include "string"
#include "windows.h"
#include "stdio.h"
using namespace std;
int main()
{
string str;
const char *a;
int len,n;
int num=0;
string s;
int i;
int index;
string::iterator pos;
int b[10];
memset(b,0,10);
cin>>str;
len=str.length();
a=str.c_str();
cout<<"删除了重复的元素后的字符串:"<<endl;
for(i=0; i<len; i++)
{
index=str.find(a[i],i+1);
if(index!=str.npos&&i+1<len)
{
b[num++]=index;//将重复的元素的索引在数组中存好!
}
}
for(i=0; i<num; i++)
{
b[i]=b[i]-i;//删除了一个元素之后,就递减string的长度
pos=str.begin();
std::advance(pos,b[i]);//移动iterator指向每次要删除的元素的索引
str.erase(pos);
}
cout<<str;
system("pause");
return 0;
}
其实呢,我们之前说的那个问题也就解决了!那就是只限于两个重复元素的问题。怎么解决了呢?期待吧!