【问题标题】:How many ways to make groups of 2 of factors of a number? (C/C++)有多少种方法可以将一个数的 2 个因数分组? (C/C++)
【发布时间】:2013-03-18 16:57:26
【问题描述】:

如果假设一个数 X = A1*A2*...*An,其中 A1, A2, .., An 是 X 的因数。 我们可以用多少种方式排列这 N 个因子,一次包含 2 个因子?

假设 X 有 5 个因子 g,h,j,k 表达式 ghjk 可以用 5 种方式计算,即 (((gh)j)k) , (g(h(jk))) , (g((hj)k)) , ((g(hj))k) 和 ( (gh)(jk))

所以输入为 ghjk

输出应该是 5

如何在 C/C++ 中做到这一点?

给定 1

【问题讨论】:

  • 你想要什么:输出可能组合的数量,还是输出所有组合?
  • 您在寻找排列吗?还是组合?
  • 我不知道它是否需要排列或组合。所以我标记了两者。
  • @Synxis : 我需要可能的组合数
  • A1、A2、A3... 是否都是不同的,还是有重复的?

标签: c++ c grouping permutation combinations


【解决方案1】:

我认为您的意思是“X 有 5 个因子,如 g、h、j、k、i”您只为上面的 X 放置了 4 个因子。 您似乎正在寻找 5 个元素中的 2 个元素的组合。

这难道不是S的简单组合选择K没有重复吗:

n! /k!(n-k)!

其中 n 是集合中元素的数量,k 是 k 组合。

对你来说,这将是一组 5 个中的 2 个的子集:(n = 5, k = 2)

5! / 2!*(5-2)! = 5! / (2!* 3!) = 10

(g,h), (g,j), (g,k), (g,i)

(h,j), (h,k), (h,i)

(j,k), (j, i)

(k,i)

因此,在一组 5 个因素中,实际上有 2 个因素的 10 种可能组合。

【讨论】:

  • 不!在 ghijk 中,假设选择 (hi) 后,您可以选择 (g(hi)) 或 ((hi)j)!!
  • “不!...”。请记住,我们正在努力帮助您。阅读其他答案后,我意识到这不是您要找的……提到加泰罗尼亚数字的答案是正确的。
【解决方案2】:

在不改变因子顺序的情况下,n 因子的乘积可以用C(n-1) 的方式括起来,其中C(k)k-th Catalan number

C(k) = 1/(k+1) * \binom(2*k, k)
     = 1/(k+1) * (2k)!/(k!)²

由于n 因子乘积的(全)括号相当于用n 叶子构建二叉树,这也是具有n 叶子的二叉树不同结构的数量。

如果允许更改因子的顺序,则必须将其乘以因子的不同顺序的数量,如果没有重复的因子,则为 n!,并且

n!/(a_1! * ... * a_k!)

如果有 k 不同的因子分别具有多重性 a_i

【讨论】:

  • 非常感谢。这真的是我问题的解决方案。谢谢。
  • 哪个公式?加泰罗尼亚数字或因子的不同顺序的数量?
  • 根据您的回复,我的理解是 N-1 的加泰罗尼亚语数可以完全解决我的问题,这是真的吗?那个加泰罗尼亚语公式对我来说有点不清楚!
  • 是的,C(n-1) 为您提供了将n 因子的乘积完全括起来的不同方法的数量(对于n >= 1)。对于n >= 2,有n-1 点可以进行最外层的乘法运算。然后你会得到重复出现P(n) = \sum_{i = 1}^{n-1} P(i)*P(n-i),因为你可以用P(i) 的方式将A_1, ... A_i 括起来,而用P(n-i) 的方式将A_(i+1), ..., A_n 括起来。加泰罗尼亚数字具有相同的重复频率(以不同的索引为模),P(1) = C(0) = 1,所以P(k) = C(k-1)。给定的公式允许比递归更有效的计算。
【解决方案3】:

您的问题是使用 Catalan numbers :Cn 是用括号括起来的关联表达式的数量。它也是具有 n+1 个叶子的可能全二叉树的数量(全二叉树 = 每个节点正好有 2 个子节点的树,或者是一个叶子)。

因此,可以use recursion to generate all combinations:

#include <iostream>
#include <string>
#include <vector>

typedef std::vector<std::string> str_vector;

// Combine u and v, and add the result to w
// u and v contains all possible combinations with respectively m and n - m letters
// So w will contain combinations with n letters
void combine(str_vector& w, const str_vector& u, const str_vector& v)
{
    for(unsigned int t = 0; t < u.size(); t++)
        for(unsigned int i = 0; i < v.size(); i++)
            w.push_back("(" + u[t] + v[i] + ")");
}

// The function resolving our problem
// It output an array containing all possible combinations
// with n letters, starting with startLetter
str_vector problem(unsigned int n, char startLetter)
{
    if(n == 1)
        // Only one combination with one letter.
        // Array with 1 string which contains only one character
        return str_vector(1,std::string(1,startLetter));
    else
    {
        str_vector w;
        // Get all combinations for n-1 letters, and add them to w
        for(unsigned int t = 1; t < n; t++)
            combine(w, problem(t, startLetter), problem(n - t, startLetter + (char)t));
        return w;
    }
}

int main()
{
    // Get all possible combinations with 4 letters
    const str_vector& r = problem(4,'a');

    // Print all solutions
    for(unsigned int t = 0; t < r.size(); t++)
        std::cout << r[t] << "\n";
}

这段代码不是最快的,也不是最优化的。不过,我认为它的可读性很强。

对于组合的数量,公式为:

这可以简化为:

       (2n)!
Cn = ---------
     n!² (n+1)

计算 Cn 为您提供具有 n+1 个标识符的组合数。但是,它并没有为您提供解决方案。

【讨论】:

  • 嗨!首先非常感谢您的回复。感谢您向我介绍加泰罗尼亚语数字。我不知道他们。根据wiki,这正是我的问题的解决方案。但很抱歉,我是 C++ 的初学者。所以我不理解这些向量。无论如何都要感谢:D
  • 还有一件事,根据wiki ------------- Cn是n + 1个因子可以完全括起来的不同方式的数量(或关联 n 个二元运算符的应用)。例如,对于 n = 3,我们有以下五个不同的四个因素的括号: !Like these -------------------------- 只是为 N-1 计算这个 !Formula 会给我解决方案吗?
  • 我编辑了我的答案。向量是 C++ 中的动态数组。有一个tutorial here,你应该阅读它。如果您在理解算法方面有任何问题,请告诉我。
猜你喜欢
  • 1970-01-01
  • 2015-11-29
  • 2010-11-27
  • 2012-05-28
  • 2014-02-07
  • 2017-05-26
  • 1970-01-01
  • 2023-03-03
  • 2011-07-18
相关资源
最近更新 更多