在开始时获得多个字符串的相等部分

时间:2015-06-22 11:42:12

标签: c# string

我有一些大型数组/文件名列表,它们起始相同。像这样:

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的方法吗?

3 个答案:

答案 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()));
        }
    }
}