您的位置:首页 > 编程语言 > C语言/C++

C++ 去除字符串中的重复字符

2013-04-03 15:34 726 查看
给定一个字符串,要求去除其中的重复字符。例如 abcbs ,操作后得到 abcs 。

方法一:不考虑时间和空间,最简单直接的方法是 另外开辟一个 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());

 

谢谢,请指教!

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息