从字符串中删除重复字符

Remove repeating characters from string

本文关键字:字符 删除 字符串      更新时间:2023-10-16

我有一个字符串,例如acaddefbbaaddgg。我必须尽快删除所有重复的字符。因此,例如,后面的pooaatat应该看起来像poat,而ggaatpop应该看起来像是gatpo。有没有内置的函数或算法可以快速做到这一点?我试着搜索STL,但没有得到满意的结果。

好的,这里有4种不同的解决方案。

固定阵列

std::string str = "pooaatat";
// Prints "poat"
short count[256] = {0};
std::copy_if(str.begin(), str.end(), std::ostream_iterator<char>(std::cout),
             [&](unsigned char c) { return count[c]++ == 0; });

计数算法+迭代器

std::string str = "pooaatat";
// Prints "poat"
std::string::iterator iter = str.begin();
std::copy_if(str.begin(), str.end(), std::ostream_iterator<char>(std::cout),
             [&](char c) { return !std::count(str.begin(), iter++, c); });

无序集合

std::string str = "pooaatat";
// Prints "poat"
std::unordered_set<char> container;
std::copy_if(str.begin(), str.end(), std::ostream_iterator<char>(std::cout),
             [&](char c) { return container.insert(c).second; });

无序地图

std::string str = "pooaatat";
// Prints "poat"
std::unordered_map<char, int> container;
std::copy_if(str.begin(), str.end(), std::ostream_iterator<char>(std::cout),
             [&](char c) { return container[c]++ == 0; });

AFAIK,没有内置的算法。如果只想删除连续的重复字符,std::unique算法是有效的。

然而,您可以遵循以下简单的方法:

如果字符串仅包含ASCII字符,则可以形成布尔数组a[256],表示是否已经遇到相应的字符。

如果A[character]仍然为0(并使A[character]=1),则只需遍历输入字符串并复制该字符即可输出。

如果字符串包含任意字符,则可以使用字符的std::unordered_mapstd::map进行int。

内置正则表达式应该是高效的,即

#include <regex>
[...]
const std::regex pattern("([\w ])(?!\1)");
string s = "ssha3akjssss42jj 234444 203488842882387 heeelloooo";
std::string result;
for (std::sregex_iterator i(s.begin(), s.end(), pattern), end; i != end; ++i)
    result.append((*i)[1]);
std::cout << result << std::endl;

当然,您可以根据需要修改cpaturing组。好在VisualStudio2010tr1已经支持它了。然而,gcc 4.8似乎在regex迭代器方面存在问题。