C#从字符串中删除重复项的最快方法:Split vs. Loop

时间:2014-07-16 15:17:39

标签: c# performance loops split duplicates

我有一串用短划线分隔的数字,我从

中删除了重复的数字
    string original = "45-1-3-45-10-3-15";
    string new = "45-1-3-10-15";

我尝试了两种方法,并使用秒表来确定哪种方法更快,但是我的时间过了不一致,所以我希望能够深入了解哪种方法可以更有效地实现新的无重复列表。< / p>

方法1:while循环

        List<string> temp = new List<string>();
        bool moreNumbers = true;

        while (moreNumbers)
        {
            if (original.Contains("-"))
            {
                string number = original.Substring(0, original.IndexOf("-"));

                //don't add if the number is already in the list
                int index = temp.FindIndex(item => item == number);
                if (index < 0)
                    temp.Add(value);

                original = original.Substring(original.IndexOf("-") + 1);
            }
            else
                moreNumbers = false;
        }

        //add remaining value in
        string lastNumber = original;

        //don't add if the number is already in the list
        int indexLast = temp.FindIndex(item => item == lastNumber);
        if (indexLast < 0)
            temp.Add(lastNumber);

        string new = "";
        foreach (string number in temp)
        {
            new += "-" + number;
        }
        if (new[0] == '-')
            new = new.Substring(1);

方法2:拆分

    List<string> temp = original.Split('-').Distinct().ToList();
    string new = "";
    foreach (string number in temp)
    {
         new += "-" + number;
    }
    if (new[0] == '-')
            new = new.Substring(1);

我认为第二种方法更具可读性,但可能更慢?哪种方法更有效或更好?

2 个答案:

答案 0 :(得分:3)

这将进行高度优化,但您需要测试性能。

string result = string.Join("-", original.Split('-').Distinct());

您的示例中都存在一些效率低下的问题。

方法1:操纵string永远不会有效。字符串是不可变的。

方法2:无需创建List并使用StringBuilder()而不是使用字符串连接。

最后,new是一个C#保留字,所以你的代码都不会编译。

答案 1 :(得分:0)

在第一种方法中,您使用了几个Substring调用和几个IndexOf调用。我不确切知道内部实现,但我猜他们的时间复杂度是O(n)。

因为,对于列表中的每个数字,您将在另一个列表中执行完整循环(您使用字符串作为列表),您将拥有O(n ^ 2)时间复杂性。

第二个选项,我假设它也是O(n ^ 2),因为要在IEnumerable中创建一个不同的列表,它必须迭代列表。

我认为这个问题的一个optimezed方法是:

1)循环主弦并为每个&#34; - &#34;或者字符串结尾,保存数字(这在空间方面比Split更经济)。 2)对于每个数字,将其放在一个字典中。这在空间方面不会经济,但会提供O(1)时间来检查物品。散列小字符串不应该过于笼统。 3)循环字典以检索不同的值。

此实现将为O(n),优于O(n ^ 2)。

请注意,仅使用字典可以以不同的顺序传递结果字符串。如果订单很重要,请使用“词典”检查项目是否重复,但是放入辅助列表。同样,这将有一个空间成本。