【编程题目】寻找丑数
题目:我们把只包含因子 2、3 和 5 的数称作丑数(Ugly Number)。例如 6、8 都是丑数,
但 14 不是,因为它包含因子 7。习惯上我们把 1 当做是第一个丑数。
求按从小到大的顺序的第 1500 个丑数。
思路:
1. 数字从1递增,判断是不是丑数
2. 用2、3、5分别乘以已有的丑数,用大于当前的丑数的结果中最小的作为当前的丑数 快!
/* 64. 寻找丑数(运算)。 题目:我们把只包含因子 2、3 和 5 的数称作丑数(Ugly Number)。例如 6、8 都是丑数, 但 14 不是,因为它包含因子 7。习惯上我们把 1 当做是第一个丑数。 求按从小到大的顺序的第 1500 个丑数。 */ #include <stdio.h> #include <stdlib.h> int uglynum(int n) //输入要找第几个丑数 { long int i; int num = 1; for (i = 2; num < n; i++) { int flag = 0; int d = i; while (d != 1 && 0 == flag) { if (d % 2 == 0) { d = d/2; } else if (d % 3 == 0) { d = d/3; } else if (d % 5 == 0) { d = d/5; } else { flag = 1; } } if (0 == flag) { num++; } } return (i - 1); } int uglynum2(int n) //输入要找第几个丑数 { if (n == 1) { return 1; } int* data = (int *)malloc(n * sizeof(n)); data[0] = 1; int b[3] = {2, 3, 5}; for (int i = 1; i < n; i++) { int mintmp = 2 * data[i - 1]; //存储比上一个数字大的数中最小的那个 初始化这个数 for(int m = 0; m < 3; m++) { for (int j = 0; j < i; j++) { if (data[j] * b[m] > data[i - 1]) { if (data[j] * b[m] < mintmp) { mintmp = data[j] * b[m]; } break; } } } data[i] = mintmp; } int ans = data[n - 1]; free(data); return ans; } int main() { //long int d = uglynum(1500); //d = uglynum2(1500); for (int i = 2; i <= 1500; i++) { int d = uglynum2(i); printf("第%d个丑数为:%d\n", i, d); } return 0; }
网上看答案,发现自己写的不好,虽然思路一样,但是我写的看起来很乱。而且在方法二中我对 2 3 5都是从第一个数字开始乘,实际上可以用三个指针记录上一次乘到哪里了,下一次从记录位开始找就好了。
还有,有些子功能可以写成子函数,可以让整个代码看起来更清晰。
http://www.cnblogs.com/mingzi/archive/2009/08/04/1538491.html 里的代码就看起来很舒服。
方法一:
bool IsUgly(int number) { while(number % 2 == 0) number /= 2; while(number % 3 == 0) number /= 3; while(number % 5 == 0) number /= 5; return (number == 1) ? true : false; } int GetUglyNumber_Solution1(int index) { if(index <= 0) return 0; int number = 0; int uglyFound = 0; while(uglyFound < index) { ++number; if(IsUgly(number)) { ++uglyFound; } } return number; }
方法二:
int GetUglyNumber_Solution2(int index) { if(index <= 0) return 0; int *pUglyNumbers = new int[index]; pUglyNumbers[0] = 1; int nextUglyIndex = 1; int *pMultiply2 = pUglyNumbers; int *pMultiply3 = pUglyNumbers; int *pMultiply5 = pUglyNumbers; while(nextUglyIndex < index) { int min = Min(*pMultiply2 * 2, *pMultiply3 * 3, *pMultiply5 * 5); pUglyNumbers[nextUglyIndex] = min; while(*pMultiply2 * 2 <= pUglyNumbers[nextUglyIndex]) ++pMultiply2; while(*pMultiply3 * 3 <= pUglyNumbers[nextUglyIndex]) ++pMultiply3; while(*pMultiply5 * 5 <= pUglyNumbers[nextUglyIndex]) ++pMultiply5; ++nextUglyIndex; } int ugly = pUglyNumbers[nextUglyIndex - 1]; delete[] pUglyNumbers; return ugly; } int Min(int number1, int number2, int number3) { int min = (number1 < number2) ? number1 : number2; min = (min < number3) ? min : number3; return min; }