黑马程序员技术交流社区
标题:
一道算法题,求解
[打印本页]
作者:
李跃达
时间:
2013-1-30 13:45
标题:
一道算法题,求解
本帖最后由 张向辉 于 2013-2-3 11:32 编辑
输入两个整数 n 和 m,从数列1,2,3.......n 中 随意取几个数,使其和等于 m ,要求将其中所有的可能组合列出来.
作者:
李跃达
时间:
2013-1-30 14:36
所有和都等于M是没问题的,但是要全排列,这个不太会有没有会的同学帮个忙
作者:
黄鸿达
时间:
2013-1-30 22:14
本帖最后由 黄鸿达 于 2013-1-30 22:35 编辑
写一个这个程序,居然写了我一个下午+一个晚上,无语。不过也程序也实现了楼主的要求,而且不会有重复~~
里面注释的,下面是我的大体思想,那些各种打印语句是我调试的时候用到的,因为刚写完很多问题,通过
打印语句,慢慢推敲出错误的代码。该程序大循环嵌套小循环,小循环是个递归程序,通过return返回,并通过各种真假标记判断。
import java.util.*;
public class 使其和等于 {
public static void main(String[] args) {
使其和等于 a=new 使其和等于();
a.user();
//a.get(9,8);
System.out.println(a.showNum.toString());
//System.out.print(a.wantNumBank.toString());
//System.out.print(a.showNum.toString());
}
// int 给的x开始的数=1;
int mark=1;
// int 目标数=0;
int target=0;
// int 送入数组其中数=0;
int wantNum=0;
int length=0;
String tempString;
boolean flag=false;
boolean bigflag=false;
int bigtarget=0;
//读取东西A的ALL东西出来
StringBuffer wantNumBank=new StringBuffer();
//按照表示应该是 组合:XX,XX,送入数组其中数,给的X开始的数
StringBuffer showNum=new StringBuffer();
void sum(int toMark,int toTarget){
//这个事小循环模组
// System.out.println("你好像现在中层的x"+toMark);
mark=toMark;
// System.out.println("传入了个mark角标"+mark);
target=toTarget;
// System.out.println("传入了个target我要求和的数"+target);
for(int x=mark;x<=length;x++){
mark=x;
//下面if都是不满足条件跳出,并且打开能进入修改标记的大循环中的if语句
if(!(target-mark>0)){
// System.out.println("不符合1:将重新定位target为----"+toTarget);
// System.out.println("不符合1:将重新定位mark为----"+toMark);
// System.out.println("我将眺望"+x+"-1");
flag=true;
bigflag=true;
return;
}
if((target-mark)==mark){
// System.out.println("不符合2:将重新定位target为----"+target);
// System.out.println("不符合2:将重新定位mark为----"+mark);
// System.out.println("我将眺望"+x+"-1");
flag=true;
bigflag=true;
return;
}
if((target-mark)<mark){
// System.out.println("不符合2:将重新定位target为----"+target);
// System.out.println("不符合2:将重新定位mark为----"+mark);
// System.out.println("我将眺望"+x+"-1");
flag=true;
bigflag=true;
return;
}
wantNum=target-mark;
// System.out.println("x="+x+"wantNUm="+wantNum);
for(int y=1;y<=length;y++){
// System.out.println("你好现在中层的x"+toMark+"里层的y"+y);
// System.out.println("y="+y+"wantNUm="+wantNum);
//找到你要找的数
if(y==wantNum){
// System.out.println(wantNumBank.toString());
// System.out.println(mark);
//把可能的组合加进去
showNum.append("组合:"+wantNumBank+mark+"+"+wantNum+"="+bigtarget+"\n");
wantNumBank.append(mark+"+");
// System.out.println(tempString.toString());
// System.out.println(showNum.toString());
toMark=mark+1;
toTarget=wantNum;
//递归
sum(toMark,toTarget);
}
//有可能递归从这里跳出,这里就可以再次判断跳出~
if(flag){
return;
}
}
}
}
void get(int target,int length){
//大循环
for(int x=1;x<length;x++){
//修改判断标记全假,不然内循环某些地方还没弄完就跳出,
//这个语句是内层跳出来改写bigflag为true才能进入,
if(bigflag){
flag=false;
bigflag=false;
}
// System.out.println("我是最外层,现在第"+x);
wantNum=0;
//每次出来都要清空
wantNumBank.delete(0, wantNumBank.length());
// System.out.println(wantNumBank.toString());
sum(x,target);
}
//System.out.println(mark+"+"+target+"+"+length);
}
void user(){
System.out.print("输入你所给与数列最大数");
this.length=new Scanner(System.in).nextInt();
System.out.print("输入你的和");
this.target=new Scanner(System.in).nextInt();
bigtarget=target;
get(target,length);
}
}
//
// void reout(int target,int mark){
// if(!(target-mark>0)){
// System.out.println("不符合1:将重新定位target为----"+toTarget);
// System.out.println("不符合1:将重新定位mark为----"+toMark);
//
// return;
// }
// if((target-mark)==mark){
// System.out.println("不符合2:将重新定位target为----"+target);
// System.out.println("不符合2:将重新定位mark为----"+mark);
//
// return;
// }
// }
//}
// void sum(){
// int 给的x开始的数=1;
// int 目标数=0;
// int 送入数组其中数=0;
// final int 最大长度=目标数;
// for(int x=给的x开始的数;x<最大长度;x++){
// 送入数组其中数=目标数-给的x开始的数;
// 17=18-1
//
// //读取东西A的ALL东西出来
// //读取出来的格式为 XX,XX,
// //再用个东西wantNumBank存给的x开始的数
// //存入格式为 XX,
// //把 ALL东西+送入数组其中数+给的X开始的数 都送进 一个东西
// //按照表示应该是 组合:XX,XX,送入数组其中数,给的X开始的数
//
// //(给的x开始的数+1)传给下面调用的函数
// //目标数=送入数组其中数
//
// void sum(int 给的x开始的数,int 目标数){
//
// }
// }
// }
//}
//
//
//17=18-1
//
//1 17 送数组
//1临时数组
//
//15=17-2
//1 2 15 songshuzu
//
//1 2
复制代码
作者:
许晓华
时间:
2013-1-30 23:20
import java.util.Scanner;
public class x
{
static int Max=1000;
static int n,m;//n个数中选出若干数,总和为m
static int []a=new int[Max];//存放n个数
static int []flag=new int[Max];//标记n个数是否被选,1选,0不选
static void f(int sum,int idx)
{
if(sum==0)
{
for(int i=0;i<idx;i++)
if(flag[i]==1)
System.out.print(a[i]+" ");
System.out.println();
return;
}
if(sum<0||idx==n)
return;
flag[idx]=1;//选第idx号
f(sum-a[idx],idx+1);//递归
flag[idx]=0;//不选第idx号
f(sum,idx+1);//递归
}
public static void main(String[] args)
{
Scanner sc=new Scanner(System.in);
n=sc.nextInt();
m=sc.nextInt();
for(int i=0;i<n;i++)
a[i]=i+1;
f(m,0);//递归
}
}
复制代码
当n=5,m=6 时,结果如下:
2013-01-30_231936.jpg
(2.5 KB, 下载次数: 21)
下载附件
2013-1-30 23:19 上传
作者:
梁永奇
时间:
2013-1-31 03:12
你题目中说想要算法,所以我把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);
}
}
}
}
作者:
周发建
时间:
2013-2-1 14:43
这里的牛人很多啊
作者:
周发建
时间:
2013-2-1 14:43
看到你们的回答问题,我就感觉我真是个不够认真的人
作者:
周发建
时间:
2013-2-1 14:43
我向你们致敬,和向你们学习
作者:
周发建
时间:
2013-2-1 14:44
谢谢你们的辛苦付出,真心希望你们能不断牛
作者:
周发建
时间:
2013-2-1 14:44
祝福你们能够更加幸福,快乐
作者:
周发建
时间:
2013-2-1 14:45
你们的付出,不是白付出的,我们这些新来的会从你们的经验中收获很多
作者:
周发建
时间:
2013-2-1 14:45
你们的经验,就是可以让我们,学习少走弯路
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2