数字拆分

qq_25318097 2015-06-08 11:15:28
输入一个数n 拆分并输出所有可能的结果
比如:
输入 n=4
输出 1 1 1 1
1 1 2
1 3
4
2 2(不要求顺序)

求大神帮忙 让小弟学习学习
...全文
170 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
fly_dragon_fly 2015-06-11
  • 打赏
  • 举报
回复
层次不深的话,递归就好
#include <iostream>
using namespace std;
const int N=10000;

int a[N];
void dfs(int d,int last,int rem){
    if(!rem){
        for(int i=0;i<d;i++) cout<<a[i]<<' ';
        cout<<endl;
        return;
    }
    for(;last<=rem;last++) {
        a[d]=last;
        dfs(d+1,last,rem-last);
    }
}

int main()
{
    int n;
    while(cin>>n && n) dfs(0,1,n);
}
赵4老师 2015-06-11
  • 打赏
  • 举报
回复
引用 8 楼 worldy 的回复:
[quote=引用 7 楼 zhao4zhong1 的回复:] [quote=引用 6 楼 worldy 的回复:] [quote=引用 4 楼 zhao4zhong1 的回复:] http://www.codeproject.com/Articles/418776/How-to-replace-recursive-functions-using-stack-and 不要自以为非递归比递归高大上!
你那连接不正好证明非递归比递归高大上吗?[/quote] 这个链接说明任何递归都能改为对应的非递归。[/quote] 据我所知,消除递归起码有下面几个好处: 1、确保栈不会溢出 2、可以使用堆,从而可能进行超大数据运算,栈一般也就1M或者几M,能进行递归计算层次是比较有限的 3、提高运行效率,递归每次都需要进行函数调用,而调用函数必然需要保护各个寄存器,保护各种状态数据,返回还的清栈,非递归就不需要这些操作 请赵老师指点[/quote] 建议你了解一下Lisp、Prolog、F#这类语言。
worldy 2015-06-11
  • 打赏
  • 举报
回复
引用 7 楼 zhao4zhong1 的回复:
[quote=引用 6 楼 worldy 的回复:] [quote=引用 4 楼 zhao4zhong1 的回复:] http://www.codeproject.com/Articles/418776/How-to-replace-recursive-functions-using-stack-and 不要自以为非递归比递归高大上!
你那连接不正好证明非递归比递归高大上吗?[/quote] 这个链接说明任何递归都能改为对应的非递归。[/quote] 据我所知,消除递归起码有下面几个好处: 1、确保栈不会溢出 2、可以使用堆,从而可能进行超大数据运算,栈一般也就1M或者几M,能进行递归计算层次是比较有限的 3、提高运行效率,递归每次都需要进行函数调用,而调用函数必然需要保护各个寄存器,保护各种状态数据,返回还的清栈,非递归就不需要这些操作 请赵老师指点
赵4老师 2015-06-11
  • 打赏
  • 举报
回复
引用 6 楼 worldy 的回复:
[quote=引用 4 楼 zhao4zhong1 的回复:] http://www.codeproject.com/Articles/418776/How-to-replace-recursive-functions-using-stack-and 不要自以为非递归比递归高大上!
你那连接不正好证明非递归比递归高大上吗?[/quote] 这个链接说明任何递归都能改为对应的非递归。
worldy 2015-06-11
  • 打赏
  • 举报
回复
引用 4 楼 zhao4zhong1 的回复:
http://www.codeproject.com/Articles/418776/How-to-replace-recursive-functions-using-stack-and 不要自以为非递归比递归高大上!
你那连接不正好证明非递归比递归高大上吗?
赵4老师 2015-06-10
  • 打赏
  • 举报
回复
mewiteor 2015-06-09
  • 打赏
  • 举报
回复
改了个非递归算法,思路和1楼差不多,并且不受递归深度限制。
#include<stdio.h>
#include<malloc.h>
void f(unsigned long long n)
{
    if(n)
    {
        unsigned long long *count=(unsigned long long*)calloc(n,sizeof(unsigned long long)),remain=n,i,j,cur=n;
        for(;;)
        {
            if(!remain)
            {
                for(i=0;i<n;++i)
                    for(j=0;j<count[i];++j)
                        printf("%llu ",i+1);
                putchar('\n');
                if(!cur)
                {
                    if(count[0]==n)break;
                    remain=count[0];
                    count[0]=0;
                    while(!count[++cur]);
                }
                remain+=cur+1;
                --count[cur];
            }
            else if(cur==1)
            {
                count[0]=remain;
                remain=0;
                cur=0;
            }
            else
            {
                count[cur-1]=remain/cur;
                remain%=cur--;
            }
        }
        free(count);
    }
}
int main()
{
    unsigned long long n;
    scanf("%llu",&n);
    f(n);
    return 0;
}
mewiteor 2015-06-09
  • 打赏
  • 举报
回复
仅供参考
#include<stdio.h>
#include<malloc.h>
void g_f(int n);
int main()
{
    int n;
    scanf("%d",&n);
    g_f(n);
    return 0;
}
/*
 * cur:当前选值,cur从大到小递归
 * remain:剩余值,也就是n减去已选值的总和
 * count:选值的计数器
 * size:计数器的大小
 */
void f(int cur,int remain,int* const count,const int size)
{
    int i,j;
    if(!remain)
    {
        for(i=0;i<size;++i)
        {
            for(j=0;j<count[i];++j)
                printf("%d ",i+1);
        }
        putchar('\n');
    }
    else if(cur==1)
    {
        count[0]=remain;
        f(0,0,count,size);
        count[0]=0;
    }
    else
    {
        // remain/cur计算出当前选值的最大数量,
        // 然后对于每一种选值数量的值,递归计算
        // 较小选值的所有情况
        for(i=remain/cur;i>=0;--i)
        {
            count[cur-1]=i;
            f(cur-1,remain-cur*i,count,size);
        }
    }
}
// 由这个函数来调用f
void g_f(int n)
{
    if(n>0)
    {
        int *count=(int*)calloc(n,sizeof(int));
        f(n,n,count,n);
        free(count);
    }
}
赵4老师 2015-06-09
  • 打赏
  • 举报
回复
#include <stdio.h>
#include <stdlib.h>
void print(int res[], int num) {
    static int L=0;
    L++;
    printf("%8d:",L);
    for (int i=0;i<num;++i) {
        printf(" %d", res[i]);
    }
    printf("\n");
}
void split(int n, int m) {// n表示总数,m表示最大因子
    static int res[100];// 保存结果
    static int num=-1;// 当前因子下标

    if (n<m || n<0 || m<1) return;
    num++;
    if (0==n) {// 递归终止条件,为0不可再分,直接输出
        print(res,num+1);
        num--;
        return;
    } else {
        if (n==m) {// 不拆,直接输出
            res[num]=m;
            print(res,num+1);
            num--;
        } else {
            // 拆分出第一个
            res[num]=m;
            n=n-m;

            if (m>n) m = n; // 最大因子不可能大于总数

            for (int i=m;i>=1;--i) {// 循环,第二个因子可以继续拆分,而且按照最大因子不同可以拆分成多个
                split(n,i);
            }
            num--;
        }
    }
}
void Split(int n) {
    if (n<=0) return;
    if (100<n) {
        printf("Up to 100\n");
        return;
    }
    for (int i=n;i>=1;--i) {
        split(n, i);
    }
}
void main(int argc,char **argv) {
         if (argc<=1) Split(5);
    else if (argc>=3) split(atoi(argv[1]),atoi(argv[2]));
    else              Split(atoi(argv[1]));
}

15,446

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 非技术区
社区管理员
  • 非技术区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧