C++中的unique(),unique_copy(),sort()用法

来源:互联网 发布:发泥推荐 知乎 编辑:程序博客网 时间:2024/06/05 19:07
 

C++中的unique(),unique_copy(),sort()用法

标签: C++
 19453人阅读 评论(1) 收藏 举报

在C+中如何使用STL和Algorithm库中的函数一起来获取一个字符串包含的字符集呢?这是今天遇到的问题。

要用到的容器或函数有:string,sort(),unique(),unique_copy()。

string:C++中char *的代替者,使用它处理字符串的时候再也不用考虑内存访问异常或是下标越界问题了,我是自从使用了string后很少出现上述的问题了。关于string的用法网上很多,给出一个链接两个链接

点击打开链接              点击打开链接


unique()函数是将重复的元素折叠缩编,使成唯一。

unqiue_copy()函数是将重复的元素折叠缩编,使成唯一,并复制到他处。这两个函数的剔除字符原理是,看当前字符与他前一个字符是否相同,如果相同就剔除当前字符,如果不同就跳转到下一个字符。所以在求一个字符串的字符集的时候要先把字符串排个序再调用上面两个函数剔除重复字符,获取字符集。

下面看一些代码比较

[cpp] view plain copy
  1. string str = "zhaohaoyang";  
  2. vector<char> vecch(str.begin(), str.end()); //根据迭代器的起始位置和终止位置来定初始化一个容器  
  3. vector<char>::iterator it = vecch.begin();  
  4. for (; it != vecch.end(); ++it)  
  5. {  
  6.     cout<<*it;  
  7. }  
  8. cout<<endl;  输出:zhaohaoyang  

再加上下面两行:

[cpp] view plain copy
  1. unique(str.begin(), str.end());  
  2. out<<str<<endl;  //输出的还是原样:zhaohaoyang  
unique()是剔除重复的没错,可是他是剔除相邻之间字符重复的,str中的字符前后之间是没有重复的,所以unique函数是起不到作用的。

假如把str换成"acttacct"执行上面的两句代码结果是:actactct,这个结果也是奇怪的。按照意愿应该是把多于的t与多于的c剔掉后只剩下actact了啊。最后两个字符ct是怎么回事呢?因为unique()函数并不是真的在源字符串上进行剔除的,原来的字符串经过unique()函数后虽然除掉了相邻之间重复的字符,可是字符串长度是不变的,也就是说所占内存大小没变。遇到这个问题通常会这么做str.erase(unique(str.begin(), str.end()), str.end());unique()函数的返回值是源字符串中去除相邻之间相同字符后剩下的字符串中的最后一个字符的下一个位置,举例说明:"acttacct"有8个字符,相邻之间重复的有两个,"acttacct"被unique()后的字符串面貌是"actactXX",X代表的是不确定的字符。unique函数的返回值是一个迭代器类型,指向的是第一个X所处的位置。STL中的参数区间都是左闭右开的,str.end()返回的迭代器指向第二个X位置的后面一个位置,所以调用str.erase()后就把后两个不确定的字符XX删除掉了。最后得到的就是我们最开始想要的结果了"actact"。


以上展示还未用的sort()排序函数。现在来看sort()的加入会有什么新的变化。

前面说到unique()和unique_copy()函数都是针对相邻之间相同字符的剔除,他们并不会从一个字符串的整体去剔除重复字符,如果不用sort()函数,那么我们想要获取一个字符串所包含的的字符集并不是每一次都能保证正确的(如果字符串中没有相同的字符就是正确的,如果相同的字符都是在相邻位置出现结果也是正确的,但大多数情况下却不是这么回事)。

[cpp] view plain copy
  1. string str = "zhaohaoyang";  
  2. vector<char> vecch(str.begin(), str.end());  
  3. sort(str.begin(), str.end());  
  4. str.erase(unique(str.begin(), str.end()), str.end());  
  5. cout<<str<<endl;      //输出:aghnoyz  
在第二段代码中两行展示的不能剔除重复字符,现在可以从一个字符串出发剔除重复字符了,可以获取一个字符串的字符集了。关键在于使用了sort()函数对字符串进行排序,排序后的字符串相同字符都会集中出现,所以unique()就能正确发挥功能了。


上面所展示的是把获取的字符集存储在了源字符串变量中,如果遇到要把字符集放置在额外的变量中的情况,就要用到unique_copy()函数了。来看一段代码:

[cpp] view plain copy
  1. string str = "zhaohaoyang";  
  2. string dststr;  
  3. dststr.resize(str.size());  
  4. sort(str.begin(), str.end());  
  5. dststr.resize(unique_copy(str.begin(), str.end(), dststr.begin()) - dststr.begin());  
  6. cout<<dststr<<endl;   //输出:aghnoyz  
dststr是存储字符集的目标串,str是源字符串变量。dststr在用之前必须要先设置大小,否则到unique_copy()的时候会报内存错误,因为是要存储字符串的字符集,所以dststr设置和源字符串相同的大小是完全可以的,最后再把剩余的位置erase掉就好了。
2、unique_copy与unique的唯一区别在于:unique_copy会将进行删除相邻重复元素的结果 保存在另外一个结果容器中。函数参数:unique_copy(first,last,result,compare);//first为容器的首迭代器,last为容器的末迭代器,result为保存结果的容器(原容器的内容不变),compare为比较函数(可略写)。
string s = "axttacctabc";
string s1 = "";
s1.resize(s.size());
unique_copy(s.begin(), s.end(), s1.begin());
cout << s1 << endl;
cout << s<< endl;
system("pause");
s1的内容是axtactabc