2015-06-22 7 views
7

Ho un paio di matrici grandi/liste di nomi di file che iniziano lo stesso. Così:Ottenere Pari Parte della più stringhe al Beginning

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

Vorrei estrarre la parte iniziale che tutti hanno in comune.
In questo caso: "C:\Program Files"

Come si fa?

ho pensato che potrei avere per confrontare 2 stringhe alla volta e ottenere lo stesso principio. Non so nemmeno come farlo senza comparare manualmente ogni personaggio? Quindi dovrò confrontare ogni stringa con ogni altra stringa? Sarà O (n²)? C'è un modo migliore, più veloce?

Modifica: C'è anche un modo senza Linq?

+0

In altre parole, la ragione si vuole fare questo può dare una migliore comprensione del problema reale. A volte, c'è un problema di fondo più profondo. –

risposta

9

colpo rapido:

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

O

var minimumLength = strings.Min(x => x.Length); 
Enumerable 
    .Range(0, minimumLength) 
    .Count(i => strings.All(y => y[i] == strings[0][i])); 

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

ci sono un paio di altre soluzioni.

+5

Penso che sia un errore di battitura e dovrebbe essere 'stringhe.Seleziona' ...? – petelids

+0

Danke! La parte 'Without Linq' ha ancora alcuni bug, penso, ma ho funzionato correttamente per me. E la seconda riga usa ancora Linq. – Bitterblue

+0

La complessità di questo modello di ricerca è O (n)? È una buona idea cercare in senso verticale anziché orizzontale. – Bitterblue

1

Se si dispone di una grande lista, il migliore è quello di ordinare la stringa, controllare il numero di caratteri della prima e ultima stringa ha.

Non posso veramente dimostrare che funziona, ma intuitivamente, lo fa. Tutti quelli di mezzo dovranno avere lo stesso prefisso per essere ordinati in questo modo.

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())); 
     } 
    } 
} 
+0

Avrei dovuto usare un StringBuilder invece di Elenco – mrwaim

+0

Owh e non gestisce il caso quando non ci sono corrispondenze, e la seconda stringa è più corta – mrwaim

+0

In un tentativo veloce, sembra funzionare nel mio progetto. Ma quanto è stata complessa la classificazione delle liste C#? – Bitterblue

3

Un'altra soluzione 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 
Problemi correlati