2015-06-22 7 views
7

पर एकाधिक स्ट्रिंग्स के समान भाग प्राप्त करें मेरे पास फ़ाइल नामों के कुछ बड़े सरणी/सूचियां हैं जो इसे शुरू करती हैं। इस तरह:शुरुआत

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

मैं शुरुआती भाग को निकालना चाहता हूं कि वे सभी समान हैं।
इस मामले में: "C:\Program Files"

मैं यह कैसे कर सकता हूं?

मैंने सोचा कि मुझे एक समय में 2 तारों की तुलना करना पड़ सकता है और एक ही शुरुआत मिल सकती है। मैं यह भी नहीं जानता कि प्रत्येक चरित्र को मैन्युअल रूप से तुलना किए बिना इसे कैसे किया जाए? तो मुझे प्रत्येक स्ट्रिंग को हर दूसरे स्ट्रिंग से तुलना करना होगा? क्या यह ओ (एन²) होगा? क्या कोई बेहतर, तेज़ तरीका है?

संपादित करें: क्या लिंक के बिना भी कोई रास्ता है?

+0

दूसरे शब्दों में, कारण है कि आप ऐसा करने के लिए वास्तविक समस्या में बेहतर जानकारी दे सकते हैं चाहता हूँ। कभी-कभी, एक गहरी अंतर्निहित समस्या होती है। –

उत्तर

9

त्वरित शॉट:

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

या

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

अन्य समाधान के एक जोड़े हैं।

+5

मुझे लगता है कि यह एक टाइपो है और 'तार' होना चाहिए। चयन करें ...? – petelids

+0

डांके! 'लिंक के बिना' भाग में अभी भी कुछ बग हैं जो मुझे लगता है, लेकिन मुझे यह मेरे लिए सही ढंग से चल रहा है। और दूसरी पंक्ति लिंक अभी भी उपयोग करती है। – Bitterblue

+0

क्या इस खोज पैटर्न की जटिलता ओ (एन) है? क्षैतिज रूप से लंबवत खोजना बहुत अच्छा विचार है। – Bitterblue

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

मुझे सूची – mrwaim

+0

ओवीएच की बजाय स्ट्रिंगबिल्डर का उपयोग करना चाहिए, और जब कोई मैचों नहीं होता है तो यह मामला संभाल नहीं लेता है, और दूसरी स्ट्रिंग कम – mrwaim

+0

त्वरित प्रयास पर, ऐसा लगता है कि यह मेरी प्रोजेक्ट में काम करता है। लेकिन सी # सूचियों को क्रमबद्ध करने के लिए जटिलता कितनी थी? – Bitterblue

3

एक और 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 
संबंधित मुद्दे