用于生成并输出前 n 个丑数 cpp

丑数(Ugly Numbers)是指其质因数只包含 2、3 和 5 的正整数。换句话说,丑数是可以表示为 2a×3b×5c2^a \times 3^b \times 5^c2a×3b×5c 形式的数,其中 aaa、bbb 和 ccc 是非负整数。第一个丑数是 1(通常认为 1 是丑数)

下面的是python实现

def generate_ugly_numbers(n):
    if n <= 0:
        return []

    ugly_numbers = [1]
    i2 = i3 = i5 = 0

    for _ in range(1, n):
        next_ugly_2 = ugly_numbers[i2] * 2
        next_ugly_3 = ugly_numbers[i3] * 3
        next_ugly_5 = ugly_numbers[i5] * 5

        next_ugly = min(next_ugly_2, next_ugly_3, next_ugly_5)
        ugly_numbers.append(next_ugly)

        if next_ugly == next_ugly_2:
            i2 += 1
        if next_ugly == next_ugly_3:
            i3 += 1
        if next_ugly == next_ugly_5:
            i5 += 1

    return ugly_numbers

# 示例:获取前10个丑数
ugly_numbers = generate_ugly_numbers(10)
print(ugly_numbers)

下面的是用cpp实现

#include <iostream>
#include <vector>
#include <algorithm> // for std::min

std::vector<int> generateUglyNumbers(int n) {
    if (n <= 0) {
        return {};
    }

    std::vector<int> uglyNumbers(n);
    uglyNumbers[0] = 1; // 第一个丑数是1

    int i2 = 0, i3 = 0, i5 = 0; // 分别指向将乘以2、3、5的下一个丑数

    for (int i = 1; i < n; ++i) {
        int nextUgly2 = uglyNumbers[i2] * 2;
        int nextUgly3 = uglyNumbers[i3] * 3;
        int nextUgly5 = uglyNumbers[i5] * 5;

        int nextUgly = std::min({nextUgly2, nextUgly3, nextUgly5});
        uglyNumbers[i] = nextUgly;

        if (nextUgly == nextUgly2) {
            ++i2;
        }
        if (nextUgly == nextUgly3) {
            ++i3;
        }
        if (nextUgly == nextUgly5) {
            ++i5;
        }
    }

    return uglyNumbers;
}

int main() {
    int n = 10; // 可以更改n的值来获取前n个丑数
    std::vector<int> uglyNumbers = generateUglyNumbers(n);

    // 输出前n个丑数
    for (int num : uglyNumbers) {
        std::cout << num << " ";
    }
    std::cout << std::endl;

    return 0;
}

 

具体变化过程

假设我们要生成前 n = 10 个丑数,初始时 uglyNumbers 中已经存储了第一个丑数1(uglyNumbers[0] = 1),指针 i2 = 0, i3 = 0, i5 = 0

  1. 第2个丑数

    • 计算 nextUgly2 = uglyNumbers[i2] * 2 = 1 * 2 = 2
    • 计算 nextUgly3 = uglyNumbers[i3] * 3 = 1 * 3 = 3
    • 计算 nextUgly5 = uglyNumbers[i5] * 5 = 1 * 5 = 5
    • 最小值是 2,因此确定第二个丑数为 2。将 i2 增加1,i2 = 1
  2. 第3个丑数

    • 计算 nextUgly2 = uglyNumbers[i2] * 2 = 2 * 2 = 4
    • 计算 nextUgly3 = uglyNumbers[i3] * 3 = 1 * 3 = 3
    • 计算 nextUgly5 = uglyNumbers[i5] * 5 = 1 * 5 = 5
    • 最小值是 3,因此确定第三个丑数为 3。将 i3 增加1,i3 = 1
  3. 第4个丑数

    • 计算 nextUgly2 = uglyNumbers[i2] * 2 = 2 * 2 = 4
    • 计算 nextUgly3 = uglyNumbers[i3] * 3 = 2 * 3 = 6
    • 计算 nextUgly5 = uglyNumbers[i5] * 5 = 1 * 5 = 5
    • 最小值是 4,因此确定第四个丑数为 4。将 i2 增加1,i2 = 2
  4. 第5个丑数

    • 计算 nextUgly2 = uglyNumbers[i2] * 2 = 3 * 2 = 6
    • 计算 nextUgly3 = uglyNumbers[i3] * 3 = 2 * 3 = 6
    • 计算 nextUgly5 = uglyNumbers[i5] * 5 = 1 * 5 = 5
    • 最小值是 5,因此确定第五个丑数为 5。将 i5 增加1,i5 = 1
  5. 第6个丑数

    • 计算 nextUgly2 = uglyNumbers[i2] * 2 = 3 * 2 = 6
    • 计算 nextUgly3 = uglyNumbers[i3] * 3 = 2 * 3 = 6
    • 计算 nextUgly5 = uglyNumbers[i5] * 5 = 2 * 5 = 10
    • 最小值是 6,因此确定第六个丑数为 6。同时更新 i2i3i2 = 3, i3 = 2
  6. 第7个丑数

    • 计算 nextUgly2 = uglyNumbers[i2] * 2 = 4 * 2 = 8
    • 计算 nextUgly3 = uglyNumbers[i3] * 3 = 3 * 3 = 9
    • 计算 nextUgly5 = uglyNumbers[i5] * 5 = 2 * 5 = 10
    • 最小值是 8,因此确定第七个丑数为 8。将 i2 增加1,i2 = 4
  7. 第8个丑数

    • 计算 nextUgly2 = uglyNumbers[i2] * 2 = 5 * 2 = 10
    • 计算 nextUgly3 = uglyNumbers[i3] * 3 = 3 * 3 = 9
    • 计算 nextUgly5 = uglyNumbers[i5] * 5 = 2 * 5 = 10
    • 最小值是 9,因此确定第八个丑数为 9。将 i3 增加1,i3 = 3
  8. 第9个丑数

    • 计算 nextUgly2 = uglyNumbers[i2] * 2 = 5 * 2 = 10
    • 计算 nextUgly3 = uglyNumbers[i3] * 3 = 4 * 3 = 12
    • 计算 nextUgly5 = uglyNumbers[i5] * 5 = 2 * 5 = 10
    • 最小值是 10,因此确定第九个丑数为 10。同时更新 i2i5i2 = 5, i5 = 2
  9. 第10个丑数

    • 计算 nextUgly2 = uglyNumbers[i2] * 2 = 6 * 2 = 12
    • 计算 nextUgly3 = uglyNumbers[i3] * 3 = 4 * 3 = 12
    • 计算 nextUgly5 = uglyNumbers[i5] * 5 = 3 * 5 = 15
    • 最小值是 12,因此确定第十个丑数为 12。同时更新 i2i3i2 = 6, i3 = 4

通过这种方式,指针 i2i3i5 在数组 uglyNumbers 中不断向前推进,确保每次选出最小的可能丑数,避免重复计算,并生成有序的丑数序列。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值