दिलचस्प पोस्ट
एचटीएमएल 5 वीडियो को डाउनलोड होने से रोकें (सहेजे गए पर राइट-क्लिक)? `Is_base_of` काम कैसे करता है? सिस्टम में एक फ़ाइल में जावा ITextSharp एक मौजूदा पीडीएफ पाठ डालें क्या आप SQL सर्वर में मुद्रा या दशमलव (एक्स, वाई) डाटाटेप्स चुनना चाहिए? जावा: वेतन वृद्धि / घटते ऑपरेटरों का उपसर्ग / पोस्टफिक्स? क्रोम कहते हैं, "संसाधन स्क्रिप्ट के रूप में व्याख्या किया गया है लेकिन माइम प्रकार पाठ / सादे के साथ स्थानांतरित किया गया है।", क्या देता है? ओरेकल एसक्यूएल में स्लैश बनाम एक सेमीकोलन का उपयोग करने की आवश्यकता कब है? प्रेषण_असिनक को समझना java.lang.RuntimeException: असंगत स्रोत कोड – इसका कारण क्या हो सकता है? यूनिट परीक्षण क्या है? असंगत जादू मूल्य 1008813135 कोणीय जेएस में डबल और एकल घुंघराले ब्रेस के बीच का अंतर? गैर-अच्छी तरह से बनाए गए HTML को DomDocument (PHP) द्वारा लोड करते समय सावधानियां अक्षम करें बूटस्ट्रैप NavBar, बाएं, केंद्र और दाएं एकरेखित आइटम के साथ

स्ट्रिंग्स का सामान्य उपसर्ग ढूंढें

मेरे पास 4 तार हैं:

"h:/a/b/c" "h:/a/b/d" "h:/a/b/e" "h:/a/c" 

मुझे उन तारों के लिए सामान्य उपसर्ग मिलना है, अर्थात् "h:/a" यह कैसे खोजना है?

आमतौर पर मैं सीमांकक '/' साथ स्ट्रिंग को विभाजित करता हूं और इसे दूसरी सूची में डालता हूं, और इसी तरह।
क्या ऐसा करने का कोई बेहतर तरीका है?

वेब के समाधान से एकत्रित समाधान "स्ट्रिंग्स का सामान्य उपसर्ग ढूंढें"

 string[] xs = new[] { "h:/a/b/c", "h:/a/b/d", "h:/a/b/e", "h:/a/c" }; string x = string.Join("/", xs.Select(s => s.Split('/').AsEnumerable()) .Transpose() .TakeWhile(s => s.All(d => d == s.First())) .Select(s => s.First())); 

साथ में

 public static IEnumerable<IEnumerable<T>> Transpose<T>( this IEnumerable<IEnumerable<T>> source) { var enumerators = source.Select(e => e.GetEnumerator()).ToArray(); try { while (enumerators.All(e => e.MoveNext())) { yield return enumerators.Select(e => e.Current).ToArray(); } } finally { Array.ForEach(enumerators, e => e.Dispose()); } } 

मेरा एक छोटा सा LINQy समाधान

 var samples = new[] { "h:/a/b/c", "h:/a/b/d", "h:/a/b/e", "h:/a/e" }; var commonPrefix = new string( samples.First().Substring(0, samples.Min(s => s.Length)) .TakeWhile((c, i) => samples.All(s => s[i] == c)).ToArray()); 

बस लूप को कम से कम स्ट्रिंग के वर्णों को गोल करते हैं और दूसरे अक्षर में समान स्थिति में वर्ण के प्रत्येक चरित्र की तुलना करते हैं। जब तक वे सभी मैच चलते रहते हैं। जैसे ही कोई मेल नहीं खाता है, तब तक स्ट्रिंग को वर्तमान स्थिति -1 तक उत्तर देना होगा।

कुछ ऐसा (छद्म कोड)

 int count=0; foreach(char c in shortestString) { foreach(string s in otherStrings) { if (s[count]!=c) { return shortestString.SubString(0,count-1); //need to check count is not 0 } } count+=1; } return shortestString; 

सैम होल्डर के समाधान पर आधारित वर्किंग कोड (ध्यान दें कि यह h: / a / not h: / a को सवाल में सबसे लंबे समय तक सामान्य प्रारंभिक सबस्ट्रिंग देता है):

 using System; namespace CommonPrefix { class Program { static void Main(string[] args) { Console.WriteLine(CommonPrefix(new[] { "h:/a/b/c", "h:/a/b/d", "h:/a/b/e", "h:/a/c" })); // "h:/a/" Console.WriteLine(CommonPrefix(new[] { "abc", "abc" })); // "abc" Console.WriteLine(CommonPrefix(new[] { "abc" })); // "abc" Console.WriteLine(CommonPrefix(new string[] { })); // "" Console.WriteLine(CommonPrefix(new[] { "a", "abc" })); // "a" Console.WriteLine(CommonPrefix(new[] { "abc", "a" })); // "a" Console.ReadKey(); } private static string CommonPrefix(string[] ss) { if (ss.Length == 0) { return ""; } if (ss.Length == 1) { return ss[0]; } int prefixLength = 0; foreach (char c in ss[0]) { foreach (string s in ss) { if (s.Length <= prefixLength || s[prefixLength] != c) { return ss[0].Substring(0, prefixLength); } } prefixLength++; } return ss[0]; // all strings identical up to length of ss[0] } } } 

यह सबसे लंबे समय तक आम substring समस्या है (हालांकि यह थोड़ा विशिष्ट मामला है क्योंकि आप केवल उपसर्ग की परवाह करते हैं)। .NET प्लेटफ़ॉर्म में एल्गोरिथ्म का कोई लाइब्रेरी कार्यान्वयन नहीं है, जिसे आप सीधे कॉल कर सकते हैं, लेकिन यहां से जुड़ा हुआ आलेख आपको अपने आप कैसे कर सकता है इसके बारे में कदमों से भरा होता है।

मैं एक सामान्य स्ट्रिंग उपसर्ग चाहता था, सिवाय मैं किसी भी चरित्र को शामिल करना चाहता था (जैसे /) और मैं कुछ निष्पादक / फैंसी नहीं चाहता था, जिसे मैं परीक्षण के साथ पढ़ सकता हूं। इसलिए मेरे पास यह है: https://github.com/fschwiet/DreamNJasmine/commit/ad802611ceacc673f2d03c30f7c8199f552b586f

 public class CommonStringPrefix { public static string Of(IEnumerable<string> strings) { var commonPrefix = strings.FirstOrDefault() ?? ""; foreach(var s in strings) { var potentialMatchLength = Math.Min(s.Length, commonPrefix.Length); if (potentialMatchLength < commonPrefix.Length) commonPrefix = commonPrefix.Substring(0, potentialMatchLength); for(var i = 0; i < potentialMatchLength; i++) { if (s[i] != commonPrefix[i]) { commonPrefix = commonPrefix.Substring(0, i); break; } } } return commonPrefix; } } 

यहाँ सी # ( http://en.wikipedia.org/wiki/Trie ) में ट्री एल्गोरिथम का कस्टम कार्यान्वयन है। इसका उपयोग उपसर्गों के जरिए अनुक्रमित स्ट्रिंग करने के लिए किया जाता है। इस कक्षा में ओ (1) लिखने और पत्ती नोड्स के लिए पढ़ता है। उपसर्ग खोजों के लिए, प्रदर्शन ओ (लॉग एन) है, हालांकि उपसर्ग के लिए परिणामों की गिनती ओ (1) है।

 using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; public class StringIndex { private Dictionary<char, Item> _rootChars; public StringIndex() { _rootChars = new Dictionary<char, Item>(); } public void Add(string value, string data) { int level = 0; Dictionary<char, Item> currentChars = _rootChars; Item currentItem = null; foreach (char c in value) { if (currentChars.ContainsKey(c)) { currentItem = currentChars[c]; } else { currentItem = new Item() { Level = level, Letter = c }; currentChars.Add(c, currentItem); } currentChars = currentItem.Items; level++; } if (!currentItem.Values.Contains(data)) { currentItem.Values.Add(data); IncrementCount(value); } } private void IncrementCount(string value) { Dictionary<char, Item> currentChars = _rootChars; Item currentItem = null; foreach (char c in value) { currentItem = currentChars[c]; currentItem.Total++; currentChars = currentItem.Items; } } public void Remove(string value, string data) { Dictionary<char, Item> currentChars = _rootChars; Dictionary<char, Item> parentChars = null; Item currentItem = null; foreach (char c in value) { if (currentChars.ContainsKey(c)) { currentItem = currentChars[c]; parentChars = currentChars; currentChars = currentItem.Items; } else { return; // no matches found } } if (currentItem.Values.Contains(data)) { currentItem.Values.Remove(data); DecrementCount(value); if (currentItem.Total == 0) { parentChars.Remove(currentItem.Letter); } } } private void DecrementCount(string value) { Dictionary<char, Item> currentChars = _rootChars; Item currentItem = null; foreach (char c in value) { currentItem = currentChars[c]; currentItem.Total--; currentChars = currentItem.Items; } } public void Clear() { _rootChars.Clear(); } public int GetValuesByPrefixCount(string prefix) { int valuescount = 0; int level = 0; Dictionary<char, Item> currentChars = _rootChars; Item currentItem = null; foreach (char c in prefix) { if (currentChars.ContainsKey(c)) { currentItem = currentChars[c]; currentChars = currentItem.Items; } else { return valuescount; // no matches found } level++; } valuescount = currentItem.Total; return valuescount; } public HashSet<string> GetValuesByPrefixFlattened(string prefix) { var results = GetValuesByPrefix(prefix); return new HashSet<string>(results.SelectMany(x => x)); } public List<HashSet<string>> GetValuesByPrefix(string prefix) { var values = new List<HashSet<string>>(); int level = 0; Dictionary<char, Item> currentChars = _rootChars; Item currentItem = null; foreach (char c in prefix) { if (currentChars.ContainsKey(c)) { currentItem = currentChars[c]; currentChars = currentItem.Items; } else { return values; // no matches found } level++; } ExtractValues(values, currentItem); return values; } public void ExtractValues(List<HashSet<string>> values, Item item) { foreach (Item subitem in item.Items.Values) { ExtractValues(values, subitem); } values.Add(item.Values); } public class Item { public int Level { get; set; } public char Letter { get; set; } public int Total { get; set; } public HashSet<string> Values { get; set; } public Dictionary<char, Item> Items { get; set; } public Item() { Values = new HashSet<string>(); Items = new Dictionary<char, Item>(); } } } 

इस वर्ग का उपयोग करने के तरीके के लिए इकाई परीक्षण और उदाहरण कोड यहां दिया गया है।

 using System; using Microsoft.VisualStudio.TestTools.UnitTesting; [TestClass] public class StringIndexTest { [TestMethod] public void AddAndSearchValues() { var si = new StringIndex(); si.Add("abcdef", "1"); si.Add("abcdeff", "2"); si.Add("abcdeffg", "3"); si.Add("bcdef", "4"); si.Add("bcdefg", "5"); si.Add("cdefg", "6"); si.Add("cdefgh", "7"); var output = si.GetValuesByPrefixFlattened("abc"); Assert.IsTrue(output.Contains("1") && output.Contains("2") && output.Contains("3")); } [TestMethod] public void RemoveAndSearch() { var si = new StringIndex(); si.Add("abcdef", "1"); si.Add("abcdeff", "2"); si.Add("abcdeffg", "3"); si.Add("bcdef", "4"); si.Add("bcdefg", "5"); si.Add("cdefg", "6"); si.Add("cdefgh", "7"); si.Remove("abcdef", "1"); var output = si.GetValuesByPrefixFlattened("abc"); Assert.IsTrue(!output.Contains("1") && output.Contains("2") && output.Contains("3")); } [TestMethod] public void Clear() { var si = new StringIndex(); si.Add("abcdef", "1"); si.Add("abcdeff", "2"); si.Add("abcdeffg", "3"); si.Add("bcdef", "4"); si.Add("bcdefg", "5"); si.Add("cdefg", "6"); si.Add("cdefgh", "7"); si.Clear(); var output = si.GetValuesByPrefix("abc"); Assert.IsTrue(output.Count == 0); } [TestMethod] public void AddAndSearchValuesCount() { var si = new StringIndex(); si.Add("abcdef", "1"); si.Add("abcdeff", "2"); si.Add("abcdeffg", "3"); si.Add("bcdef", "4"); si.Add("bcdefg", "5"); si.Add("cdefg", "6"); si.Add("cdefgh", "7"); si.Remove("cdefgh", "7"); var output1 = si.GetValuesByPrefixCount("abc"); var output2 = si.GetValuesByPrefixCount("b"); var output3 = si.GetValuesByPrefixCount("bc"); var output4 = si.GetValuesByPrefixCount("ca"); Assert.IsTrue(output1 == 3 && output2 == 2 && output3 == 2 && output4 == 0); } } 

इस वर्ग को सुधारने के बारे में कोई भी सुझाव स्वागत है 🙂

मेरा दृष्टिकोण होगा, पहली स्ट्रिंग लें पत्र द्वारा पत्र प्राप्त करें, जबकि अन्य स्ट्रिंग को उसी सूचकांक स्थिति पर एक ही पत्र मिला है और अगर कोई मैच नहीं है तो रोकें। अंतिम वर्ण निकालें यदि यह एक विभाजक है

 var str_array = new string[]{"h:/a/b/c", "h:/a/b/d", "h:/a/b/e", "h:/a/c"}; var separator = '/'; // get longest common prefix (optinally use ToLowerInvariant) var ret = str_array.Any() ? str_array.First().TakeWhile((s,i) => str_array.All(e => Char.ToLowerInvariant(s) == Char.ToLowerInvariant(e.Skip(i).Take(1).SingleOrDefault()))) : String.Empty; // remove last character if it's a separator (optional) if (ret.LastOrDefault() == separator) ret = ret.Take(ret.Count() -1); string prefix = new String(ret.ToArray()); 

मुझे असम्बद्ध तारों में सबसे लंबे समय तक सामान्य उपसर्ग की तलाश करने की जरूरत थी। मेरे द्वारा लाया गया:

 private string FindCommonPrefix(List<string> list) { List<string> prefixes = null; for (int len = 1; ; ++len) { var x = list.Where(s => s.Length >= len) .GroupBy(c => c.Substring(0,len)) .Where(grp => grp.Count() > 1) .Select(grp => grp.Key) .ToList(); if (!x.Any()) { break; } // Copy last list prefixes = new List<string>(x); } return prefixes == null ? string.Empty : prefixes.First(); } 

यदि एक ही लंबाई के साथ एक से अधिक उपसर्ग है, तो यह स्वैच्छिक रूप से पहले पाया गया एक रिटर्न देता है इसके अलावा यह मामला-संवेदनशील है। इन दोनों बिंदुओं को पाठक द्वारा संबोधित किया जा सकता है!

मैंने वेब पतों के संग्रह से सबसे लंबे समय तक सामान्य आधार उरी को खोजने के लिए इस आइकलोन एक्सटेंशन को लिखा है।

चूंकि यह केवल प्रत्येक स्लैश पर स्ट्रिंग्स का संग्रह जांचता है, यह थोड़ा तेज होगा कि एक सामान्य प्रीफ़िक्स रूटीन (मेरी अक्षम अल्गोरिदम नहीं गिना!)। यह शब्दशः है, लेकिन का पालन करने के लिए आसान … मेरे पसंदीदा प्रकार का कोड 😉

Ignore 'http: //' और 'https: //', साथ ही साथ मामले।

  /// <summary> /// Resolves a common base Uri from a list of Uri strings. Ignores case. Includes the last slash /// </summary> /// <param name="collectionOfUriStrings"></param> /// <returns>Common root in lowercase</returns> public static string GetCommonUri(this ICollection<string> collectionOfUriStrings) { //Check that collection contains entries if (!collectionOfUriStrings.Any()) return string.Empty; //Check that the first is no zero length var firstUri = collectionOfUriStrings.FirstOrDefault(); if(string.IsNullOrEmpty(firstUri)) return string.Empty; //set starting position to be passed '://' int previousSlashPos = firstUri.IndexOf("://", StringComparison.OrdinalIgnoreCase) + 2; int minPos = previousSlashPos + 1; //results return must have a slash after this initial position int nextSlashPos = firstUri.IndexOf("/", previousSlashPos + 1, StringComparison.OrdinalIgnoreCase); //check if any slashes if (nextSlashPos == -1) return string.Empty; do { string common = firstUri.Substring(0, nextSlashPos + 1); //check against whole collection foreach (var collectionOfUriString in collectionOfUriStrings) { if (!collectionOfUriString.StartsWith(common, StringComparison.OrdinalIgnoreCase)) { //return as soon as a mismatch is found return previousSlashPos > minPos ? firstUri.Substring(0, previousSlashPos + 1).ToLower() : string.Empty ; } } previousSlashPos = nextSlashPos; nextSlashPos = firstUri.IndexOf("/", previousSlashPos + 1, StringComparison.OrdinalIgnoreCase); } while (nextSlashPos != -1); return previousSlashPos > minPos ? firstUri.Substring(0, previousSlashPos + 1).ToLower() : string.Empty; }