从字符串中删除重复字符

时间:2014-09-20 08:57:28

标签: c++ string algorithm character

我有一个字符串,例如acaddefbbaaddgg。我必须尽快删除所有重复的字符。因此,例如,pooaatat之后应该看起来像poat,而ggaatpop应该看起来像gatpo。是否有任何内置函数或算法可以快速完成?我试图搜索STL,但没有令人满意的结果。

3 个答案:

答案 0 :(得分:3)

好的,所以这里有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; });

答案 1 :(得分:3)

AFAIK,没有内置算法可以做到这一点。如果您只想删除连续的重复字符,std::unique算法有效。

但是,您可以遵循以下简单方法:

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

然后只需遍历输入字符串并将字符复制到输出,如果A [字符]仍为0(并使A [字符] = 1)。

如果字符串包含任意字符,那么您可以使用std::unordered_mapstd::map char来实现int。

答案 2 :(得分:0)

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

#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组。 好消息是它已经在Visual Studio 2010 tr1中得到支持。但是,gcc 4.8似乎有一个带有正则表达式迭代器的problem