A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 李跃达 中级黑马   /  2013-1-30 13:45  /  1621 人查看  /  11 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 张向辉 于 2013-2-3 11:32 编辑

输入两个整数 n 和 m,从数列1,2,3.......n 中 随意取几个数,使其和等于 m ,要求将其中所有的可能组合列出来.

11 个回复

倒序浏览
所有和都等于M是没问题的,但是要全排列,这个不太会有没有会的同学帮个忙
回复 使用道具 举报
本帖最后由 黄鸿达 于 2013-1-30 22:35 编辑

写一个这个程序,居然写了我一个下午+一个晚上,无语。不过也程序也实现了楼主的要求,而且不会有重复~~
里面注释的,下面是我的大体思想,那些各种打印语句是我调试的时候用到的,因为刚写完很多问题,通过
打印语句,慢慢推敲出错误的代码。该程序大循环嵌套小循环,小循环是个递归程序,通过return返回,并通过各种真假标记判断。
  1. import java.util.*;
  2. public class 使其和等于 {

  3. public static void main(String[] args) {

  4. 使其和等于 a=new 使其和等于();
  5. a.user();
  6. //a.get(9,8);
  7. System.out.println(a.showNum.toString());
  8. //System.out.print(a.wantNumBank.toString());
  9. //System.out.print(a.showNum.toString());
  10. }
  11. // int 给的x开始的数=1;
  12. int mark=1;
  13. // int 目标数=0;
  14. int target=0;
  15. // int 送入数组其中数=0;
  16. int wantNum=0;
  17. int length=0;
  18. String tempString;
  19. boolean flag=false;
  20. boolean bigflag=false;
  21. int bigtarget=0;
  22. //读取东西A的ALL东西出来
  23. StringBuffer wantNumBank=new StringBuffer();
  24. //按照表示应该是 组合:XX,XX,送入数组其中数,给的X开始的数
  25. StringBuffer showNum=new StringBuffer();

  26. void sum(int toMark,int toTarget){
  27. //这个事小循环模组
  28. // System.out.println("你好像现在中层的x"+toMark);
  29. mark=toMark;
  30. // System.out.println("传入了个mark角标"+mark);
  31. target=toTarget;
  32. // System.out.println("传入了个target我要求和的数"+target);
  33. for(int x=mark;x<=length;x++){
  34. mark=x;
  35. //下面if都是不满足条件跳出,并且打开能进入修改标记的大循环中的if语句
  36. if(!(target-mark>0)){
  37. // System.out.println("不符合1:将重新定位target为----"+toTarget);
  38. // System.out.println("不符合1:将重新定位mark为----"+toMark);
  39. // System.out.println("我将眺望"+x+"-1");
  40. flag=true;
  41. bigflag=true;
  42. return;
  43. }
  44. if((target-mark)==mark){
  45. // System.out.println("不符合2:将重新定位target为----"+target);
  46. // System.out.println("不符合2:将重新定位mark为----"+mark);
  47. // System.out.println("我将眺望"+x+"-1");
  48. flag=true;
  49. bigflag=true;
  50. return;
  51. }
  52. if((target-mark)<mark){
  53. // System.out.println("不符合2:将重新定位target为----"+target);
  54. // System.out.println("不符合2:将重新定位mark为----"+mark);
  55. // System.out.println("我将眺望"+x+"-1");
  56. flag=true;
  57. bigflag=true;
  58. return;
  59. }
  60. wantNum=target-mark;
  61. // System.out.println("x="+x+"wantNUm="+wantNum);
  62. for(int y=1;y<=length;y++){
  63. // System.out.println("你好现在中层的x"+toMark+"里层的y"+y);
  64. // System.out.println("y="+y+"wantNUm="+wantNum);
  65. //找到你要找的数
  66. if(y==wantNum){
  67. // System.out.println(wantNumBank.toString());
  68. // System.out.println(mark);
  69. //把可能的组合加进去
  70. showNum.append("组合:"+wantNumBank+mark+"+"+wantNum+"="+bigtarget+"\n");
  71. wantNumBank.append(mark+"+");
  72. // System.out.println(tempString.toString());
  73. // System.out.println(showNum.toString());
  74. toMark=mark+1;
  75. toTarget=wantNum;
  76. //递归
  77. sum(toMark,toTarget);
  78. }
  79. //有可能递归从这里跳出,这里就可以再次判断跳出~
  80. if(flag){
  81. return;
  82. }
  83. }
  84. }

  85. }
  86. void get(int target,int length){
  87. //大循环
  88. for(int x=1;x<length;x++){
  89. //修改判断标记全假,不然内循环某些地方还没弄完就跳出,
  90. //这个语句是内层跳出来改写bigflag为true才能进入,
  91. if(bigflag){
  92. flag=false;
  93. bigflag=false;
  94. }
  95. // System.out.println("我是最外层,现在第"+x);
  96. wantNum=0;
  97. //每次出来都要清空
  98. wantNumBank.delete(0, wantNumBank.length());
  99. // System.out.println(wantNumBank.toString());
  100. sum(x,target);

  101. }

  102. //System.out.println(mark+"+"+target+"+"+length);
  103. }
  104. void user(){
  105. System.out.print("输入你所给与数列最大数");
  106. this.length=new Scanner(System.in).nextInt();
  107. System.out.print("输入你的和");
  108. this.target=new Scanner(System.in).nextInt();
  109. bigtarget=target;
  110. get(target,length);
  111. }
  112. }

  113. //
  114. // void reout(int target,int mark){
  115. // if(!(target-mark>0)){
  116. // System.out.println("不符合1:将重新定位target为----"+toTarget);
  117. // System.out.println("不符合1:将重新定位mark为----"+toMark);
  118. //
  119. // return;
  120. // }
  121. // if((target-mark)==mark){
  122. // System.out.println("不符合2:将重新定位target为----"+target);
  123. // System.out.println("不符合2:将重新定位mark为----"+mark);
  124. //
  125. // return;
  126. // }
  127. // }
  128. //}

  129. // void sum(){
  130. // int 给的x开始的数=1;
  131. // int 目标数=0;
  132. // int 送入数组其中数=0;
  133. // final int 最大长度=目标数;
  134. // for(int x=给的x开始的数;x<最大长度;x++){
  135. // 送入数组其中数=目标数-给的x开始的数;
  136. // 17=18-1
  137. //
  138. // //读取东西A的ALL东西出来
  139. // //读取出来的格式为 XX,XX,
  140. // //再用个东西wantNumBank存给的x开始的数
  141. // //存入格式为 XX,
  142. // //把 ALL东西+送入数组其中数+给的X开始的数 都送进 一个东西
  143. // //按照表示应该是 组合:XX,XX,送入数组其中数,给的X开始的数
  144. //
  145. // //(给的x开始的数+1)传给下面调用的函数
  146. // //目标数=送入数组其中数
  147. //
  148. // void sum(int 给的x开始的数,int 目标数){
  149. //
  150. // }
  151. // }
  152. // }
  153. //}
  154. //
  155. //
  156. //17=18-1
  157. //
  158. //1 17 送数组
  159. //1临时数组
  160. //
  161. //15=17-2
  162. //1 2 15 songshuzu
  163. //
  164. //1 2
复制代码

评分

参与人数 1技术分 +1 收起 理由
Rancho_Gump + 1

查看全部评分

回复 使用道具 举报
  1. import java.util.Scanner;
  2. public class x
  3. {
  4. static int Max=1000;
  5. static int n,m;//n个数中选出若干数,总和为m
  6. static int []a=new int[Max];//存放n个数
  7. static int []flag=new int[Max];//标记n个数是否被选,1选,0不选
  8. static void f(int sum,int idx)
  9. {
  10. if(sum==0)
  11. {
  12. for(int i=0;i<idx;i++)
  13. if(flag[i]==1)
  14. System.out.print(a[i]+" ");
  15. System.out.println();
  16. return;
  17. }
  18. if(sum<0||idx==n)
  19. return;
  20. flag[idx]=1;//选第idx号
  21. f(sum-a[idx],idx+1);//递归
  22. flag[idx]=0;//不选第idx号
  23. f(sum,idx+1);//递归
  24. }
  25. public static void main(String[] args)
  26. {
  27. Scanner sc=new Scanner(System.in);
  28. n=sc.nextInt();
  29. m=sc.nextInt();
  30. for(int i=0;i<n;i++)
  31. a[i]=i+1;
  32. f(m,0);//递归

  33. }
  34. }
复制代码
当n=5,m=6 时,结果如下:

评分

参与人数 1黑马币 +9 收起 理由
Rancho_Gump + 9 赞一个!

查看全部评分

回复 使用道具 举报
你题目中说想要算法,所以我把m,n的值直接赋给了,如果需要的话可以改成从键盘录入。

public class HelloWorld
{
        public static void main(String args[])
        {
                int[] shuzu = {1,2,3,4,5,6,7,8,9};//n=9,这里的n如果是需要手动输入的话,那么久生成新的数组,长度是n,然后依次赋值,你只是要算法,所以我把这里的n直接赋值了
                int jieguo = 7;//这是你题目中的m的值
                qiuHe(shuzu,jieguo);
        }
       
        public static void  qiuHe(int[] shuzu,int jieguo)
        {
                int len = shuzu.length;
                for(int m=0;m<len-1;m++)
                {
                        for(int n=m+1;n<len;n++)
                        {
                                if((shuzu[m]+shuzu[n])==jieguo)
                                {
                                        System.out.println("组合:"+shuzu[m]+"+"+shuzu[n]);
                                }
                                else if((shuzu[m]+shuzu[n])<jieguo)
                                {
                                        int he = shuzu[m]+shuzu[n];
                                        int[] arr = {shuzu[m],shuzu[n]};
                                        qiuHe2(shuzu,n,he,jieguo,arr);
                                }
                        }
                }
                for(int x=0;x<len;x++)
                {
                        if(shuzu[x]==jieguo)
                        {
                                System.out.println("组合:"+jieguo);
                        }
                }
        }
        public static void qiuHe2(int[] shuzu,int kaishiweizhi,int he,int jieguo,int[] xinshuzu)//这个函数用来求出组合
        {
                for(int position=kaishiweizhi+1;position<shuzu.length;position++)
                {
                        if((he+shuzu[position])==jieguo)
                        {
                                System.out.print("组合:");
                                for(int x=0;x<xinshuzu.length;x++)
                                {
                                        System.out.print(xinshuzu[x]+"+");
                                }
                                System.out.println(shuzu[position]);
                        }
                        else if((he+shuzu[position])<jieguo)
                        {
                                int temp = xinshuzu.length+1;
                                int[] newarry = new int[temp];
                                for(int lennewarry=0;lennewarry<temp-1;lennewarry++)
                                {
                                        newarry[lennewarry] = xinshuzu[lennewarry];
                                }
                                newarry[temp-1] = shuzu[position];
                                int he1 = he+shuzu[position];
                                qiuHe2(shuzu,position,he1,jieguo,newarry);
                        }
                }
        }
}

评分

参与人数 1黑马币 +9 收起 理由
Rancho_Gump + 9

查看全部评分

回复 使用道具 举报
这里的牛人很多啊
回复 使用道具 举报
看到你们的回答问题,我就感觉我真是个不够认真的人
回复 使用道具 举报
我向你们致敬,和向你们学习
回复 使用道具 举报
谢谢你们的辛苦付出,真心希望你们能不断牛
回复 使用道具 举报
祝福你们能够更加幸福,快乐
回复 使用道具 举报
你们的付出,不是白付出的,我们这些新来的会从你们的经验中收获很多
回复 使用道具 举报
你们的经验,就是可以让我们,学习少走弯路
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马