我有n个空格,在每个空格中,我可以放置一个0到m的数字。编写程序以输出所有可能的结果。需要帮忙 :)

时间:2012-12-07 19:31:19

标签: c++ permutation

这个想法是,给定n个空格,空字段或者你有什么,我可以放在从0到m的数字中。所以,如果我有两个空格而且只有01,那么结果将是: (0 1) (1 0) (0 0) (1 1)

如果我有两个空格和三个数字(0 1 2),结果将是

(0 1) (1 1) (0 2) (2 0) (2 2) (2 1)

等等,直到我得到所有9(3 ^ 2)个可能的结果。

所以我试着编写一个程序,如果我有n个空格,可以给我所有可能的结果,并且可以在任何一个空格中放置0到m之间的任何数字。

最初我认为是使用for循环,但是当我意识到我必须为n中的每个数字创建一个时,它很快被击落,而且对于n更大的情况它不会起作用。

我有一个想法是使用一个随机数生成器并生成一个从0到m的数字,但这并不能保证我实际上会得到所有可能的结果。

我被困住了:(

想法?

非常感谢任何帮助:)

4 个答案:

答案 0 :(得分:4)

每当一个任务需要找到“全部”的东西时,你应该首先尝试在这三个步骤中完成它:我可以把它们放在某种顺序吗?我可以找到下一个吗?我可以找到第一个吗?

所以如果我要求你给我1到10的所有数字,你会怎么做?嗯,这很简单,因为:你知道一种简单的方法可以将它们整理好。鉴于其中任何一个,您可以给我下一个。你知道哪个是第一个。所以你从第一个开始,然后继续下一个直到你完成。

这种方法同样适用于此问题。您需要三种算法:

  1. 对输出进行排序的算法,使每个输出大于或小于每个其他可能的输出。 (您不需要对此进行编码,只需了解它。)

  2. 将任何输出转换为下一个输出的算法,如果给出最后一个输出则会失败。 (你需要对此进行编码。)

  3. 生成第一个输出的算法,比其他每个可能的输出少一个(根据第一个算法)。 (你需要对此进行编码。)

  4. 然后很简单:

    1. 生成第一个输出(使用算法3)。输出它。

    2. 使用增量算法(算法2)生成下一个输出。如果没有下一个输出,请停止。否则,输出它。

    3. 重复步骤2.

    4. 更新:以下是一些可能的算法:

      算法1:

      1. 比较两个输出的第一个数字。如果一个大于另一个,则输出更大。如果它们相同,请继续

      2. 重复步骤,移动到连续的数字,直到找到不匹配为止。

      3. 算法2:

        1. 从最右边的数字开始。

        2. 如果这个数字不是最大数字,可以递增并停止。

        3. 我们是最左边的数字吗?如果是这样,请停止错误。

        4. 将数字指针向左移动一位数。

        5. 算法3:

          1. 将所有数字设置为零。

答案 1 :(得分:4)

基本上你需要的是一个起点,终点,以及从每个状态转换到下一个状态的方法。例如,一个递归函数,它能够将一个数字添加到您需要的最小速度值,并且当它大于最大速度值时,递增下一个更大的数字并将当前数字设置回零。

以此为例:

#include <iostream>
#include <vector>

using namespace std;

// This is just a function to print out a vector.
template<typename T>
inline ostream &operator<< (ostream &os, const vector<T> &v) {
    bool first = true;
    os << "(";
    for (int i = 0; i < v.size (); i++) {
        if (first) first = false;
        else os << " ";
        os << v[i];
    }
    return os << ")";
}

bool addOne (vector<int> &nums, int pos, int maxNum) {
    // If our position has moved off of bounds, so we're done
    if (pos < 0)
        return false;

    // If we have reached the maximum number in one column, we will
    // set it back to the base number and increment the next smallest number.
    if (nums[pos] == maxNum) {
        nums[pos] = 0;
        return addOne (nums, pos-1, maxNum);
    }

    // Otherwise we simply increment this numbers.
    else {
        nums[pos]++;
        return true;
    }
}

int main () {
    vector<int> nums;
    int spaces = 3;
    int numbers = 3;

    // populate all spaces with 0
    nums.resize (spaces, 0);

    // Continue looping until the recursive addOne() function returns false (which means we
    // have reached the end up all of the numbers)
    do {
        cout << nums << endl;    
    } while (addOne (nums, nums.size()-1, numbers));

    return 0;
}

答案 2 :(得分:2)

  

“我正在尝试编写一个程序,如果我有n个空格,可以给我所有可能的结果,并且可以在任何一个空格中放置0到m之间的任何数字。”

假设包含“to”,则设R = m + 1.

然后,这是同构的,输出基本R数字系统中出现的0到R n -1范围内的每个数字。

这意味着要计算一个外部循环(为此可以使用C ++ ++增量运算符),以及一个内部循环来提取和显示数字。对于内部循环,您可以使用C ++'/除法运算符,并且根据您最清楚的结果,还可以使用%余数运算符。除非您将自己限制在C ++标准库直接支持的三个R选项中,否则请使用标准格式化程序。

请注意,R n 可以快速增长。

因此,请勿将输出重定向到您的打印机,并准备等待程序完成。

答案 3 :(得分:1)

我认为你需要查找递归。 http://www.danzig.us/cpp/recursion.html

基本上它是一个自我调用的函数。这允许您执行N个嵌套for循环。