Next Palindrome:分段故障

时间:2015-06-30 10:39:53

标签: c segmentation-fault palindrome

我正在尝试解决SPOJ上的Next Palindrome问题。以下是问题SPOJ的链接
这是我的问题代码。当我在我的机器上运行以下测试用例时,我得到了正确的结果:

  

9 11
99 101
808 818

这是我的代码:

#include<stdio.h>
#include<string.h>

char k[1000004];

int find_palin(char num[])
{
int len = strlen(num);
char str1[1000004] = {NULL};
char str3[500002] = {NULL};
char str2[500002] = {NULL};
char rev[500002] ={NULL};

if(len%2==0)
{
    int half = (len)/2;
    int i;
    int j=0;

    for(i=1;i<=len-1;++i)
    {
        if(num[i]!='0')
            break;

        k[i]='0';
    }

    if(i>len-1)
    {
        k[0]=num[0];
        k[len-1]=num[0];
        return 0;
    }

    for(i=0;i<half;++i)
        str1[i] = num[i];

    for(i=half;i<len;++i)
        str3[j++] = num[i];

    for(i=0 , j=half-1;i<half;++i,--j)
    {
        if(str3[i]>=str1[j])
            break;
        else
            rev[i]=str1[j];
    }

    if(i>=half)
    {
        strcat(str1,rev);
        for(i=0;i<len;++i)
            k[i]=str1[i];
        return 0;
    }
    else
    {
        for(i=0;i<half;++i)
            str3[i] = '0';

        if(str1[half-1]!='9')
            str1[half-1]++;
        else
        {
            for(i=half-1;i>=0;--i)
            {
                if(str1[i]=='9')
                    str1[i] = '0';
                else
                {
                    str1[i]++;
                    break;
                }
            }
            if(i<0)
            {
                str1[half]='0';
                str1[0] = '1';
            }
        }

        strcat(str1,str3);
        find_palin(str1);
    }
}
else
{
    int half = (len-1)/2;
    int i;
    int j=0;

    if(len==1)
    {
        if(num[0]=='9')
        {
            k[0] = '1';
            k[1] = '1';
            return 0;
        }
        k[0] = ++num[0];
        return 0;
    }

    for(i=1;i<=len-1;++i)
    {
        if(num[i]!='0')
            break;

        k[i]='0';
    }

    if(i>len-1)
    {
        k[0]=num[0];
        k[len-1]=num[0];
        return 0;
    }

    for(i=0;i<half;++i)
        str1[i] = num[i];

    for(i=half+1;i<len;++i)
        str3[j++] = num[i];

    str2[0] = num[half];

    for(i=0 , j=half-1;i<half;++i,--j)
    {
        if(str3[i]>=str1[j])
            break;
        else
            rev[i]=str1[j];
    }

    if(i>=half)
    {
        strcat(str2 , rev);
        strcat(str1 , str2);
        for(i=0;i<len;++i)
            k[i]=str1[i];
        return 0;
    }
    else
    {
        for(i=0;i<half;++i)
            str3[i] = '0';

        if(str2[0]!='9')
        {
            str2[0]++;
            strcat(str2,str3);
            strcat(str1,str2);
            find_palin(str1);
        }
        else
        {
            str2[0] = '0';

            if(str1[half-1]!='9')
                str1[half-1]++;
            else
            {
                for(i=half-1;i>=0;--i)
                {
                    if(str1[i]=='9')
                        str1[i] = '0';
                    else
                    {
                        str1[i]++;
                        break;
                    }
                }
                if(i<0)
                {
                    str1[half]='0';
                    str1[0] = '1';
                }
            }

            strcat(str2,str3);
            strcat(str1,str2);
            find_palin(str1);
        }
    }
}
}

int main()
{
char input[1000004];
int t;

scanf("%d" , &t);

int i;

for(i=0;i<t;++i)
{
    scanf("%s" , &input);
    find_palin(input);
    printf("%s\n" , k);
}
return 0;
}

当我尝试提交代码时,它会给出Segmentation Fault。有人可以帮助我,为什么我收到这个错误?

1 个答案:

答案 0 :(得分:0)

使用大型数组的方法是在heap not on the stack上分配内存。我已经在你的程序中为你做了这个。我没有在main中这样做,而是懒洋洋地将input[]移动为全局var。由于递归,您无法在find_palin中执行此操作,无论如何全局变量都不受欢迎。

我还将所有return 0语句更改为goto,以便进行常规清理。它并不优雅,但我并不想改变你的代码结构。

我还调整了一些其他的东西,例如检查输入是否有效,以及使用单个#define从中导出指定的所有其他尺寸。

#include<stdio.h>
#include<string.h>

#define ARRSIZE 1000004                 // don't hard code stuff

char k[ARRSIZE];
char input[ARRSIZE];                    // move out of main

void find_palin(char num[])             // change return type to void
{
    int len = strlen(num);
    char *str1 = calloc(ARRSIZE,   sizeof(*str1));  // allocate and zero
    char *str2 = calloc(ARRSIZE/2, sizeof(*str2));
    char *str3 = calloc(ARRSIZE/2, sizeof(*str3));
    char *rev  = calloc(ARRSIZE/2, sizeof(*rev));
    if (str1 == NULL || str2 == NULL || str3 == NULL || rev == NULL)
        exit (1);                       // check memory allocations

    if(len%2==0)
    {
        int half = (len)/2;
        int i;
        int j=0;

        for(i=1;i<=len-1;++i)
        {
            if(num[i]!='0')
                break;

            k[i]='0';
        }

        if(i>len-1)
        {
            k[0]=num[0];
            k[len-1]=num[0];
            goto endfunc;               // replace all return statements
        }

        for(i=0;i<half;++i)
            str1[i] = num[i];

        for(i=half;i<len;++i)
            str3[j++] = num[i];

        for(i=0 , j=half-1;i<half;++i,--j)
        {
            if(str3[i]>=str1[j])
                break;
            else
                rev[i]=str1[j];
        }

        if(i>=half)
        {
            strcat(str1,rev);
            for(i=0;i<len;++i)
                k[i]=str1[i];
            goto endfunc;
        }
        else
        {
            for(i=0;i<half;++i)
                str3[i] = '0';

            if(str1[half-1]!='9')
                str1[half-1]++;
            else
            {
                for(i=half-1;i>=0;--i)
                {
                    if(str1[i]=='9')
                        str1[i] = '0';
                    else
                    {
                        str1[i]++;
                        break;
                    }
                }
                if(i<0)
                {
                    str1[half]='0';
                    str1[0] = '1';
                }
            }

            strcat(str1,str3);
            find_palin(str1);
        }
    }
    else
    {
        int half = (len-1)/2;
        int i;
        int j=0;

        if(len==1)
        {
            if(num[0]=='9')
            {
                k[0] = '1';
                k[1] = '1';
                goto endfunc;
            }
            k[0] = ++num[0];
            goto endfunc;
        }

        for(i=1;i<=len-1;++i)
        {
            if(num[i]!='0')
                break;

            k[i]='0';
        }

        if(i>len-1)
        {
            k[0]=num[0];
            k[len-1]=num[0];
            goto endfunc;
        }

        for(i=0;i<half;++i)
            str1[i] = num[i];

        for(i=half+1;i<len;++i)
            str3[j++] = num[i];

        str2[0] = num[half];

        for(i=0 , j=half-1;i<half;++i,--j)
        {
            if(str3[i]>=str1[j])
                break;
            else
                rev[i]=str1[j];
        }

        if(i>=half)
        {
            strcat(str2 , rev);
            strcat(str1 , str2);
            for(i=0;i<len;++i)
                k[i]=str1[i];
            goto endfunc;
        }
        else
        {
            for(i=0;i<half;++i)
                str3[i] = '0';

            if(str2[0]!='9')
            {
                str2[0]++;
                strcat(str2,str3);
                strcat(str1,str2);
                find_palin(str1);
            }
            else
            {
                str2[0] = '0';

                if(str1[half-1]!='9')
                    str1[half-1]++;
                else
                {
                    for(i=half-1;i>=0;--i)
                    {
                        if(str1[i]=='9')
                            str1[i] = '0';
                        else
                        {
                            str1[i]++;
                            break;
                        }
                    }
                    if(i<0)
                    {
                        str1[half]='0';
                        str1[0] = '1';
                    }
                }

                strcat(str2,str3);
                strcat(str1,str2);
                find_palin(str1);
            }
        }
    }

endfunc:                                    // free the memory
    free(rev);
    free(str3);
    free(str2);
    free(str1);
}

int main()
{
    int t;
    int i;

    if (1 != scanf("%d" , &t))              // check garbage input
        exit (1);
    for(i=0;i<t;++i)
    {
        if (1 != scanf("%s" , input))       // remove &
            exit (1);                       // check garbage input
        find_palin(input);
        printf("%s\n" , k);
    }
    return 0;
}