zoukankan      html  css  js  c++  java
  • 【编程题目】寻找丑数

    题目:我们把只包含因子 2、3 和 5 的数称作丑数(Ugly Number)。例如 6、8 都是丑数,
    但 14 不是,因为它包含因子 7。习惯上我们把 1 当做是第一个丑数。
    求按从小到大的顺序的第 1500 个丑数。

    思路:

    1.  数字从1递增,判断是不是丑数

    2. 用2、3、5分别乘以已有的丑数,用大于当前的丑数的结果中最小的作为当前的丑数 快!

    /* 
    64.  寻找丑数(运算)。
    题目:我们把只包含因子 2、3 和 5 的数称作丑数(Ugly Number)。例如 6、8 都是丑数,
    但 14 不是,因为它包含因子 7。习惯上我们把 1 当做是第一个丑数。
    求按从小到大的顺序的第 1500 个丑数。
    */
    #include <stdio.h>
    #include <stdlib.h>
    
    int uglynum(int n) //输入要找第几个丑数
    {
        long int i;
        int num = 1;
        for (i = 2; num < n; i++)
        {
            int flag = 0;
            int d = i;
            while (d != 1 && 0 == flag)
            {
                if (d % 2 == 0)
                {
                    d = d/2;
                }
                else if (d % 3 == 0)
                {
                    d = d/3;
                }
                else if (d % 5 == 0)
                {
                    d = d/5;
                }
                else
                {
                    flag = 1;
                }
            }
            if (0 == flag)
            {
                num++;
            }
        }
        return (i - 1);
    }
    
    int uglynum2(int n) //输入要找第几个丑数
    {
        if (n == 1)
        {
            return 1;
        }
        int* data = (int *)malloc(n * sizeof(n));
        data[0] = 1;
        int b[3] = {2, 3, 5};
        for (int i = 1; i < n; i++)
        {
            int mintmp = 2 * data[i - 1]; //存储比上一个数字大的数中最小的那个 初始化这个数
            for(int m = 0; m < 3; m++)
            {    
                for (int j = 0; j < i; j++)
                {
                    if (data[j] * b[m] > data[i - 1])
                    {
                        if (data[j] * b[m] < mintmp)
                        {
                            mintmp = data[j] * b[m];
                        }
                        break;
                    }
                }
            }
            data[i] = mintmp;
        }
    
        int ans = data[n - 1];
        free(data);
        return ans;
    }
    int main()
    {
        //long int d = uglynum(1500);
        //d = uglynum2(1500);
        for (int i = 2; i <= 1500; i++)
        {
            int d = uglynum2(i);
            printf("第%d个丑数为:%d
    ", i, d);
        }
        return 0;
    }

    网上看答案,发现自己写的不好,虽然思路一样,但是我写的看起来很乱。而且在方法二中我对 2 3 5都是从第一个数字开始乘,实际上可以用三个指针记录上一次乘到哪里了,下一次从记录位开始找就好了。

    还有,有些子功能可以写成子函数,可以让整个代码看起来更清晰。

    http://www.cnblogs.com/mingzi/archive/2009/08/04/1538491.html 里的代码就看起来很舒服。

    方法一:

    bool IsUgly(int number)
    {
        while(number % 2 == 0)
            number /= 2;
        while(number % 3 == 0)
            number /= 3;
        while(number % 5 == 0)
            number /= 5;
    
        return (number == 1) ? true : false;
    }
    
    int GetUglyNumber_Solution1(int index)
    {
        if(index <= 0)
            return 0;
    
        int number = 0;
        int uglyFound = 0;
        while(uglyFound < index)
        {
            ++number;
    
            if(IsUgly(number))
            {
               ++uglyFound;
            }
        }
        return number;
    }

    方法二:

    int GetUglyNumber_Solution2(int index)
    {
        if(index <= 0)
            return 0;
    
        int *pUglyNumbers = new int[index];
        pUglyNumbers[0] = 1;
        int nextUglyIndex = 1;
    
        int *pMultiply2 = pUglyNumbers;
        int *pMultiply3 = pUglyNumbers;
        int *pMultiply5 = pUglyNumbers;
    
        while(nextUglyIndex < index)
        {
            int min = Min(*pMultiply2 * 2, *pMultiply3 * 3, *pMultiply5 * 5);
            pUglyNumbers[nextUglyIndex] = min;
            while(*pMultiply2 * 2 <= pUglyNumbers[nextUglyIndex])
                ++pMultiply2;
            while(*pMultiply3 * 3 <= pUglyNumbers[nextUglyIndex])
                ++pMultiply3;
            while(*pMultiply5 * 5 <= pUglyNumbers[nextUglyIndex])
                ++pMultiply5;
            ++nextUglyIndex;
        }
    
        int ugly = pUglyNumbers[nextUglyIndex - 1];
        delete[] pUglyNumbers;
        return ugly;
    }
    
    int Min(int number1, int number2, int number3)
    {
        int min = (number1 < number2) ? number1 : number2;
        min = (min < number3) ? min : number3;
    
        return min;
    }
  • 相关阅读:
    mysql sql语句大全
    windows composer 安装,使用新手入门
    PHP 变量类型的强制转换 & 创建空对象
    window bat 运行 cmd 命令
    window apidoc的安装和使用
    linux apidoc的安装和使用
    RabbitMQ的安装与基本使用
    控制流之continue
    控制流之break
    控制流之while
  • 原文地址:https://www.cnblogs.com/dplearning/p/3914807.html
Copyright © 2011-2022 走看看