-3

I'm getting a SIGABRT error when I compile the following code(PALIN problem on SPOJ).The objective of the code is to find smallest palindromic number which should be greater than the given number, where given number can have upto 1000000 digits. Link to the problem is: http://www.spoj.com/problems/PALIN/ It runs well on codeblocks but SPOJ returns SIGABRT error. Can someone explain the reason?

#include<iostream>
#include<string>
using namespace std;
string palinodd(string num)//to find next nearest palindrome for an odd digit number
{
    string palin=num;
    int flag=0;
    for(int i=num.size()/2-1;i>-1;i--)
    {
        if(flag==0)//checks if the middle most digit should be incremented
        {
            if(num[i]<palin[num.size()-i-1])
                flag=1;
            else if(num[i]>palin[num.size()-i-1])
                flag=-1;
        }
        palin[num.size()-1-i]=num[i];
    }
    if(flag!=-1)
        palin[num.size()/2]++;
    if(palin[num.size()/2]==':')//if the middle digit goes greater than 9
    {
        palin[num.size()/2]='0';
        palin[num.size()/2-1]++;
        palin[num.size()/2+1]++;
    }
    return palin;
}
string palineve(string num)//to find next nearest palindrome for an even digit number
{
    string palin=num;
    int flag=0;
    for(int i=num.size()/2-1;i>-1;i--)
    {
        if(flag==0)//checks if middle digit should be incremented
        {
            if(num[i]<palin[num.size()-i-1])
                flag=1;
            else if(num[i]>palin[num.size()-i-1])
                flag=-1;
        }
        palin[num.size()-1-i]=num[i];
    }
    if(flag!=-1)
        palin[num.size()/2-1]++;
    if(palin[num.size()/2-1]==':')//if the middle digit goes greater than 9
    {
        palin[num.size()/2-2]++;
        palin[num.size()/2+1]++;
        palin[num.size()/2-1]='0';
    }
    palin[num.size()/2]=palin[num.size()/2-1];//updates the middle number
    return palin;
}
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        string num="912496394";
        string ans;
        if(num.size()%2!=0)
            ans=palinodd(num);
        else
            ans=palineve(num);
        cout<<ans<<endl;
    }
    return 0;
}
Sc00by_d00
  • 65
  • 1
  • 11

2 Answers2

1

Appreciate your effort, try to match c++ compiler, version in SPOJ and codeblocks. I tried your code with clang++-5.0 after changing num (912496394) to string but i didn't get expected results. I think you might have posted older version of your code, if possible you can post the updated code.

The process will be aborted with SIGABRT if there are any overflows in your code, as you are using more string operations you can refer below link which has some info on SIGABRT, SIGABRT called when calling find() on a string element in an array

One suggestion on your approach to the problem, you can try to increment the input by one in a while loop until you find a palindrome or you reach largest number and print the results

1

The solution I found out for above problem is:

#include<iostream>
#include<string>
using namespace std;
string palinodd(string num)
{
    string palin=num;
    int flag=0;
    for(int i=num.size()/2-1;i>-1;i--)
    {
        if(flag==0)
        {
            if(num[i]<palin[num.size()-i-1])
                flag=1;
            else if(num[i]>palin[num.size()-i-1])
                flag=-1;
        }
        palin[num.size()-1-i]=num[i];
    }
    if(flag!=-1)
        palin[num.size()/2]++;
    if(palin[num.size()/2]==':')
    {
        palin[num.size()/2]='0';
        palin[num.size()/2-1]++;
        palin[num.size()/2+1]++;
    }
    for(int i=num.size()/2-1;i>0;i--)
    {
        if(palin[i]==':')
        {
            palin[i]='0';
            palin[i-1]++;
        }
    }
    for(int i=num.size()/2+1;i<num.size()-1;i++)
    {
        if(palin[i]==':')
        {
            palin[i]='0';
            palin[i+1]++;
        }
    }
    return palin;
}
string palineve(string num)
{
    string palin=num;
    int flag=0;
    for(int i=num.size()/2-1;i>-1;i--)
    {
        if(flag==0)
        {
            if(num[i]<palin[num.size()-i-1])
                flag=1;
            else if(num[i]>palin[num.size()-i-1])
                flag=-1;
        }
        palin[num.size()-1-i]=num[i];
    }
    if(flag!=-1)
        palin[num.size()/2-1]++;
    if(palin[num.size()/2-1]==':')
    {
        palin[num.size()/2-2]++;
        palin[num.size()/2+1]++;
        palin[num.size()/2-1]='0';
    }
    palin[num.size()/2]=palin[num.size()/2-1];
    /*if any incremented digit becomes greater than 9,it shows a ':' so we make it 0 and increase previous(if ':' comes in the first half of the string)/next(if ':' comes in the last half of the sting) digit by 1.*/
    for(int i=num.size()/2-2;i>0;i--)
    {
        if(palin[i]==':')
        {
            palin[i]='0';
            palin[i-1]++;
        }
    }
    for(int i=num.size()/2+1;i<num.size()-1;i++)
    {
        if(palin[i]==':')
        {
            palin[i]='0';
            palin[i+1]++;
        }
    }
    return palin;
}
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        string num,ans;
        cin>>num;
        int cnt=0;
        /*if all the digits in the string are 9, then the next palindromic number will have one more digit than the original number of digits. Thus, increasing the string length*/
        for(int i=0;i<num.size();i++)
        {
            if(num[i]=='9')
                cnt++;
        }
        if(cnt==num.size())
        {
            num[0]='1';
            for(int i=1;i<num.size();i++)
                num[i]='0';
            num+='0';
        }
        if(num.size()%2!=0)
            ans=palinodd(num);
        else
            ans=palineve(num);
        cout<<ans<<endl;
    }
    return 0;
}
Sc00by_d00
  • 65
  • 1
  • 11