这天,在bat群里面有个哥们提出一个问题:
//string str =
"zhaohaoyang";
//如何去除重复出现的字符,而且保持原序列的相对位置不变,例如这个例子会变成zyng
当时首先想到的,脑袋中出现得竟然是map容器,因为它不会存储重复的key值,于是,我写起下面这段代码:
mapvector
> char_repeator;
intinput;
intnumber
= 0;
while(EOF!=
(input = getchar())){
char_repeator[input].push_back(++number);
}
for(mapvector
>::const_iterator iter = char_repeator.begin(); iter!=
char_repeator.end(); ++iter){
if(1==
iter->second.size())
cout<<
iter->first;
}
cout
<< endl;
输出结果:
我们想得到的结果是eca,没想到最后却是ace,这是因为map会自动对key排序。
此路不通,寻问别人。
甘哥说,可以用unique,于是我上网找了一篇文章,了解了一下,开干,写了下面这段代码:
string
str = "zhaohaoyang";
vector
vecch(str.begin(), str.end());
//根据迭代器的起始位置和终止位置来定初始化一个容器
vector::iterator
it = vecch.begin();
for
(; it != vecch.end(); ++it)
{
cout<
}
cout
<< endl;
sort(str.begin(),str.end());
cout<< str
<
str.erase(unique(str.begin(),
str.end()), str.end());
cout
<< str <
输出结果:
结果依然不理想,和map的结果类似,unique只对相邻且重复的字符去重得唯一,但不能对不相邻的去重得唯一,
故还是不行。
此路不通,再次寻问别人。
晓卫说,可以创建三个数组来记录,用数组模拟散列,我一听晕了,真得能做到吗?怀着半信半疑的态度把代码写完,发现:
charorgin[]
= {"zhaohaoyang"};//应该输出zyng
chartemp[128];//按序暂存字符
chardest[128];//存放结果
intcountor[128]
= {0};//统计字符个数
intlength
= strlen(orgin);
memset(temp,'\0',
sizeof(dest));
memset(dest,'\0',
sizeof(dest));
intj
= 0;
for(inti
= 0; i != length; ++i){
if(1
== ++countor[orgin[i]])
temp[j++]=
orgin[i];
}
j=
0;
for(inti
= 0; temp[i] != '\0'; ++i)
if(1==
countor[temp[i]])
dest[j++]=
temp[i];
printf("\n%s\n",orgin);
printf("%s\n",
dest);
输出结果:
发现真得成功了。主要是需要一个数组来存放字符的顺序,然后取出现次数为1的字母加进目标数组就行了。
后来想想,因为我们的目的是去重,所以一共128个可输入字符(可见字符其实是93个),每个字符至多出现一次,所以我们得到的最后字符串并不繁琐,反而很简单,从我们创建的字符数组的大小是128就可以得知,得到的最后字符串的大小最多是128。
自己转了一个大弯子,本来用C语言老老实实写的程序,非得用C++,这,你说能不郁闷吗?
在bat群里的一哥们也提出一种方案,用vbs的len(replace(str,”z”,””))依次替换每一个字符后计算长度来判断是否重复,
这个方法理论上是可以的,只不过效率可能略低,因为要依次替换,还要计算长度。但是也是一种思路,多动脑毕竟是好事。
所以,思路还需灵活,思路决定出路,我还需要多多学习,最后,感谢各位兄弟的帮忙。