Find a common string within a list of strings

前端 未结 2 2136
迷失自我
迷失自我 2020-12-20 18:37

I\'m very close on this. I got a question posed to me yesterday by a developer if I could have a look at this.

I feel close, but I think some people here would apprec

2条回答
  •  渐次进展
    2020-12-20 19:05

    Find the shortest entry in the list.

    • Today
    • Monday
    • Tuesday
    • Wednesday

    So we use "Today".

    Build a list of strings of consecutive characters in "Today" of the length of the string down to each character, in "longest first" order.

    "Today",

    "Toda", "oday",

    "Tod", "oda", "day",

    "To", "od", "da", "ay",

    "t", "o", "d", "a", "y"

    Enumerate over this list, finding the first entry for which all the other strings contain that entry.

            List words = new List { "Today", "Monday", "Tuesday", "Wednesday" };
    
            // Select shortest word in the list
            string shortestWord = (from word in words
                                orderby word.Length
                                select word).First();
    
            int shortWordLength = shortestWord.Length;
    
            // Build up the list of consecutive character strings, in length order.
            List parts = new List();
            for (int partLength = shortWordLength; partLength > 0; partLength--)
            {
                for (int partStartIndex = 0; partStartIndex <= shortWordLength - partLength; partStartIndex++)
                {
                    parts.Add(shortestWord.Substring(partStartIndex, partLength));
                }
            }
            // Find the first part which is in all the words.
            string longestSubString = (from part in parts where words.All(s => s.Contains(part)) select part).FirstOrDefault();
    
           // longestSubString is the longest part of all the words, or null if no matches are found.
    

    EDIT

    Thinking a little more about it, you can optimise a little.

    You don't need to build up a list of parts - just test each part as it is generated. Also, by sorting the word list in length order, you always test against the shortest strings first to reject candidate parts more quickly.

            string longestSubString = null;
    
            List words = new List { "Todays", "Monday", "Tuesday" };
    
            // Sort word list by length
            List wordsInLengthOrder = (from word in words
                                               orderby word.Length
                                               select word).ToList();
    
            string shortestWord = wordsInLengthOrder[0];
            int shortWordLength = shortestWord.Length;
    
            // Work through the consecutive character strings, in length order.
            for (int partLength = shortWordLength; (partLength > 0) && (longestSubString == null); partLength--)
            {
                for (int partStartIndex = 0; partStartIndex <= shortWordLength - partLength; partStartIndex++)
                {
                    string part = shortestWord.Substring(partStartIndex, partLength);
    
                    // Test if all the words in the sorted list contain the part.
                    if (wordsInLengthOrder.All(s => s.Contains(part)))
                    {
                        longestSubString = part;
                        break;
                    }
                }
    
            }
    
            Console.WriteLine(longestSubString);
    

提交回复
热议问题