コード例 #1
0
        public static string FindLargestPalindrome(string s)
        {
            if (s.Length == 0)
            {
                return(string.Empty);
            }
            if (s.Length == 1)
            {
                return(s[0].ToString());
            }

            var rs         = new string(s.Reverse().ToArray());
            var ns         = s + '\0' + rs;
            var suffixTree = SuffixTreeNode.Build(ns);
            var Earray     = new int[(ns.Length + 2) * 4 - 1];
            var Aarray     = new int[(ns.Length + 2) * 4 - 1];
            var Rarray     = new int[ns.Length + 1];

            suffixTree.WriteToArrays(Earray, 0, Aarray, Rarray);
            var rmqHelper = new RMQPM1Helper(Aarray);

            var lenMaxPalindrome = 0;
            var midPalindrome    = -1;

            for (int i = 0; i < s.Length; i++)
            {
                var indL = Rarray[i + 1];
                var indR = Rarray[ns.Length - i];
                if (indL > indR)
                {
                    int tmp = indL;
                    indL = indR;
                    indR = tmp;
                }

                int indexInE         = rmqHelper.GetMinimum(indL, indR).Index;
                var palindromeLength = Earray[indexInE];

                if (palindromeLength > lenMaxPalindrome)
                {
                    lenMaxPalindrome = palindromeLength;
                    midPalindrome    = i + 1;
                }
            }

            var startPalindrome = midPalindrome - lenMaxPalindrome;
            var endPalindrome   = startPalindrome + 2 * lenMaxPalindrome - 2;
            var lenPalindrome   = endPalindrome - startPalindrome + 1;
            var r = s.Substring(startPalindrome, lenPalindrome);

            return(r);
        }
コード例 #2
0
        public static SuffixTreeNode Build(string s)
        {
            var s2   = '\t' + s + '\t';
            var root = new SuffixTreeNode(0, 0, 0);

            for (int i = 1; i < s2.Length - 1; i++)
            {
                var  currentNode  = root;
                var  indexInWord  = i;
                bool alreadyAdded = false;
                while (currentNode.children.TryGetValue(s2[indexInWord], out SuffixTreeNode searchedChild))
                {
                    int endMatchIndex = indexInWord;
                    int indInFound    = searchedChild.startIndex;
                    while (s2[endMatchIndex] == s2[indInFound] && indInFound <= searchedChild.endIndex)
                    {
                        endMatchIndex++;
                        indInFound++;
                    }
                    bool wholeWord = indInFound == searchedChild.endIndex + 1;
                    if (!wholeWord)
                    {
                        var nodeOldChildren = new SuffixTreeNode(indInFound, searchedChild.endIndex, searchedChild.subwordStartIndex);
                        nodeOldChildren.children = searchedChild.children;
                        var newNode = new SuffixTreeNode(endMatchIndex, s2.Length - 1, i);
                        searchedChild.children = new Dictionary <char, SuffixTreeNode>
                        {
                            { s2[indInFound], nodeOldChildren },
                            { s2[endMatchIndex], newNode }
                        };

                        searchedChild.endIndex = indInFound - 1;
                        alreadyAdded           = true;
                        break;
                    }
                    else
                    {
                        currentNode = searchedChild;
                        indexInWord = endMatchIndex;
                    }
                }
                if (!alreadyAdded)
                {
                    var newNode = new SuffixTreeNode(indexInWord, s2.Length - 1, i);
                    currentNode.children.Add(s2[indexInWord], newNode);
                }
            }

            root.UpdateDepth(0);
            return(root);
        }