經典算法詳解(9)尋找丑數


題目:我們把只含有因子2、3、5的數稱為丑數。例如6、8都是丑數,而14不是丑數,因為它含有因子7.通常也把1當做丑數。編程找出1500以內的全部丑數。注意:使用的算法效率應盡量高。

C++實現:

 1 #include<iostream>
 2 
 3 using namespace std;
 4 
 5 //判斷一個數是否是丑數,uglynum=2*2……*2*3*3*……*3*5*5……*5組成
 6 int isUglyNumber(int n) {
 7     while (n%2==0)
 8     {
 9         n /= 2;
10     }
11     while (n%3==0)
12     {
13         n /= 3;
14     }
15     while (n%5==0)
16     {
17         n /= 5;
18     }
19     return n == 1;
20 }
21 //方法1:逐個判斷是否是丑叔,思路簡單,但是計算冗余,因為越到后面很多都不是丑數也在計算。
22 int get_Ugly_fir(int number) {
23     int i = 1;
24     int count = 0;
25     while (i<=number)
26     {
27         if (isUglyNumber(i)) {
28             cout << i << "\t";
29             count++;
30             if (count % 10 == 0)
31                 cout << endl;
32         }
33         i++;
34     }
35     return count;
36 }
37 
38 //方法二:算法效率高。
39 //思路:(1)后面的丑數肯定是已存在的丑數乘以2、3或者5,找到比現有丑數大的且是最小的丑數作為下一個丑數(如何找是關鍵)。
40 //2分別從現有丑數中從前往后乘以丑數,找到第一個大於當前所有丑數的值以及位置,3、5同樣如此,再把他們相乘之后的結果做對比,取最小的。
41 //下次將從上一次的位置開始往下找,這樣將不會出現冗余,詳細見如下函數。
42 
43 int Next_Ugly(int ugly_arr[], int *loc2, int *loc3, int *loc5, int *index) {
44     while (ugly_arr[*loc2] * 2 <= ugly_arr[*index]) {    //千萬注意這里是小於等於,不要寫成小於了
45         (*loc2)++;
46     }
47     while (ugly_arr[*loc3] * 3 <= ugly_arr[*index]) {
48         (*loc3)++;
49     }
50     while (ugly_arr[*loc5] * 5 <= ugly_arr[*index]) {
51         (*loc5)++;
52     }
53     if (ugly_arr[*loc2] *2< ugly_arr[*loc3]*3) {
54         return (ugly_arr[*loc2] * 2 < ugly_arr[*loc5] * 5) ? ugly_arr[*loc2] * 2 : ugly_arr[*loc5] * 5;
55     }
56     else {
57         return (ugly_arr[*loc3] * 3) < ugly_arr[*loc5] * 5 ? ugly_arr[*loc3] * 3 : ugly_arr[*loc5] * 5;
58     }
59 }
60 
61 int get_Ugly_sec(int num) {
62     int ugly_arr[1000];
63     int index = 0, value = 1;
64     int loc2=0, loc3=0, loc5=0;
65     while (value<=num) {
66         ugly_arr[index] = value;
67         cout << ugly_arr[index] << "\t";
68         if ((index + 1) % 10 == 0)
69             cout << endl;
70         
71         value = Next_Ugly(ugly_arr, &loc2, &loc3, &loc5, &index);
72         index++;
73     }
74     return index;
75 }
76 
77 int main(int argc, char *argv[]) {
78     get_Ugly_fir(1500);
79     cout << endl;
80     get_Ugly_sec(1500);
81     getchar();
82     return 0;
83 }

(1)說明:總共使用了兩種辦法,第一種算法效率低,編程簡單,第二種算法效率高,編程相對復雜。

(2)方法二思路:后面的丑數肯定是已存在的丑數乘以2、3或者5,找到比現有丑數大的且是最小的丑數作為下一個丑數(如何找是關鍵)。用2分別從現有丑數中從前往后乘以丑數,找到第一個大於當前所有丑數的值以及位置,3、5同樣如此,再把他們相乘之后的結果做對比,取最小的。下次將從上一次的位置開始往下找,這樣將不會出現冗余。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM