如何有效地从字符串中删除重复的字符?

时间:2010-01-11 00:11:44

标签: string language-agnostic duplicates algorithm

是否可以从字符串中删除重复的字符而不保存您在数组中看到的每个字符,并检查该字符中是否已有新字符?这看起来非常低效。肯定有一个更快的方法吗?

6 个答案:

答案 0 :(得分:9)

您可以使用由字符索引的布尔数组

bool seen[256];

对于字节大小的类似ASCII的字符,上面的内容是合适的。对于16位Unicode:

bool seen[65536];

等等。然后,对于字符串中的每个字符,它是一个简单的查找,以查看是否已设置该布尔值。

答案 1 :(得分:1)

使用linq

string someString = "Something I wrote quickly";
char[] distinctChars = someString.ToCharArray().Distinct();
string newString = new string(distinctChars);

答案 2 :(得分:1)

您可以使用正则表达式一次匹配重复的字符。

答案 3 :(得分:1)

我不知道是否有更简单的算法。另一种方法是检查第一个字符,然后遍历字符串的其余部分并删除所有相等的字符。然后对第二个字符,第三个字符执行此操作,依此类推。这可能会节省内存,但可能是O(n ^ 2)。

您建议的算法是O(n * m),m < n,因为它为字符串中的每个字符循环遍历数组。由于数组中的字符少于字符串中的字符,因此它很可能比上面的替代方法更快。该阵列会增加一些额外的内存需求,但不多。

然而,在大多数实际应用中,我怀疑您建议的方法的效率会对性能产生任何明显的影响。可能有其他方法(例如正则表达式或LINQ区分)可能具有更多的性能开销,但由于代码简化可能是值得的。

答案 4 :(得分:0)

这取决于数据的特征。字符串超长吗?预期会有很多重复吗?字符串中可能的字符范围是什么(是英文?中文?)你有多少内存可用?生成的字符串是否仍需要订购?

保持一组你在遍历时已经看过的角色是合理的。所以可能会对字符串进行排序,然后在遍历字符串时删除dupes,如果你可以像这样改变字符串。

如果字符串真的很长,你需要保持接近O(n)的运行时间,这意味着保持一个位设置(通常)或在极少数情况下保持一个哈希(如果可能的字符列表很大:中文?)等跟踪你看过的角色,这样你就可以在走绳子的时候把它们赶走。这里还有大量的实现细节,围绕每次删除字符时是否必须将所有其余字符串移回内存中,或者是否可以用空格或其他原位替换它。

再次,取决于你想要完成什么以及你所处的环境。

答案 5 :(得分:0)

的Python:

>>> ''.join(set("Something I wrote quickly"))
' cegihkmlonqISrutwy'

显然这不会保留秩序。