C++里面如何去除一个字符串里面重复字符
显然:大家可以使用两重循环完成这个操作,但是今天小编带大家学一下更加简单高效的方法完成字符串的去重,这个小编会在文章中讲到。
例子:string str = “abeaacda”;(小编全文将用这个例子);
处理后:"abcde"
各路方法
1,两层for循环
时间复杂度高,代码也多
## 时间复杂度高,代码也多 效率低
int i, j, k;
for(i = k = 0; i < str.size(); i++)
{
if(str[i])
{
str[k++] = str[i];
for(j = i + 1; j < str.size(); j++)
if(str[j] == str[i])
str[j] = '\0';
}
}
当然上面这个方法还可以优化:
+++++++++++++++++++++++但是+++++++++++++++
小编想说一句:算法竞赛中这方法往往报:Time LImit
2,利用set集合完成
思路清晰,代码简单,效率也低
(set集合底层:红黑树)
原理:set集合里面不能出现重复元素,是不是感觉直接的思路一下子打开。
思路清晰,代码简单,效率也低
//头文件导入不可少
#include <set>
...
int main(){
set<char> ss;
//将string里面的字符依次装入set集合即可完完成
for(int i=0;i<str.length();i++){
ss.insert(str[i]);
}
return 0;
}
再将set集合里面的字符一次取出即可。
注意:string字符串最后的一个字符为’\0’
string str_res="";
set<int>::iterator it;
for(it=ss.begin();it!=ss.end();it++){
//'\0'
if(*it=='\0') break;
str_res.push_back(*it);
}
3,利用stl库函数集合完成
代码较少,容易理解,上手简单
代码 少,容易理解,上手简单
#include <algorithm>
...
int main(){
//现将字符排一下序
sort(str,str.length());
str.erase(unique(str.begin(),str.end()),str.end());
//这样处理后的字符串无重复字符
cout<<str<<endl;
}
小编有话说:
同时这个去重的模板同样可以用来
补充:
sort():排序函数
unique():去重函数(只能去除相邻字符)
erase():删除函数(删除开始,删除结束)
关于unique()函数的理解小编在这里推荐:
关于unique()函数的理解
这个方法是小编的最爱,不要问为什么,就两个字:
4,结合标记数组操作
代码较多,但是处理效率高
代码较多,但是处理效率高
char temp[N] = { 0 };
int i, j, len;
len = strlen(s);
for(i = j = 0; i < len; i++)
{
if(temp[s[i]] == 0)
{
s[j++] = s[i];
temp[s[i]] = 1;
}
}
s[j] = '\0';
简单优化一下
int i, j, len, rem;
int temp[8] = {0};
len = strlen(s);
for(i = j = 0; i < len; i++)
{
rem= s[i] % 32;
if((temp[s[i] >> 5] & (1 << rem)) == 0)
{
s[j++] = s[i];
temp[s[i] >> 5] |= (1 << rem);
}
}
s[j] = '\0';
进一步优化
(结合具体的赛题)
同时结合不同的题目还可以进一步优化:
如果字符串中只出现a~z之间的小写字母
int i, j, val, temp;
j = temp= 0;
for(i = 0; s[i]; i++)
{
val = s[i] - 'a';
if((temp& (1 << val)) == 0)
{
s[j++] = s[i];
temp|= 1 << val;
}
}
s[j] = '\0';
总结:
要是图省事,大家可以选择方法三;要是追求时间效率,大家可以使用方法四。
小编图像:
小编ID:薇薇的憨宝