C++ 去除字符串中的重复字符
2013-04-03 15:34
726 查看
给定一个字符串,要求去除其中的重复字符。例如 abcbs ,操作后得到 abcs 。
方法一:不考虑时间和空间,最简单直接的方法是 另外开辟一个 string 数组,用于保存unique字符。
主函数中的 isUnique(mystr) 见我的上一篇博文。
这里我用到了 string类来实现duplicate 算法。时间O(n2) 空间O(n)。
方法二:假如我们限定空间复杂度为O(1),即不能开辟新的空间,只能声明一些简单变量,那么我们就只能在元string数组上进行操作了。
我们仔细想后,发现这样是可行的。我们用一个变量 tail 来标记新string数组的长度,可知tail肯定小于等于元数组的长度。具体代码如下:
该算法的时间复杂度是O(n2),空间是O(1)。
方法三:应用Hash Table思想,可以将时间复杂度降低到O(1)。
选择的测试用例:没有重复的字符,空串等。
特别注意:string类对象到 字符数组的转换:
string是C++标准库里面其中的一个,封装了对字符串的操作。
其中 string str1,str2; str[1]=str[3];是错误的,不能下标修改string对象的单个字符值,必须应用string类对应的具体函数来修改。所以我们一般应用char str[ ]比较方便。
str1.data() , str1.c_str() 这两者得到的都是 const char * 类型,而不是char * 类型 。直接 char * tmpstr = str1.c_str(); 是错误的。
str1.copy(tmpstr,5,0) 5表示复制的个数,0表示复制的位置,*(p+5)='\0' ; 要手动加上结束符。
我们一般用 C中的字符串操作函数来处理字符串或字符数组。
如 strlen() , strcpy(), strcmp() .
char * dest=new char[mystr.size()+1]; //必须先申请一个足够大的空间来存储。
strcpy(dest , mystr.c_str());
谢谢,请指教!
方法一:不考虑时间和空间,最简单直接的方法是 另外开辟一个 string 数组,用于保存unique字符。
主函数中的 isUnique(mystr) 见我的上一篇博文。
string duplicate(string str) { if(str.size()<2) return str; string tmp_str("\0"); tmp_str+=str[0]; string::size_type j; for(string::size_type i=1 ; i<str.size() ; i++) { for(j=0 ; j<tmp_str.size() ; j++) { if(tmp_str[j]==str[i]) break; } if(j==tmp_str.size()) tmp_str+=str[i]; } return tmp_str; } int _tmain(int argc, _TCHAR* argv[]) { string mystr; string dest; while(cin>>mystr) { if(isUnique(mystr)) cout<<mystr<<" is Unique!"<<endl; else { cout<<mystr<<" is not Unique!"<<endl; dest = duplicate(mystr); cout<<"After the dup: "<<dest<<endl; } } return 0; }
这里我用到了 string类来实现duplicate 算法。时间O(n2) 空间O(n)。
方法二:假如我们限定空间复杂度为O(1),即不能开辟新的空间,只能声明一些简单变量,那么我们就只能在元string数组上进行操作了。
我们仔细想后,发现这样是可行的。我们用一个变量 tail 来标记新string数组的长度,可知tail肯定小于等于元数组的长度。具体代码如下:
void duplicate(char str[]) { int len = strlen(str); if(len<2) return ; int tail = 1; for(int i=1 ; i<len ; i++) { int j=0; for(j=0 ; j<tail ; j++) { if(str[j]==str[i]) break; } if(j==tail) str[tail++]=str[i]; } str[tail] = '\0'; } int _tmain(int argc, _TCHAR* argv[]) { string mystr; string dest; while(cin>>mystr) { if(isUnique(mystr)) cout<<mystr<<" is Unique!"<<endl; else { char * dest=new char[mystr.size()+1]; strcpy(dest , mystr.c_str()); duplicate(dest); cout<<"After the dup: "<<dest<<endl; } } return 0; }
该算法的时间复杂度是O(n2),空间是O(1)。
方法三:应用Hash Table思想,可以将时间复杂度降低到O(1)。
void duplicate(char str[]) { int len = strlen(str); if(len<2) return ; int hash[256]={0}; hash[str[0]]=1; int tail = 1; for(int i=1 ; i<len ; i++) { if(hash[str[i]]==0) { str[tail++]=str[i]; hash[str[i]]+=1; } } str[tail] = '\0'; } int _tmain(int argc, _TCHAR* argv[]) { string mystr; string dest; while(cin>>mystr) { if(isUnique(mystr)) cout<<mystr<<" is Unique!"<<endl; else { char * dest=new char[mystr.size()+1]; strcpy(dest , mystr.c_str()); duplicate(dest); cout<<"After the dup: "<<dest<<endl; } } return 0; }
选择的测试用例:没有重复的字符,空串等。
特别注意:string类对象到 字符数组的转换:
string是C++标准库里面其中的一个,封装了对字符串的操作。
其中 string str1,str2; str[1]=str[3];是错误的,不能下标修改string对象的单个字符值,必须应用string类对应的具体函数来修改。所以我们一般应用char str[ ]比较方便。
str1.data() , str1.c_str() 这两者得到的都是 const char * 类型,而不是char * 类型 。直接 char * tmpstr = str1.c_str(); 是错误的。
str1.copy(tmpstr,5,0) 5表示复制的个数,0表示复制的位置,*(p+5)='\0' ; 要手动加上结束符。
我们一般用 C中的字符串操作函数来处理字符串或字符数组。
如 strlen() , strcpy(), strcmp() .
char * dest=new char[mystr.size()+1]; //必须先申请一个足够大的空间来存储。
strcpy(dest , mystr.c_str());
谢谢,请指教!
相关文章推荐
- 【c++】字符串---去除重复字符
- 3.去除字符串中重复的字符
- 用正则表达式(零宽断言)去除字符串中重复的字符
- c/c++生成不重复的字符串(6个字符组成,可表示的个数可以扩充),简易版数据库主键
- "找出字符串中第一个不重复的字符"和"找出字符串中最后一个重复的字符"的两种方法的C++实现
- 去除字符串中重复出现的字符
- oracle如何去除字符串中的重复字符
- JS字符串去除连续或全部重复字符的实例
- VBS去除字符串的重复项并统计重复字符出现的次数
- [面试题]去除字符串中相邻两个字符的重复
- js 去除字符串中重复的字符
- 去除字符串中的重复字符——方法汇总和性能测试
- C# 使用String.Join 和 Distinct 方法 去除字符串中重复字符
- 去除字符串中的重复字符——方法汇总和性能测试
- leetcode 316. Remove Duplicate Letters 去除重复字符字典序最小字符串+贪心+递归
- 去除字符串中重复字符
- 去除字符串中连续重复的字符
- (C++)剑指offer-54:字符流中第一个不重复的字符(字符串)
- C/C++去除字符串首尾空白字符
- 华为机试题C++-去除重复字符并排序