1. 程式人生 > >設計一個演算法,找出只含素因子2,3,5 的第 n 小的數

設計一個演算法,找出只含素因子2,3,5 的第 n 小的數

醜數為值只包含因子 2、 3、 5 的數,14不是醜數因為包含因子7.

/*int min(int a,int b){
        if(a>b){
            return b;
        }else{
            return a;
        }
    }*/C++中存在min函式,可以直接使用
    int nthUglyNumber(int n) {
        int num[n+1];
         int p2,p3,p5;
         p2=p3=p5=0;
         num[0]=1;

        for
(int i=1;i<n;i++) { num[i]=min(min(num[p2]*2,num[p3]*3),min(num[p2]*2,num[p5]*5)); if(num[i]==num[p2]*2) ++p2; if(num[i]==num[p3]*3) ++p3; if(num[i]==num[p5]*5) ++p5; } return num[n-1
]; }

1.
當前醜數必定是之前某個醜數 k 的 2倍、3倍、或者 5倍。
設定一個整型陣列num[]存放醜數,當前醜數為2*num[p2],3*num[p3],5*num[p5]中的最小值,其中p2,p3,p5之前第p2,p3,p5個醜數,p2,p3,p5初值均為0。
2.
設陣列第一個數值num[0]=1,分別用2,3,5乘1尋找第二個醜數,得到最小值2作為第二個醜數即num[1]=2。
2*num[p2]=2*num[0]=2*1=2
3*num[p3]=3*num[0]=3*1=3
5*num[p5]=5*num[0]=5*1=5
因為第二個醜數是2與上一個醜數相乘得到的,因此在下一次尋找醜數時不需要再計算2與對應相乘的上一個醜數num[p2]相乘,因為下一個醜數一定大於num[1]即2*num[0]。所以在下一次計算醜數時,直接從nun[1]開始乘以2,即p2進一位。
3.
分別用2*num[p2],3*num[p3],5*num[p5]判斷第三個醜數,p2=1,p3=p5=0.
2*num[p2]=2*num[1]=2*2=4
3*num[p3]=3*num[0]=3*1=3
5*num[p5]=5*num[0]=5*1=5
得到最小值3作為第三個醜數,因此在下一次尋找醜數時不需要再計算3與對應相乘的上一個醜數num[0]相乘,因為下一個醜數一定大於3*num[0]即num[2]。所以在下一次計算醜數時,直接從num[1]乘以3,即下表p3進一位。
4.以此類推找到第n個最小值為第n個醜數。