google面试题目:寻找丑数
[cpp]
/*******************************************************************************
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.
************************************************************************/
#include<cstdio>
#include<iostream>
#include<cstdlib>
using namespace std;
/*the smallest in the three*/
int mymin(int a, int b, int c)
{
int temp = (a < b ? a : b);
return (temp < c ? temp : c);
}
int FindUgly(int n)
{
int* ugly = new int[n];
ugly[0] = 1;
int index2 = 0;
int index3 = 0;
int index5 = 0;
int index = 1;
while (index < n)
{
int val = mymin(ugly[index2]*2, ugly[index3]*3, ugly[index5]*5);
//竞争产生下一个丑数
if (val == ugly[index2]*2)
//将产生这个丑数的index*向后挪一位;
++index2;
if (val == ugly[index3]*3)
//这里不能用elseif,因为可能有两个最小值,这时都要挪动;
++index3;
if (val == ugly[index5]*5)
++index5;
ugly[index++] = val;
}
int result = ugly[n-1]; //ugly[0] = 1 是第一个丑数
delete[] ugly;
return result;
}
int main()
{
int num=1;
cout<<"input the number:"<<endl;
cin>>num;
cout<<"the "<<(num)<<" th agly number is "<<FindUgly(num);
return 0;
}
/*******************************************************************************
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.
************************************************************************/
#include<cstdio>
#include<iostream>
#include<cstdlib>
using namespace std;
/*the smallest in the three*/
int mymin(int a, int b, int c)
{
int temp = (a < b ? a : b);
return (temp < c ? temp : c);
}
int FindUgly(int n)
{
int* ugly = new int[n];
ugly[0] = 1;
int index2 = 0;
int index3 = 0;
int index5 = 0;
int index = 1;
while (index < n)
{
int val = mymin(ugly[index2]*2, ugly[index3]*3, ugly[index5]*5);
//竞争产生下一个丑数
if (val == ugly[index2]*2)
//将产生这个丑数的index*向后挪一位;
++index2;
if (val == ugly[index3]*3)
//这里不能用elseif,因为可能有两个最小值,这时都要挪动;
++index3;
if (val == ugly[index5]*5)
++index5;
ugly[index++] = val;
}
int result = ugly[n-1]; //ugly[0] = 1 是第一个丑数
delete[] ugly;
return result;
}
int main()
{
int num=1;
cout<<"input the number:"<<endl;
cin>>num;
cout<<"the "<<(num)<<" th agly number is "<<FindUgly(num);
return 0;
}
补充:软件开发 , C++ ,