C ++:Happy Number Endless Loop

时间:2014-08-14 22:00:54

标签: c++ optimization

我创建了一个函数来查找第一个X Happy Numbers

  

幸福的数字由以下过程定义。从任何开始   正整数,将数字替换为其平方和   数字,并重复该过程,直到数字等于1(其中   将留下来,或者它在一个不包括1的循环中无休止地循环

我的问题是我怎么知道它在一个循环中无休止地循环?我目前正在做的是计算它通过平方和函数的次数,如果它是> 10,它只会返回0.这是我的代码..

C ++

#include <iostream>
#include <cmath>
#include <cstdlib>
using namespace std;

int k, rep = 0;

int SumOfSq(int num) {
    int total = 0;
    while(num) {
        int digit = num % 10;
        num /= 10;
        total += pow(digit,2);
    }
    return total;
}

bool Happy(int num) {
    int temp = 0;
    while(num != 1) {
        if(k == rep) exit(1);
        num = SumOfSq(num);
        if(temp++ > 10) {
            return 0; //Not happy
        }
    }
    rep++;
    return 1; //Happy
}

int main() {
    cout << "How many Happy Numbers to find? ";
    cin >> k;
    for(int j = 1;;j++) 
        if(Happy(j)) cout << j << " ";
}

如果我的代码有任何错误或需要改进的地方,也请告诉我。当前输出应该是正确的。

6 个答案:

答案 0 :(得分:5)

来自Happy numbers上的wiki:

如果n很满意,那么它的序列将变为1.否则,它将在循环中结束:

4, 16, 37, 58, 89, 145, 42, 20, 4, ... 

所以,看看你是否已登陆其中一个数字,看看你是否处于不愉快的周期。

另一种跟踪您已经看过的号码的方法,如果您计划在许多情况下旅行超过8个号码,这可能会更好。

答案 1 :(得分:2)

TheGoatMan7给出了这个问题的实际答案,但我想我应该添加一个答案,至少部分解释如何到达那里。正整数n中的位数等于floor(log n/log 10)+1。那么,该数字的数字的平方和总和高于81*floor(log n/log 10 + 1)。您应该能够看到n足够大时,这将小于n。也就是说,当n很大时,n的数位的平方和小于n。让我们在这个截止点上放一个松散的上限:

81*floor(log 1000/log 10+1) = 81*4 < 1000

现在你可以看到当n&gt; 1000,n上的数字的平方和小于n。无论你开始使用什么数字,你最终都会低于1000并保持在那里,要么稳定或循环数字低于1000.所以你只需要担心1000以下的数字,以及最多1000步的循环。这只是几百万次操作,很容易通过蛮力完成。


我刚刚看到基本问题是关于列出快乐的数字,而不是检查数字是否满意。有效地执行此操作看起来很复杂,但我可能会从这个事实开始:

定理

n是一个快乐的数字,当且仅当每个数字m(其数字的平方和为n)是一个满意的数字时。现在每个非零自然是无数许多其他自然数字的平方和,因此需要注意将所有这些都按正确的顺序排列,但我猜想它会以更快的速度结束。让我们看看这是如何开始的。

1是一个快乐的数字。 因此也是如此 10,100,1000,10000,......

10 = 1 + 9 = 2 * 4 + 2 * 1 = 4 + 6 * 1 = 10 * 1是一个满意的数字。因此,也是如此 13,31,103,301,1003,3001,......, 1122,1212,1221,2112,2121,2211,10122,10212,10221,.... 1111112,1111121,1111211,1112111,1121111,1211111,2111111,10111112,10111121,... 1111111111,10111111111,110111111111,...

当然,这些列表需要合并。对于复杂的簿记,这种方法似乎交易了复杂的检查每个数字方法的算法。我不知道是否有办法让这件事值得一试。

答案 2 :(得分:2)

Happy Number序列的C代码示例:

#include<stdio.h>
#include<math.h>
int happy(int t)
{
  long sum=0;
  int r;
  while(t>0)
  {
    r=t%10;
    t/=10;
    sum+=pow(r,2);
  }
  if(sum==4||sum==16||sum==37||sum==58||sum==89||sum==145||sum==42||sum==20)
    return 0;
  else if(sum==1)
    return sum;
  else
    return happy(sum);
}

int main()
{
    int n,i;
    printf("Enter the range: ");
    scanf("%d",&n);
    for(i=1;i<=n;i++)
    {
        if(happy(i)==1)
            printf("%d ",i);
    }
    return 0;
}

答案 3 :(得分:1)

  

这是我的C解决方案。对我来说很好。

cell.EntireRow.offset(-1).Delete

答案 4 :(得分:0)

对于来自wiki Happy numbers的前1000个满意数字,这是真的:

  

if(temp ++&gt; 5){            返回0; //不开心}

即。你不必迭代超过6次。

答案 5 :(得分:0)

WIKI的定义 :以任何正整数开头,用数字的平方和代替数字,然后重复此过程,直到数字等于1 (它将停留的位置),或者在不包含1的循环中无限循环。此过程以1结尾的数字是快乐数字,而没有以1结尾的数字是不快乐数字(或悲伤数字)。

如果说有任何数字是快乐的,那么涉及该序列的任何数字也是快乐的数字。 示例:以7开头的序列为7、49、97、130、10、1,因此7是一个快乐数字。

同样,如果任何数字被认为是不满意的,那么涉及该序列/周期的任何数字也是不快乐的数字。 示例:从4开始给出序列4、16、37、58、89、145、42、20、4,这导致一个循环,所以4是一个不愉快的数字。

检查“ n”是否为快乐数字的函数(返回true),否则返回false

class Solution {                                           
public:
   bool isHappy(int n) {                         // funtion to check 
   if (n <= 0) return false;                     // if negative cannot be a happy number

    int magic = 4;                                // it a unhappy number 
    while (1)
    {
    if (n == 1) return true;                  // if n becomes 1 then it is happy number 
    if (n == magic) return false;             // if n becomes equal to 4 then the cycle cannot become happy
    int t = 0;
    while (n)                                 
    {
        t += (n % 10) * (n % 10);             // adding square of digit square of digits
        n /= 10;
    }
    n = t;
    }
    }
};