问题是这样的:编写一个算法来判断一个数是不是“快乐数”。
一个“快乐数”定义为:对于一个正整数,每一次将该数替换为它每一个位置上的数字的平方和,然后重复这个过程,直到这个数变为1,也可能是无限循环但始终变不到1,如果可以变为1,那么这个数就是快乐数。
示例:
输入: 19 输出: true 解释: 12 + 92 = 82 82 + 22 = 68 62 + 82 = 100 12 + 02 + 02 = 1
解法:对于这一道题而言:思路就是根据快乐数的描述,首先开始要对这个数进行判断是否为正整数。接着计算出这个数有多少位,并且根据位数来算出每个位上的平方在算出平方和。然后在进行循环。
这个问题中有一个就是说有可能无限循环所以要考虑什么样的数会无限循环。当然人脑是无法短时间内看出其中的奥妙的,那么就让计算机来测试吧,我用了100个1万以内数进行测试,尝试发现其中的循环条件。下面就是
测试用例代码:
#include<iostream> #include<cmath> #include<ctime> using namespace std; class Solution { public: bool isHappy(int n) { if (n > 0) { int x = n; int count = 0; int SumS = 0; int i = 0; cout << n << ":"; while ((x != 1) && (x != 0) && (i < 20)) { i++; count = IsNCount(x); SumS = Sum(x, count); cout << SumS << " "; x = SumS; //if (x == 4) //{ // return false; //} } cout << endl; if (x == 1) { return true; } else { return false; } } return false; } //求这个数有多少位 int IsNCount(int x) { int count = 0; while (x != 0) { x = x / 10; count++; } return count; } //把每个数的每一位进行处理 int Sum(int x, int count) { int sum = 0; int i = count - 1; //cout << x << ":"; while (i >= 0) { sum = (x / (int)pow(10, i)) * (x / (int)pow(10, i)) + sum; //cout << sum; x = x % (int)pow(10, i); i--; } //cout << endl; return sum; } }; int main() { int num; int i = 0; srand((unsigned int)time(NULL)); while (i < 100) { num = rand() % 10000; Solution S; cout << endl; cout << "IsHappyNum:"; cout << S.isHappy(num) << endl; i++; } system("pause"); return 0; }
运行显示:
特别说明:由于窗口无法全部显示,我只能截取一部分,但这足够发现其中规律。
运行结果说明:上面只要不是快乐数的数字,无一里面不包含这样几个数字:4,16,37,58,89,145,42,20.在后续的计算平方和中依次进行循环。
所以对于无限循环的情况进行判断只要有一次数的平方和是这8个数中一个就不再计算直接返回false。
代码实现:
class Solution { public: bool isHappy(int n) { if(n > 0) { int x = n; int count = 0; int SumS = 0; while((x != 1) && (x != 0)) { count = IsNCount(x); SumS=Sum(x, count); x = SumS; if(x == 4) { return false; } } if(x == 1) { return true; } else { return false; } } return false; } //求这个数有多少位 int IsNCount(int x) { int count = 0; while(x != 0) { x = x / 10; count++; } return count; } //把每个数的每一位进行处理 int Sum(int x, int count) { int sum=0; int i = count - 1; while(i >= 0) { sum = (x / (int)pow(10, i) ) * (x / (int)pow(10, i) ) + sum; x = x % (int)pow(10, i); i--; } return sum; } };
提交结果:
珍&源码