在字符串中实现重复字符删除的最快方法(C#)

时间:2009-08-27 21:49:51

标签: c# .net string

在C#中,检测字符串中重复字符并删除它们的最快方法是什么(删除包括重复字符的第一个实例)?

示例输入:nbHHkRvrXbvkn

示例输出:RrX

5 个答案:

答案 0 :(得分:21)

最快的代码行中最快:

var s = "nbHHkRvrXbvkn";
var duplicates = s.Where(ch => s.Count(c => c == ch) > 1);
var result = new string(s.Except(duplicates).ToArray()); // = "RrX"

速度最快,性能最快可能是这样的(不保留顺序):

var h1 = new HashSet<char>();
var h2 = new HashSet<char>();

foreach (var ch in "nbHHkRvrXbvkn")
{
    if (!h1.Add(ch))
    {
        h2.Add(ch);
    }
}

h1.ExceptWith(h2); // remove duplicates

var chars = new char[h1.Count];
h1.CopyTo(chars);
var result = new string(chars); // = "RrX"

效果测试

如有疑问 - 请测试一下:)

Yuriy Faktorovich's answer        00:00:00.2360900
Luke's answer                     00:00:00.2225683
My 'few lines' answer             00:00:00.5318395
My 'fast' answer                  00:00:00.1842144

答案 1 :(得分:9)

这是一个非常快速的保留顺序。但我有点担心LINQ如何组和其中:

string s = "nbHHkRvrXbvkn";
Console.WriteLine( 
    s.ToCharArray()
        .GroupBy(c => c)
        .Where(g => g.Count() == 1)
        .Aggregate(new StringBuilder(), (b, g) => b.Append(g.Key)));

编辑:在某些情况下,这个比Lut更慢,但它仍然比dtb更慢,但它保留了命令

private static string MyMethod(string s)
{
    StringBuilder sb = new StringBuilder(s.Length);
    foreach (var g in s.ToCharArray().GroupBy(c => c))
        if (g.Count() == 1) sb.Append(g.Key);

    return sb.ToString();
}

答案 2 :(得分:4)

这个应该很快(并保留原始顺序):

public static string RemoveDuplicates(string source)
{
    HashSet<char> found = new HashSet<char>();
    HashSet<char> dupes = new HashSet<char>();

    foreach (char c in source)
    {
        if (!found.Add(c))
        {
            dupes.Add(c);
        }
    }

    StringBuilder sb = new StringBuilder(source.Length);
    foreach (char c in source)
    {
        if (!dupes.Contains(c))
        {
            sb.Append(c);
        }
    }
    return sb.ToString();
}

答案 3 :(得分:2)

这保留了顺序,根据我的测试,它比使用HashSet快4倍。假设您的角色范围是0-255,但您可以轻松扩展。如果您打算在循环中使用此功能,请移出int[] c = new int[255];,然后在功能中执行Array.Clear(c,0,255)


        private static string RemoveDuplicates(string s)
        {
            int[] c = new int[255];
            for (int i = 0; i < s.Length; i++)
            {
                c[s[i]]++;
            }
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < s.Length; i++)
            {
                if (c[s[i]] == 1) sb.Append(s[i]);
            }
            return sb.ToString();
        }

答案 4 :(得分:0)

此算法是通用的,可应用于任何语言

  1. 创建一个地图(HashTable)char-&gt; int,其中包含找到的每个字符的数量,最初为空
  2. 扫描字符串一次以填充地图。
  3. 创建一个新的空字符串,它将保存输出,可能您需要使用StringBuilder。
  4. 扫描字符串(或地图,以较短者为准)仅将出现1的字符复制到输出字符串/ StringBuilder