例14 丑数
问题描述
丑数是其质因子只可能是2,3或5的数。前10个丑数分别为1, 2, 3, 4, 5, 6, 8, 9, 10, 12。输入一个正整数n,求第n个丑数。
输入格式
每行为一个正整数n (n <= 1500),输入n=0结束。
输出格式
每行输出一个整数,表示求得的第n个丑数。
输入样例
1
2
50
0
输出样例
1
2
243
(1)编程思路。
根据丑数的定义,丑数从小到大排列的序列中的一个数应该是其前面某个数乘以2、3或者5的结果。因此,可以定义一个数组num[1501]来顺序保存序列中的丑数,数组里面的每一个元素的值是前面的某个元素值乘以2、3或者5得到。
问题的关键是怎样确保数组里面的各元素是按值的大小依次生成的。
假设数组中已经有若干个序列中的元素,排好序后存在数组中。把序列中现有的最大的数记做M。由于序列中的下一个数肯定是前面某一个数乘以2、3或者5的结果。首先考虑把已有的每个数乘以2。在乘以2的时候,能得到若干个结果小于或等于M的。由于数组中的元素是按照顺序生成的,小于或者等于M的数肯定已经在数组中了,不需再次考虑;还会得到若干个大于M的结果,但只需要第一个大于M的结果,因为数组中的元素是按值从小到大顺序生成的,其他更大的结果可以以后再说,记下得到的第一个乘以2后大于M的数M2。同样,把已有的每一个数乘以3和5,记下得到的第一个大于M的结果M3和M5。那么,序列中下一个数应该是M2、M3和M5三个数的最小者。
事实上,上面所说的把数组中已有的每个数分别都乘以2、3和5,是不需要的,因为已有的数是按顺序存在数组中的。对乘以2而言,肯定存在某一个数T2,排在它之前的每一个数乘以2得到的结果都会小于已有最大的数,在它之后的每一个数乘以2得到的结果都会太大。因此,只需要记下这个数的位置P2,同时每次生成一个新的序列中的数的时候,去更新这个P2。对乘以3和5而言,存在着同样的P3和P5。
定义变量index保存当前待生成的数在序列中的序号,显然,已生成的序列中的最大元素为Num[curIndex-1]。
定义3个指针变量int *p2,*p3,*p5;分别指向数组中的3个元素,排在所指元素之前的每一个数乘以2(或3、或5)得到的结果都会小于已有最大的数num[index-1],在所指元素之后的每一