Home > Back-end >  How to find all the palindromes in a large array?
How to find all the palindromes in a large array?

Time:03-25

I need to find all the palindromes of π with 50 million digits 3.141592653589793238462643383279502884197169399375105820974944592307816406286... (goes on and on...)

I've stored all the digits of π in a char array. Now I need to search and count the number of 'palindromes' of length 2 to 15. For example, 535, 979, 33, 88, 14941, etc. are all valid results.

The final output I want is basically like the following.

Palindrome length           Number of Palindromes of this length
-----------------------------------------------------------------
   2                                  1234 (just an example)
   3                                  1245
   4                                  689
  ...                                 ...
  ...                                 ...
  ...                                 ...
  ...                                 ...
   15                                  0

pseudocode of my logic so far - it works but takes forever

//store all digits in a char array
char *piArray = (char *)malloc(NUM_PI_DIGITS * sizeof(char));
int count = 0; //count for the number of palindromes

//because we only need to find palindroms that are 2 - 15 digits long
for(int i = 2; i <= 15; i  ){
     //loop through the piArray and find all the palindromes with i digits long
     for(int j = 0; j < size_of_piArray; j  ){
            //check if the the sub array piArray[j:j i] is parlindrom, if so, add a count
            bool isPalindrome = true;
            for (int k = 0; k < i / 2; k  )
            {
                if (piArray [j   k] != piArray [j   i - 1 - k])
                {
                    isPalindrom = false;
                    break;
                }
            }
             if(isPalindrome){
                  count  ;
             }
     }
}

The problem I am facing now is that it takes too long to loop through the array of this large size (15-2)=13 times. Is there any better way to do this?

CodePudding user response:

I can't solve it for C, as I'm a C# dev but I expect the conversion will be trivial - I've tried to keep it as basic as possible

    char[] pi = "3.141592653589793238462643383279502884197169399375105820974944592307816406286".ToCharArray(); //get a small piece as an array of char
    int[] lenCounts = new int[16]; //make a new int array with slots 0-15
    
    for(int i = 1; i < pi.Length-1; i  ){

        if(pi[i 1] == pi[i-1]){ //center of an odd length pal
            int n = 2; 
            while(pi[i n] == pi[i-n] && n <= 7) n  ;
            lenCounts[((n-1)*2 1)]  ;
            
        } else if(pi[i] == pi[i-1]){ //center of an even length pal
            int n = 1;
            while(pi[i n] == pi[i-1-n] && n <= 7) n  ;
            lenCounts[n*2]  ;
            
        } 
            
            
    }
    

This demonstrates the "crawl the string looking for a palindrome center then crawl away from it in both directions looking for equal chars" technique..

..the only thing I'm not sure on, and it has occurred in the Pi posted, is what you want to do if palindromes overlap:

3.141592653589793238462643383279502884197169399375105820974944592307816406286

This contains 939 and overlapping with it, 3993. The algo above will find both, so if overlaps are not to be allowed then you might need to extend it to deal with eliminating earlier palindromes if they're overlapped by a longer one found later

You can play with the c# version at https://dotnetfiddle.net/tkQzBq - it has some debug print lines in too. Fiddles are limited to a 10 second execution time so I don't know if you'll be able to time the full 50 megabyte

  • Related