Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get Equal Part of Multiple Strings at the Beginning

Tags:

string

c#

I've got a few big arrays/lists of filenames that start the same. Like this:

C:\Program Files\CCleaner\...
C:\Program Files\Common Files\...
C:\Program Files (x86)\Adobe\...
C:\Program Files (x86)\Common Files\...

I would like to extract the beginning part that they all have in common.
In this case: "C:\Program Files"

How do I do that?

I thought I might have to compare 2 strings at a time and get the same beginning. I don't even know how to do that without comparing each character manually? Then I'll have to compare each string to every other string? Will it be O(n²)? Is there a better, faster way?

Edit: Is there also a way without Linq?

like image 662
Bitterblue Avatar asked Jun 22 '15 11:06

Bitterblue


2 Answers

Quick shot:

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]));

Without 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);

There are a couple of other solutions.

like image 155
Stefan Steinegger Avatar answered Sep 17 '22 20:09

Stefan Steinegger


Another Linq solution:

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
like image 33
w.b Avatar answered Sep 17 '22 20:09

w.b