示例#1
0
        public RMQHelper(int[] inputArray)
        {
            this.inputArray = inputArray;
            var cartesian = CartesianTreeNode.BuildCartesian(inputArray);

            Earray = new int[inputArray.Length * 2 - 1];
            Aarray = new int[inputArray.Length * 2 - 1];
            Rarray = new int[inputArray.Length];

            cartesian.WriteToArrays(Earray, 0, Aarray, Rarray);
            innerHelper = new RMQPM1Helper(Aarray);
        }
示例#2
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);
        }
        public static void BasicTest()
        {
            int[] arr = new[] { 0, 34, 65, 85, 23, 434, 43, 26, 786, 563, 2, 4, 46, 47, 74, 3, 13, 45, 85 };
            arr = arr.Zip(arr.Skip(1)).Select(t => t.First > t.Second ? -1 : 1).ToArray();
            for (int i = 1; i < arr.Length; i++)
            {
                arr[i] = arr[i] + arr[i - 1];
            }

            RMQPM1Helper helper   = new RMQPM1Helper(arr);
            int          expected = arr.Skip(2).Take(5).Min();
            int          actual   = helper.GetMinimum(2, 6).Value;

            if (expected != actual)
            {
                throw new Exception("Basic test failed");
            }
        }
        public static void LongTest(int maxTestArrayLength = 10000000, int testArraysCount = 2, int testsPerArray = 5)
        {
            Random rand = new Random();

            for (int testArrayNr = 0; testArrayNr < testArraysCount; testArrayNr++)
            {
                int   testArrayLength = rand.Next() % (maxTestArrayLength - 10) + 10;
                int[] testArray       = new int[testArrayLength];
                for (int j = 1; j < testArrayLength; j++)
                {
                    testArray[j] = rand.Next();
                }

                testArray = testArray.Zip(testArray.Skip(1)).Select(t => t.First > t.Second ? -1 : 1).ToArray();
                for (int i = 1; i < testArray.Length; i++)
                {
                    testArray[i] = testArray[i] + testArray[i - 1];
                }

                RMQPM1Helper finder = new RMQPM1Helper(testArray);

                for (int test = 0; test < testsPerArray; test++)
                {
                    int i     = rand.Next() % (testArrayLength - 1);
                    int count = rand.Next() % (testArrayLength - i - 1) + 1;
                    int j     = i + count - 1;

                    int expected      = testArray.Skip(i).Take(count).Min();
                    int actual        = finder.GetMinimum(i, j).Value;
                    var actualByIndex = testArray[finder.GetMinimum(i, j).Index];

                    if (actual != expected || actualByIndex != expected)
                    {
                        throw new Exception("Long test failed");
                    }
                }
            }
        }