/*******************************************************************************
google面试题目:我们把只包含因子2、3和5的数称作丑数(Ugly Number)。
例如6、8都是丑数,但14不是,因为它包含因子7。习惯上我们把1当做是第一个丑数。
求按从小到大的顺序的第2012个丑数。
分析:假设数组ugly[N]中存放不断产生的丑数,
初始只有一个丑数ugly[0]=1,由此出发,
下一个丑数由因子2,3,5竞争产生,得到ugly[0]*2,
ugly[0]*3, ugly[0]*5, 显然最小的那个数是新的丑数,
所以第2个丑数为ugly[1]=2,开始新一轮的竞争,
由于上一轮竞争中,因子2获胜,这时因子2应该乘以ugly[1]才显得公平,
得到ugly[1]*2,ugly[0]*3,ugly[0]*5,
因子3获胜,ugly[2]=3,同理,下次竞争时因子3应该乘以ugly[1],
即:ugly[1]*2, ugly[1]*3, ugly[0]*5, 因子5获胜,得到ugly[3]=5,
重复这个过程,直到第n个丑数产生。总之:
每次竞争中有一个(也可能是两个)因子胜出,下一次竞争中
胜出的因子就应该加大惩罚!
本质就是2 ,3 ,5 的乘积的组合,不过要按照顺序组合,
每次都将2,3,5乘以一个已经是丑数的数,
再比较三者的大小,小的进入数组,然后继续比较
例如:1是丑数,那么下一个2 * 1、3 * 1和5*1,
那么获得的是2,2进入数组,下面比较的是2*2、3*1 和5*1
( 重视因为后面的3*1和5*1的大小并不断定,所以还要持续进行比较)
获得3进入数组,再比较 2 * 2、3 * 2和5*1.
感谢网友的评论,发现了程序的问题
是因为int型表示数据范围有限倒置数据溢出,后来改成unsigned long int 仍然溢出
最后只能改成double 了
三者的表示的数据范围如下:
numeric_limits<int>::max --> 2147483647 第1692个丑数越界
numeric_limits<unsigned long int>::max --> 4294967295 第1849个丑数越界
numeric_limits<double>::max --> 1.79769e+308
google面试题目:我们把只包含因子2、3和5的数称作丑数(Ugly Number)。
例如6、8都是丑数,但14不是,因为它包含因子7。习惯上我们把1当做是第一个丑数。
求按从小到大的顺序的第2012个丑数。
分析:假设数组ugly[N]中存放不断产生的丑数,
初始只有一个丑数ugly[0]=1,由此出发,
下一个丑数由因子2,3,5竞争产生,得到ugly[0]*2,
ugly[0]*3, ugly[0]*5, 显然最小的那个数是新的丑数,
所以第2个丑数为ugly[1]=2,开始新一轮的竞争,
由于上一轮竞争中,因子2获胜,这时因子2应该乘以ugly[1]才显得公平,
得到ugly[1]*2,ugly[0]*3,ugly[0]*5,
因子3获胜,ugly[2]=3,同理,下次竞争时因子3应该乘以ugly[1],
即:ugly[1]*2, ugly[1]*3, ugly[0]*5, 因子5获胜,得到ugly[3]=5,
重复这个过程,直到第n个丑数产生。总之:
每次竞争中有一个(也可能是两个)因子胜出,下一次竞争中
胜出的因子就应该加大惩罚!
本质就是2 ,3 ,5 的乘积的组合,不过要按照顺序组合,
每次都将2,3,5乘以一个已经是丑数的数,
再比较三者的大小,小的进入数组,然后继续比较
例如:1是丑数,那么下一个2 * 1、3 * 1和5*1,
那么获得的是2,2进入数组,下面比较的是2*2、3*1 和5*1
( 重视因为后面的3*1和5*1的大小并不断定,所以还要持续进行比较)
获得3进入数组,再比较 2 * 2、3 * 2和5*1.
感谢网友的评论,发现了程序的问题
是因为int型表示数据范围有限倒置数据溢出,后来改成unsigned long int 仍然溢出
最后只能改成double 了
三者的表示的数据范围如下:
numeric_limits<int>::max --> 2147483647 第1692个丑数越界
numeric_limits<unsigned long int>::max --> 4294967295 第1849个丑数越界
numeric_limits<double>::max --> 1.79769e+308
************************************************************************/
************************************************************************/
#include<iomanip> // 精度控制头文件
#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<limits>
using namespace std;
/*the smallest in the three*/
//无符号长整型 防止数据溢出
double mymin(double a, double b, double c)
{
double temp = (a < b ? a : b);
return (temp < c ? temp : c);
}
//无符号长整型 防止数据溢出
double FindUgly(int n)
{
double* ugly = new double[n];
ugly[0] = 1;
int index2 = 0;
int index3 = 0;
int index5 = 0;
int index = 1;
while (index < n)
{
double val = mymin(ugly[index2]*2, ugly[index3]*3, ugly[index5]*5);
//竞争产生下一个丑数
if (val == ugly[index2]*2)
//将产生这个丑数的index*向后挪一位;
++index2;
if (val == ugly[index3]*3)
//这里不能用elseif,因为可能有两个最小值,这时都要挪动;
++i