发现"快乐的C程序" nums递归地

时间:2016-03-16 18:26:29

标签: c recursion

大家好,我正在尝试实施一个程序,该程序发现快乐数字介于两个数字A和B之间。

对数字的所有数字的平方求和,我们用结果替换数字,并重复该过程。如果经过一些步骤后结果等于1(并保持在那里),那么我们说数字N是**<happy>**。相反,如果过程无限期地重复而没有显示数字1,那么我们说数字N是**<sad>**

例如,数字7很高兴,因为上述程序导致以下步骤:7,49,97,130,10,1,1,1 ......相反,数字42很悲伤因为这个过程导致无限序列42,20,4,16,37,58,89,145,42,20,4,16,37 ......

我试试这个,但我得到segm错误或没有结果。 提前谢谢。

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

void happy( char * A, int n);
int numPlaces (long n);

int main(void)
{
    long A,B;
    int npA;
    char *Ap;
    printf("Give 2 Numbers\n");
    scanf("%li %li",&A,&B);
    npA = numPlaces(A);
    Ap = malloc(npA);
    printf("%ld %d\n",A,npA);
    //Search for happy numbers from A to B
    do{
        sprintf(Ap, "%ld", A);
        happy(Ap,npA);
        A++;
        if ( npA < numPlaces(A) )
        {
            npA++;
            Ap = realloc(Ap, npA);
        }

    }while( A <= B);




}
//Finds happy numbers
void happy( char * A, int n)
    {   
        //Basic Condition
        if ( n == 1)
        {
            if (A[0] == 1 || A[0] == 7)
            printf("%c\n",A[0]);
            printf("%s\n",A);
            return;
        }
        long sum = 0 ;
        char * sumA;
        int nsum;
        int Ai;
        //Sum the squares of the current number
        for(int i = 0 ; i < n;i++)
        {
            Ai = atoi(&A[i]);
            sum = sum +  (Ai*Ai);
        }
        nsum = numPlaces (sum);
        sumA = malloc(nsum);
        sprintf(sumA, "%li", sum);
        happy(sumA,nsum);
        free(sumA);
    }

//Count digits of a number 
int numPlaces (long n) 
    {
        if (n < 0) return 0;
        if (n < 10) return 1;
        return 1 + numPlaces (n / 10);
    }

感谢您的时间。

3 个答案:

答案 0 :(得分:1)

根据您的程序定义,悲伤的数字将导致您的程序永远运行

  

相反,如果该过程无限期重复

你需要添加一个停止条件,比如我已经循环了1000次,或者你是否打了一个众所周知的非终止号码(比如4)(这些是否有明确的列表?我不知道)

答案 1 :(得分:0)

我发现这个解决方案已经过测试和运行.. 谢谢你的时间,我很抱歉我的模糊。 欢迎提出有关此解决方案的任何建议

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

void happy( char * A, int n);
int numPlaces (long n);
int happynum = 0;
int main(void)
{
    long A,B;
    int npA;
    char *Ap;
    printf("Give 2 Numbers\n");
    scanf("%li %li",&A,&B);
    npA = numPlaces(A);
    Ap = malloc(npA);
    //Search for happy numbers from A to B
    do{
        sprintf(Ap, "%ld", A);
        happy(Ap,npA);
        if (happynum ==1)
        printf("%s\n",Ap);
        A++;
        if ( npA < numPlaces(A) )
        {
            npA++;
            Ap = realloc(Ap, npA);
        }

    }while( A <= B);




}
//Finds happy numbers
void happy( char * A, int n)
    {   
        //Basic Condition
        if ( n == 1)
        {
            if (A[0] == '3' || A[0] == '6' || A[0] == '9')
            {
                happynum = 0;
            }    
            else
            {
                happynum = 1;
            }
            return;
        }
        long sum = 0;
        char * sumA;
        int nsum;
        int Ai;
        //Sum the squares of the current number
        for(int i = 0 ; i < n;i++)
        {
            Ai = (int)(A[i]-48);
            sum = sum +  (Ai*Ai);
        }
        nsum = numPlaces (sum);
        sumA = malloc(nsum);
        sprintf(sumA, "%li", sum);
        happy(sumA,nsum);
        free(sumA);
    }

//Count digits of a number 
int numPlaces (long n) 
    {
        if (n < 0) return 0;
        if (n < 10) return 1;
        return 1 + numPlaces (n / 10);
    }

答案 2 :(得分:0)

您的代码使用了一些可疑的做法。 Yoe可能会被误导,因为您担心性能和内存使用情况。

  • 为字符串分配内存时,忘记为null终止符分配一个字符。但是你不应该不断地分配,重新分配和释放。与其他操作相比,动态内存分配很昂贵。

    您的限制为long,可能是32位或64位有符号整数,具体取决于您的平台。可以用e 64位有符号整数表示的最大数量是9,223,372,036,854,775,807。这是一个19位数的数字。为null终止符添加一个,为可能的减号添加一个,这样溢出就不会受到影响,你在堆栈上使用21个字符的缓冲区。

  • 你可能不应该首先使用字符串。使用基本代码提取数字:通过将除数的余数除以10来分割数字。然后除以10直到得到零。 (如果你使用具有固定缓冲区大小的字符串,如上所述,你不必单独计算差异:sprintf返回写入字符串的字符数。

  • 您的功能不应该是递归的。循环就足够了。正如pm100所指出的那样,您需要一个终止标准:您必须跟踪您已访问过的数字。每个递归调用都会创建一个新状态;保持数组更容易,可以在循环中重复查看。当你看到一个你已经看过的号码(当然不是1号)时,你的号码很难过。

幸福和悲伤的数字有这样的属性,当你的平方和是一个已知幸福的数字时,原始数字也有这种幸福。如果您访问已知的das号码,则原始号码很难过。如果您访问已知的快乐号码,原始号码很高兴。

范围的限制可能很大,但方形数字的总和不大;它最多可以是81位的数字。特别是:

    type                   max. number    number of max. square sum       dss

    int                  2,147,483,647                1,999,999,999       730
    uint                 4,294,967,295                3,999,999,999       738
    long     9,223,372,036,854,775,807    8,999,999,999,999,999,999      1522
    ulong   18,446,744,073,709,55,1616    9,999,999,999,999,999,999      1539

这意味着当您获取无符号长整数的数字平方时,您将获得一个小于1540的数字。创建一个包含1540个条目的数组并用1标记所有已知的快乐数字。然后您可以减少一次取数字方块的总和然后在这个数组中查找数字的幸福值的问题。

(您可以在启动程序时对阵列进行一次预先计算。)