从字符串中删除重复字符

Posted

技术标签:

【中文标题】从字符串中删除重复字符【英文标题】:Remove repeating characters from string 【发布时间】:2014-09-20 08:57:27 【问题描述】:

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

【问题讨论】:

对字符串进行切片需要了解字符集和编码(以及您希望应用于算法的任何简化假设/输入验证)。您使用的是 Unicode/UTF-8 吗? (对于控制台程序,在 Linus 上运行:locale,在 Windows 上:chcp。) 【参考方案1】:

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

【讨论】:

它应该打印“poat”,因为双“t”也应该被删除【参考方案2】:

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

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

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

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

如果字符串中包含任意字符,则可以使用std::unordered_mapstd::map 的char 转换为int。

【讨论】:

ASCII 仅包含 128 个代码点,并且在很大程度上无关紧要。对于您的 256 元素数组,限制只是字符集最多有 256 个代码点,每个代码点都有一个 1 字节的编码,并且没有“组合字符”,这需要与前面的代码点保持一致。跨度> 【参考方案3】:

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

#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。

【讨论】:

以上是关于从字符串中删除重复字符的主要内容,如果未能解决你的问题,请参考以下文章

使用 STL 从字符串中删除重复字符

如何从字符串中删除('')[重复]

从字符串中删除重复的字符串

从字符串中删除字母字符[重复]

从字符串中删除点符号[重复]

jQuery - 从字符串数组中删除重复项[重复]