【问题标题】:Different ways of generating the partitions of a number in order按顺序生成数字分区的不同方法
【发布时间】:2015-06-17 21:49:27
【问题描述】:

我的算法教科书中有一个练习,要求我按顺序生成partitions of a number。我已经解决了,但是在以传统方式解决练习的同时,我想出了解决该问题的新想法。

有传统的做法:

#include <iostream>

#define MAX_PARTITIONS 100

int count = 1;

void printSolution(int* solution, int size)
{
    std::cout << count << "| ";
    count++;
    for(int i = 0; i < size; i++)
    {
        std::cout << solution[i] << " ";
    }
    std::cout << std::endl;
}

void generatePartitions(int* solution, int number, int sum, int partitions)
{
    if(sum == number)
    {
        printSolution(solution, partitions);
        return;
    }

    if(partitions > 1)
    {
        solution[partitions] = solution[partitions - 1];
    }
    else
    {
        solution[partitions] = 0;
    }

    while(solution[partitions] + sum < number)
    {
        solution[partitions]++;
        sum += solution[partitions];
        generatePartitions(solution, number, sum, partitions + 1);
        sum -= solution[partitions];
    }
}

int main(int argc, char const *argv[])
{
    int solution[MAX_PARTITIONS];

    generatePartitions(solution, 4, 0, 0);

    return 0;
}

基本上,当分区数大于1(存在前一个分区)时,我将前一个分区的值分配给当前分区,否则我将0分配给它。

有新方法:

#include <iostream>

#define MAX_PARTITIONS 100

int count = 1;

void printSolution(int* solution, int size)
{
    std::cout << count << "| ";
    count++;
    for(int i = 0; i < size; i++)
    {
        std::cout << solution[i] << " ";
    }
    std::cout << std::endl;
}

void generatePartitions(int* solution, int number, int sum, int partitions, 
    int start)
{
    if(sum == number)
    {
        printSolution(solution, partitions);
        return;
    }

    solution[partitions] = start;

    while(solution[partitions] + sum < number)
    {
        solution[partitions]++;
        sum += solution[partitions];
        generatePartitions(solution, number, sum, partitions + 1, 
            solution[partitions]);
        sum -= solution[partitions];
    }
}

int main(int argc, char const *argv[])
{
    int solution[MAX_PARTITIONS];

    generatePartitions(solution, 4, 0, 0, 0);

    return 0;
}

如您所见,函数generatePartitions 现在采用一个新参数start。最初,start 的值是0,并且在每次递归调用时start 都取当前solution[partitions] 的值。所以它应该和传统方法一样工作。

但事实并非如此,这些程序的输出完全不同。我不知道出了什么问题。我做错了什么?

【问题讨论】:

    标签: c++ algorithm number-theory


    【解决方案1】:

    递归时忘记移动solution数组的索引。

    generatePartitions(solution, number, sum, partitions + 1, 
                solution[partitions]);
    

    变成:

    generatePartitions(solution, number, sum, partitions + 1, 
                solution[partitions-1]);
    

    Coliru 链接:http://coliru.stacked-crooked.com/a/83b0418e1b1c9bc1

    另外,我建议使用某种形式的 std::pair&lt;int,int&gt; 和某种二叉树来为您执行此操作 - 对我来说,从上到下更有意义,因为我们正在尝试在技术上将一个数字划分或划分为较小的数字;该算法可能有点复杂,但是当你完成它时,它可能会显示一棵树。

    【讨论】:

    • 这不是一个遗漏。我认为当前的solution[partitions] 将是他在下一次递归调用中的前一个。看起来这个假设是错误的,但我不完全明白为什么。
    • 您从未真正从我所看到的中移动索引的指针迭代器。我没有得到算法,但是当你递归时一遍又一遍地修改数组中的相同索引似乎不太好。现在,在前一种算法中,您确实移动了数组索引/迭代器,这意味着您更改了正在查看的数字的位置。第二个没有。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多