算法学习笔记之寻找第1500个丑数

最近在阅读《算法新解》(刘新宇 著),书写得很不错,推荐程序们阅读。前言中有个例子,是寻找第1500个丑数,所谓丑数是指仅含2、3、5这三个素因子的自然数。作者在书中给出了伪代码。作为练习,记录下自己的代码。

一、暴力查找法

算法思路 :迭代每个自然数,逐一判断是否是丑数,并观察累计计数是否达到1500,如果是,则成功找到了第1500个丑数

#include 
#include 
#include 

using namespace std;

bool isUgly(int);


int main() {
    cout << "寻找第1500个丑数" << endl;
    clock_t start_time = clock();

    int count = 1;  //我们认为1是第1个丑数
    for(int i=2;i(end_time - start_time)/CLOCKS_PER_SEC << endl;
    return 0;
}

bool isUgly(int number){
    while(number > 1){
        if(number % 2 == 0) number /= 2; else break;
        if(number == 1) return true;
    }
    while(number > 1){
        if(number % 3 == 0) number /= 3; else break ;
        if(number == 1) return true;
    }
    while(number > 1){
        if(number % 5 == 0) number /= 5; else break;
        if(number == 1) return true;
    }
    return false;
}

该方法确实过于简单粗暴了。上面程序在笔记本上运行的结果是

算法学习笔记之寻找第1500个丑数_第1张图片


二、多队列方法

    使用构造法,逐一构造出递增的丑数,直到构造到第N个丑数,返回。刘新宇使用了queue作为数据结构,且提出可使用多个queue,生成新丑数并插入不同queue的思路也非常好(想不到作者是怎样构思出来的)。下面是本人的练习代码:

#include 
#include 
#include 
#include 
using namespace std;
typedef unsigned long ul;
ul findNthUglyNumber(int);

int main(){
    int N;
    cout << "输入想查找第几个丑数: N= " << endl;
    cin >> N;
    clock_t start_time = clock();
    ul result = findNthUglyNumber(N);
    clock_t end_time = clock();

    cout << "第" << N << "个丑数为: " << result << endl;
    cout << "运行总耗时(秒): " << static_cast(end_time - start_time)/CLOCKS_PER_SEC << endl;
    return 0;
}

ul findNthUglyNumber(int n){
    if(n == 1) return  1;
    queue
    q1,q2,q3; q1.push(2); q2.push(3); q3.push(5); ul minValue; while(n-- > 1){ minValue = min(min(q1.front(),q2.front()),q3.front()); if (minValue == q1.front()){ q1.pop(); q1.push(minValue*2); q2.push(minValue*3); q3.push(minValue*5); }else if(minValue == q2.front()){ q2.pop(); q2.push(minValue*3); q3.push(minValue*5); }else{ q3.pop(); q3.push(minValue*5); } } return minValue; }

运行效果如下:

算法学习笔记之寻找第1500个丑数_第2张图片

方法二的计算耗时为方法一的13万分之一。OMG,数据结构与算法真是一个有意思的东西。


你可能感兴趣的:(读书笔记)