尝试编写一个递归函数来计算总和达到该数字 C++ 的序列数。

发布于 2024-10-06 17:24:15 字数 1143 浏览 2 评论 0原文

好的,这就是我想做的。用户输入一个数字。我正在尝试编写一个递归函数来计算总和达到该数字(用户输入)的序列数。

例如:

那么总和为6的序列数为11(包括6本身)。

6
5+1
4+1+1
3+1+1+1
2+1+1+1+1
1+1+1+1+1+1
2+2+1+1
3+2+1
4+2
2+2+2
3+3

我还尝试不重复序列,例如 2+2+1+1 和 1+1+2+2。

我没有包含代码的原因是我无法找出一种递归方法来完成这项工作,所以我正在寻求一些指导。提前致谢!

添加:

好的,这就是我的思考过程。 6可以拆分为...

6
5+1
4+2
3+3

但还没有结束,如果你取5+1并认为+1部分已完成;您可以使用相同的技巧继续。

4+1+1
3+2+1

但然后他们开始重复......我没有比我的计划中的第二步更进一步。

好吧,就代码而言,这是我自己想出的。正在寻找解决此问题的建议。

int sum(int number, int min, int counter)
{
    int temp=0, n;
    n=number+temp;
    if (number>=(n/2)& number!=min)
    {
        while (number>=(n/2))
        {
            cout << number << "+"<< temp <<"\n";
            number --;
            temp ++;
            counter ++;
        }
    }
    sum(temp, 1,counter);
    return counter;
}

int main()
{
    int number;

    cout << "Please enter the number: ";
    cin >> number ;
    cout << "\n";

    sum(number, 1, 0);

    return 0;
}

我确实意识到这一切都很混乱。

Okay, so here is what I'm trying to do. The user inputs a number. I'm trying to write a recursive function that counts the number of sequences that sum up to that number (user input).

For example:

Then the number of sequences that sum up to 6 is 11 (including 6 itself).

6
5+1
4+1+1
3+1+1+1
2+1+1+1+1
1+1+1+1+1+1
2+2+1+1
3+2+1
4+2
2+2+2
3+3

I'm also trying not to have sequences that repeat, for example 2+2+1+1 and 1+1+2+2.

The reason i have no code included is i cannot figure out a recursive way to make this work so i'm seeking some guidance. Thanks in advance!

ADDITION:

Okay so here is what my thought process is.
6 can be split as...

6
5+1
4+2
3+3

but it is still not over,if you take 5+1 and consider the +1 part to be completed; you use the same trick to proceed.

4+1+1
3+2+1

but then they start to repeat..... and i don't get further than this second step in my plan.

Okay so code wise this is what I've come up with on my own. Looking for suggestions to fix this.

int sum(int number, int min, int counter)
{
    int temp=0, n;
    n=number+temp;
    if (number>=(n/2)& number!=min)
    {
        while (number>=(n/2))
        {
            cout << number << "+"<< temp <<"\n";
            number --;
            temp ++;
            counter ++;
        }
    }
    sum(temp, 1,counter);
    return counter;
}

int main()
{
    int number;

    cout << "Please enter the number: ";
    cin >> number ;
    cout << "\n";

    sum(number, 1, 0);

    return 0;
}

I do realize this is all sorts of messed up.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

贪了杯 2024-10-13 17:24:15

提示:尝试找到一个函数,给出总和为 n 且项不大于 k 的序列数。

编辑:
如果这听起来很刺耳,请原谅我,但是......您更新的代码都是错误的。很难看出你的意图。我可以猜测,但这毫无意义。

这就是我的想法:序列应该是非递增的顺序,例如“2 2 1 1 1 1”。那么有多少个这样的序列加起来是 6 呢?好吧,找到从 1 开始的此类序列的数量,然后是从 2 开始的序列的数量,依此类推,直到 6,然后将它们相加。以 2 开头、加起来为 6 的序列有多少个? (这就是递归发挥作用的地方。)在每个这样的序列中,第一项是 2,其余项加起来为 4,没有一项超过 2,因此我们必须找到的数量序列加起来为 4,且没有一项大于 2。所以先写签名,然后是迭代循环,然后是递归调用,就完成了。

编辑:
好吧,除了循环之外,这里是所有内容:

int partition(int n, int max)
{
  if(n==0)
    return(0);
  int ret = 0;
  if(n<=max)
    ret=1;
  for(...)
  {
    ...
  }
  return(ret);
}

你能填空吗?

Hint: try to find a function that gives the number of sequences with sum n and terms not larger than k.

EDIT:
Forgive me if this sounds harsh, but... your updated code is all wrong. It's hard to see what you intended. I can guess, but that would be pointless.

Here's what I had in mind: a sequence should be in nonincreasing order, like "2 2 1 1 1 1". So how many such sequences add up to 6? Well, find the number of such sequences starting with 1, then the number of sequences starting with 2, and so on up to 6, and add them up. And how many sequences start with 2 and add up to six? (This is where the recursion comes in.) In each such sequence, the first term is 2 and the rest add up to 4 with no term exceeding 2, so we must find the number of sequences adding up to 4 with no term greater than 2. So write the signature first, then the iteration loop, then the recursive call and you're done.

EDIT:
All right, here's everything but the loop:

int partition(int n, int max)
{
  if(n==0)
    return(0);
  int ret = 0;
  if(n<=max)
    ret=1;
  for(...)
  {
    ...
  }
  return(ret);
}

Can you fill in the blanks?

抽个烟儿 2024-10-13 17:24:15

我认为它接近概率论
给出总结 6 的集合 {1,2,3,4,5,6} 的组合数量

i think it is close to the probability theory
amount of combinations of set {1,2,3,4,5,6} giving summary 6

泪是无色的血 2024-10-13 17:24:15

这些称为整数分区,有一种简单的方法可以使用中间函数计算任意数字的分区数。看一下这里:整数分区

These are called Integer Partitions, and there is a simple way to calculate the number of partitions of any number using an intermediate function. Take a look here: Integer Partition.

不…忘初心 2024-10-13 17:24:15

令 f(n) 为我们想要的函数,它生成与 n 相加的整数序列,无需排列

定义

f(n) = g(n,n)

g(n,p) = { i \in 1..min(n, p): [ig(ni,i)] }

Let f(n) be the function we want, that generates sequences of integers that add to n, without permutations

Define

f(n) = g(n,n)

g(n,p) = { i \in 1..min(n, p): [i g(n-i,i)] }

过去的过去 2024-10-13 17:24:15

这个问题很好地介绍了该算法。

The algorithm is well covered in this question.

蘸点软妹酱 2024-10-13 17:24:15

定义 P(n) 为划分 n 的方式数,限制 n 为整数,n >= 1。

定义 p(n, k) 为使用不大于 k 的数字划分 n 的方式数,限制k为整数,k≥1,k≤n。

由此得出 P(n) = sum (i: 1..n) p(n, i)。

要找到 p(n, k),首先请注意,我们通过简单地保持分区排序来巧妙地避免重复计算:首先取最大的块。因此,第一个块可以具有从 1 到 k 的任意大小,然后其余块必须占总数 n 的其余部分,并且不大于第一个块。

因此 p(n, k) = sum (i: 1..k) p(n - i, i)。

作为基本情况,p(1, 1) = 1。


示例实现,保证完全有效,甚至无法编译(但它应该给您基本的想法) -剧透!

// A utility function to represent the result of appending to a vector,
// as a new vector (without affecting the previous one).
template <typename T>
vector<T> operator<<(vector<T> copy, T to_append) {
    // We passed by value to get a copy implicitly.
    copy.push_back(to_append);
    return copy;
}

// A utility function to append one vector to another.
template <typename T>
vector<T>& operator+=(vector<T>& original, const vector<T>& to_append) {
    // 'copy' is in namespace std:: and defined in <algorithm>.
    // 'back_inserter' is in namespace std:: and defined in <iterator>.
    copy(to_append.begin(), to_append.end(), back_inserter(original));
    return original;
}

vector<vector<int> > partitions(int remaining, int limit, vector<int> prefix) {
    // Finds the partitions of some larger number which start with the
    // numbers in 'prefix', such that the rest of the "chunks" sum to
    // 'remaining' and are all no larger than 'limit'.

    // 'max' is in namespace std:: and defined in <algorithm>. We restrict
    // the 'limit' to be no more than 'remaining'.
    limit = max(remaining, limit);

    vector<vector<int> > result;

    // Base case. 
    if (remaining == 1) {
        return result << (prefix << 1); // note the parentheses are required!
    }

    for (int i = limit; i > 0; --i) {
        result += partitions(remaining - i, i, prefix << i);
    }

    return result;
}

Define P(n) as the number of ways to partition n, restricting n to be an integer, n >= 1.

Define p(n, k) as the number of ways to partition n using numbers no larger than k, restricting k to be an integer, k >= 1, k <= n.

It follows that P(n) = sum (i: 1..n) p(n, i).

To find p(n, k), first note that we neatly avoid double-counting by simply keeping the partition sorted: take the largest chunk first. So the first chunk may have any size from 1 up to k, and then the rest of the chunks must account for the rest of the total n, and be no larger than the first chunk.

Thus p(n, k) = sum (i: 1..k) p(n - i, i).

As a base case, p(1, 1) = 1.


A sample implementation, very much not guaranteed to be at all efficient, or even to compile (but it should give you the basic idea) - spoilers!

// A utility function to represent the result of appending to a vector,
// as a new vector (without affecting the previous one).
template <typename T>
vector<T> operator<<(vector<T> copy, T to_append) {
    // We passed by value to get a copy implicitly.
    copy.push_back(to_append);
    return copy;
}

// A utility function to append one vector to another.
template <typename T>
vector<T>& operator+=(vector<T>& original, const vector<T>& to_append) {
    // 'copy' is in namespace std:: and defined in <algorithm>.
    // 'back_inserter' is in namespace std:: and defined in <iterator>.
    copy(to_append.begin(), to_append.end(), back_inserter(original));
    return original;
}

vector<vector<int> > partitions(int remaining, int limit, vector<int> prefix) {
    // Finds the partitions of some larger number which start with the
    // numbers in 'prefix', such that the rest of the "chunks" sum to
    // 'remaining' and are all no larger than 'limit'.

    // 'max' is in namespace std:: and defined in <algorithm>. We restrict
    // the 'limit' to be no more than 'remaining'.
    limit = max(remaining, limit);

    vector<vector<int> > result;

    // Base case. 
    if (remaining == 1) {
        return result << (prefix << 1); // note the parentheses are required!
    }

    for (int i = limit; i > 0; --i) {
        result += partitions(remaining - i, i, prefix << i);
    }

    return result;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文