[英]C# fastest way to remove duplicates from string: Split vs. Loop
我有一串破折号,我正在从中删除重复的数字
string original = "45-1-3-45-10-3-15";
string new = "45-1-3-10-15";
我尝试了两种方法,并使用秒表来确定哪种方法更快,但是我得到的时间不一致,因此我希望对哪种方法更有效地获得新的无重复清单有一些了解。
方法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);
我认为第二种方法更具可读性,但可能更慢? 以下哪种方法会更有效或更有效?
这将进行高度优化,但是您需要测试性能。
string result = string.Join("-", original.Split('-').Distinct());
您在两个示例中都有一些效率低下的地方。
方法1:操作string
永远不会有效。 字符串是不可变的。
方法2:无需创建List
并使用StringBuilder()
而不是使用字符串串联。
最后, new
是一个C#保留字,因此您的代码都不会编译。
在第一种方法中,您将使用几个Substring调用和几个IndexOf调用。 我不知道确切的内部实现,但我想它们的时间复杂度为O(n)。
因为对于列表中的每个数字,您将在另一个列表中进行完整循环(您将字符串用作列表),所以时间复杂度为O(n ^ 2)。
第二个选项,我假设它也是O(n ^ 2),因为要使IEnumerable中的列表与众不同,就必须迭代该列表。
我认为解决该问题的一种可行方法是:
1)循环主字符串,并为字符串的每个“-”或末尾保存数字(就空格而言,这比Split更为经济)。 2)将每个数字放入字典中。 就空间而言,这不是经济的做法,但是会提供O(1)时间来检查该项目。 散列小的字符串不应该过于固定。 3)循环字典以检索不同的值。
此实现将是O(n),优于O(n ^ 2)。
请注意,只有使用字典才能以不同顺序传递结果字符串。 如果顺序很重要,请使用词典检查该项目是否重复,但要放入辅助列表中。 同样,这将产生空间成本。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.