【问题标题】:How can you efficiently remove duplicate characters from a string?如何有效地从字符串中删除重复字符?
【发布时间】:2011-01-03 14:20:45
【问题描述】:

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

【问题讨论】:

标签: string language-agnostic duplicates algorithm


【解决方案1】:

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

bool seen[256];

对于字节大小的类 ASCII 字符,上述方法是合适的。对于 16 位 Unicode:

bool seen[65536];

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

【讨论】:

  • 啊,是的,好主意……那么你就可以在 O(n) 中完成它。虽然重组字符串可能比其他任何事情都需要更多时间。
  • 你也可以在 O(n) 中做到这一点,将你想要保留的每个字符复制到一个新字符串中。
【解决方案2】:

使用 linq

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

【讨论】:

  • string anotherString = "Mississippi"; :D
【解决方案3】:

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

【讨论】:

    【解决方案4】:

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

    您建议的算法是 O(n*m), m

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

    【讨论】:

    • 使用数组也是 O(n^2)。
    • Nitpickers'角:原始发帖人的lookup-in-an-array技术实际上是O(n*m),其中n是字符串的长度,m是对数的限制您可能拥有的独特角色。
    【解决方案5】:

    Python:

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

    显然这并不能保持秩序。

    【讨论】:

      【解决方案6】:

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

      保留一组您在遍历时已经看到的字符是合理的。因此,如果您可以像那样对字符串进行变异,那么可能会对字符串进行排序,然后在遍历字符串时删除重复项。

      如果字符串真的很长,你会希望保持运行时间接近 O(n),这意味着(通常)保持一个位设置,或者在极少数情况下保持一个哈希(如果可能的字符列表很大:中文?)或类似的,并跟踪您看到的字符,以便您可以在遍历字符串时驱逐它们。这里也有很多实现细节,关于每次删除字符时是否必须将内存中的所有其余字符串移回,或者是否可以用空白或其他原位替换它。

      同样,这取决于您要完成的工作以及您所处的环境。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-04-01
        • 1970-01-01
        • 1970-01-01
        • 2012-04-08
        • 1970-01-01
        • 1970-01-01
        • 2018-02-20
        相关资源
        最近更新 更多