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;
    }
  • 相关阅读:
    Angular Universal 学习笔记
    SAP Spartacus 如何获得当前渲染页面的 CMS 元数据
    Angular 服务器端渲染的学习笔记(二)
    Angular 服务器端渲染的学习笔记(一)
    第三方外部 Saas提供商如何跟使用 SAP 系统的客户进行对接接口集成
    如何从 SAP Spartacus Product Detail 页面,找到其 Angular 实现 Component 的位置
    具备自动刷新功能的 SAP ABAP ALV 报表
    C++学习目录
    c--条件编译
    c--文件读写--二进制
  • 原文地址:https://www.cnblogs.com/dplearning/p/3914807.html
Copyright © 2011-2022 走看看