我有一些大型数组/文件名列表,它们起始相同。像这样:
c = Canvas(self, width = 200, height = 235, relief = "sunken", borderwidth = 2)
我想提取他们都有共同点的开头部分
在这种情况下:C:\Program Files\CCleaner\...
C:\Program Files\Common Files\...
C:\Program Files (x86)\Adobe\...
C:\Program Files (x86)\Common Files\...
我该怎么做?
我想我可能要一次比较2个字符串并获得相同的开头。如果不手动比较每个字符,我甚至不知道怎么做?然后我将每个字符串与每个其他字符串进行比较?它会是O(n²)吗?有更好,更快的方式吗?
编辑:还有没有Linq的方法吗?
答案 0 :(得分:12)
快速拍摄:
List<string> strings = ...;
var minimumLength = strings.Min(x => x.Length);
int commonChars;
for(commonChars = 0; commonChars < minimumLength; commonChars++)
{
if (strings.Select(x => x[commonChars]).Distinct().Count() > 1)
{
break;
}
}
return strings[0].Substring(0, commonChars);
OR
var minimumLength = strings.Min(x => x.Length);
Enumerable
.Range(0, minimumLength)
.Count(i => strings.All(y => y[i] == strings[0][i]));
没有Linq:
List<string> strings = ...;
var minimumLength = strings.Min(x => x.Length);
int commonChars;
for(commonChars = 0; commonChars < minimumLength; commonChars++)
{
foreach(var str in strings)
{
if (str[commonChars] != strings[0][commonChars])
{
break;
}
}
}
return strings[0].Substring(0, commonChars);
还有其他一些解决方案。
答案 1 :(得分:4)
另一个Linq解决方案:
var strings = new List<string> {@"C:\Program Files\CCleaner\...", @"C:\Program Files\Common Files\...",
@"C:\Program Files (x86)\Adobe\...", @"C:\Program Files (x86)\Common Files\..."};
var common = new string(strings.Select(str => str.TakeWhile((c, index) => strings.All(s => s[index] == c)))
.FirstOrDefault().ToArray());
Console.WriteLine(common); // C:\Program Files
答案 2 :(得分:1)
如果你有一个非常大的列表,最好是对字符串进行排序,检查第一个和最后一个字符串的字符数。
我无法证明它有效,但直觉上确实如此。所有中间的都需要具有相同的前缀才能以这种方式排序。
using System;
using System.IO;
using System.Collections.Generic;
namespace StringSameStart
{
class MainClass
{
public static void Main(string[] args)
{
Console.WriteLine("Hello World!");
var files = Directory.GetFiles("/Users/ibrar", "*", SearchOption.AllDirectories);
foreach (var file in files)
{
Console.WriteLine("file : " + file);
}
Array.Sort(files);
var first = files[0];
var last = files[files.Length - 1];
List<char> list = new List<char>();
for (int ctr = 0; ctr < files[0].Length; ctr++)
{
if (first[ctr] != last[ctr])
{
break;
}
Console.WriteLine("Same : " + first[ctr]);
list.Add(first[ctr]);
}
Console.WriteLine("Match : " + new string(list.ToArray()));
}
}
}