首先输入想得到的数字N,其次输入现有数字num[](个数不限),得出num[]中相加可以等N或接近N的所有组合。
在输入“Q”时,停止输入数字,开始计算,接近N,就是范围可以自定,50以内,5以内都可以,无所谓。

解决方案 »

  1.   

    什么叫“接近N”
    1接近100吗?通常人的理解来说,不是。但是从自然数/Integer的角度来说,1和100又是接近的。
      

  2.   

    public void algorithm(int[] array,int min,int max,int rank)
    其中,array为待求数组,min为范围的最小值,max为范围的最大值,rank为级别(为了输出清晰,先可不考虑)
    算法如下:
    1、排序
    2、算法调用:
       当前数组长度是否为1?
           是:判断当前值是否符合要求,是则输出。无论是否,方法返回。
           否:(1)判断当前值是否有符合要求的,有则输出;
               (2)由大到小,依次取出当前数组中小于max的最大值,不妨设其为V(为了叙述方便)。
                    每次取出之后,subArray等于array除了V的子数组。
                    int subMin = min-V;
                  int subMax = max-V;
                  递归调用algorithm(subArray,subMin,subMax,tempRank);(最后一个参数可以先不
                    考虑,只是为了输出格式而定义的)
    源代码如下:
    /*
     * To change this template, choose Tools | Templates
     * and open the template in the editor.
     *//**
     *
     * @author afunx
     */
    public class Algorithm {
        public static void main(String args[]){
            Algorithm a = new Algorithm();
            int[] array = {5,4,3,2,1};
            //排序
            a.sort(array);
            for(int b:array)
                System.out.print(b+",");
            System.out.println();
            //算法调用
            a.algorithm(array, 3, 8,1);
            System.out.println();
        }
        /**
         *
         * @param array 数组
         * @param min   最小值
         * @param max   最大值
         * @param rank  级别,为了显示清晰,最初为1,
         */
        public void algorithm(int[] array,int min,int max,int rank){
            //如果数组为一维,递归结束
            if(array.length==1){
                if(min<=array[0]&&array[0]<=max)
                    System.out.println("("+rank+")"+array[0]);
                else
                     return;
            }
            else{
                //再加1元素即可达到要求
                for(int a:array){           
                    if(min<=a&&a<=max){                    
                        System.out.print("("+rank+")");
                        System.out.print(a+",");
                    }
                }
                System.out.println();
                //优先取最外维(即数组中小于max的最大值)为一元素,其余递归调用algorithm
                for(int i=array.length-1;i>0;i--){
                    if(array[i]<max){
                    for(int k=0;k<rank;k++){
                        System.out.print(" ");
                    }
                    System.out.println("("+rank+")"+array[i]+":");
                    //子数组
                    int[] subArray= new int[i];
                    //把array中下标从0到i的值复制到subArray
                    copy(array,subArray,i);
                    //递归调用
                    int subMin = min-array[i];
                    int subMax = max-array[i];
                    int tempRank = rank+1;
                    algorithm(subArray,subMin,subMax,tempRank);
                    }
                }                                
            }
        }    //数组copy,origin为源数组,target为目标数组,length为源数组从0开始的个数。
        /**
         * 子数组拷贝
         * @param origin    源数组
         * @param target    目标数组
         * @param length    源数组从0开始的个数
         */
        private void copy(int[] origin,int[] target,int length){
            for(int i=0;i<length;i++){
                target[i] = origin[i];
            }
        }    //数组排序(这里采用最简单的冒泡法)
        private void sort(int[] array){
            for(int i=array.length;i>0;i--)
                for(int j=1;j<i;j++){
                    if(array[j-1]>array[j])
                        swap(array,j-1,j);
                }
        }    //交换数组的位置
        private void swap(int[] array,int x,int y){
            int temp = array[x];
            array[x] = array[y];
            array[y] = temp;
        }
    }
    输出结果:
    1,2,3,4,5,
    (1)3,(1)4,(1)5,
     (1)5:
    (2)1,(2)2,(2)3,
      (2)2:
    (3)1
     (1)4:
    (2)1,(2)2,(2)3,
      (2)3:
    (3)1,
      (2)2:
    (3)1
     (1)3:
    (2)1,(2)2,
      (2)2:
    (3)1
     (1)2:
    (2)1
    输出含义:顶格的为可能组合的最后那个元素,“()”中的数为rank值,这样可以显示清除多重结构。此输出解释:此输入数组为{5,4,3,2,1},求其组合值在[3,8](包括3和8)。
                此输出结果含义:
                 3;4;5;
               5,1;5,2;5,3;
               5,2,1;
               4,1;4,2;4,3
               4,3,1;4,2,1
               3,1,;3,2;
               3,2,1;
               2,1;
    (不同的组合用";"区别,同一组合中的不同数用","间隔)
               
      

  3.   

    目标值N,可以允许的误差为M(接近的程度)
    max = N+M,min = N-M;
    还有就是输入一连串的数,最后用Q来结束。
    这两个挺简单的,楼主自己再改下代码即可。
      

  4.   

    实在不会做,做了几个小时才做个这样子、、package arithmetic;import java.util.*;
    public class SumComArithmetic { /**
     * @param args
     */
    /**
     * @param args
     */
    public static void main(String[] args) {
    // TODO Auto-generated method stub 

    Scanner input = new Scanner(System.in );
    System.out.print("Please input you target number:");
    int targetNumber = input.nextInt();

    int[] num = null ;
        int index = 0;

    while(true){
    System.out.print("input: ");
    String t = input.next();
    if(t.trim().equals("Q"))
    break;
    else
      if(SumComArithmetic.checkInput(t)){
      
      if(num == null)
      {
      num = new int[1];
      num[0] = new Integer(t).intValue();
      }
      else
      {
      index ++;
      
      int[] temp = new int[num.length + 1];
      
      for(int i=0; i<num.length; i++)
      {
      temp[i] = num[i];
      }
      num = temp;
      num[index] = new Integer(t).intValue();;
       }
      }
      else
      {
      System.out.println("input error, please again");
      continue;
      }
    }

    System.out.println("you input target Number is: " + targetNumber);
    printArray(num);
    Arrays.sort(num);
    System.out.print("\n");
    printArray(num);
    }

    /**
     * 判断输入 内容的合法性 ,必须是 数字 和 "Q"
     * 
     * @param str
     * @return boolean
     */
    private static boolean checkInput(String str){

    int len = str.length();
    int i = 0;

    while(i < len)
    {
    //不是字符Q执行
    if(!str.equals("Q"))
    //不是数字执行
    if(!Character.isDigit((str.charAt(i))))
    return false; 
    i++;
    }

    return true;
    }

    /***
     * 打印要组合的 数组,并判断目标数字是否小于要组合的数组元素
     * @param arrays
     * @return boolean 目标数是否 小于数组中的数 
     */
    public static boolean printArray(int[] arrays){
    System.out.print("you input number is: ");
    for(int i=0; i<arrays.length; i++)
    {
    System.out.print(arrays[i] + " ");
    }

    return false;



    /**
     * 接近目标数的组合,返回 List集合
     * @param num 目标数
     * @param arrays  输入的数组
     */
    public static  void  complay(int num,int[] arrays){

    }

    }
      

  5.   


    package arithmetic;import java.util.*;
    public class SumComArithmetic { /**
     * @param args
     */
    /**
     * @param args
     */
    public static void main(String[] args) {
    // TODO Auto-generated method stub 

    Scanner input = new Scanner(System.in );
    System.out.print("Please input you target number:");
    int targetNumber = input.nextInt();

    int[] num = null ;
        int index = 0;

    while(true){
    System.out.print("input: ");
    String t = input.next();
    if(t.trim().equals("Q"))
    break;
    else
      if(SumComArithmetic.checkInput(t)){
      
      if(num == null)
      {
      num = new int[1];
      num[0] = new Integer(t).intValue();
      }
      else
      {
      index ++;
      
      int[] temp = new int[num.length + 1];
      
      for(int i=0; i<num.length; i++)
      {
      temp[i] = num[i];
      }
      num = temp;
      num[index] = new Integer(t).intValue();;
       }
      }
      else
      {
      System.out.println("input error, please again");
      continue;
      }
    }

    System.out.println("you input target Number is: " + targetNumber);

    Arrays.sort(num);
    System.out.print("\n");
    printArray(num);

    complay(targetNumber,num);
    }

    /**
     * 判断输入 内容的合法性 ,必须是 数字 和 "Q"
     * 
     * @param str
     * @return boolean
     */
    private static boolean checkInput(String str){

    int len = str.length();
    int i = 0;

    while(i < len)
    {
    //不是字符Q执行
    if(!str.equals("Q"))
    //不是数字执行
    if(!Character.isDigit((str.charAt(i))))
    return false; 
    i++;
    }

    return true;
    }

    /***
     * 打印要组合的 数组,并判断目标数字是否小于要组合的数组元素
     * @param arrays
     * @return boolean 目标数是否 小于数组中的数 
     */
    public static boolean printArray(int[] arrays){
    System.out.print("you input number is: ");
    for(int i=0; i<arrays.length; i++)
    {
    System.out.print(arrays[i] + " ");
    }

    return false;



    /**
     * 接近目标数的组合,返回 List集合
     * @param num 目标数
     * @param arrays  输入的数组
     */
    public static  void  complay(int num,int[] arr){

    for(int i= 0;i<arr.length;i++)
            {
             lottery(arr , 0, arr.length-1, i,new HashSet<Integer>());
            }
            System.out.print("[");
            for(int i= 0;i<arr.length;i++)
            {
             System.out.print(arr[i]+" ");
            }
            System.out.print("]");
    }


    private static void lottery(int a[], int start_index, int end_index,
                int needed_balls, Set<Integer> already_chosen) {
            if (needed_balls == 0) {
                System.out.println(already_chosen);
                return;
            }
            for (int i = start_index; i <= end_index - needed_balls + 1; i++) {
                already_chosen.add(a[i]);
                lottery(a, i + 1, end_index, needed_balls - 1, already_chosen);
                already_chosen.remove(a[i]);
            }
        }

    }
      

  6.   

    数学上的组合排列知识也忘的差不多了;一些常见的算法问题也还得继续学习;
    不多说了,给个示例,实现了单线程查找,和多线程查找,楼主也可尝试先排序再组合优化查找:import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.Collections;
    import java.util.List;public class AlgorithmicDemo { public static void main(String[] args) {
    //从控制台获取数字 (略)
    // Scanner input = new Scanner(System.in);
    // while(true){
    //
    // }
    int[] data = {4,3,5,7,1};
    int target = 5;
    int offset = 3;
    System.out.println("范围在 " + (target-offset) + " 到  " + (target+offset) + "的数字组合有:");
    DataStore dataStore = new DataStore(data);
    for(int i = 1; i <= data.length; i++){
    AlgorithmicThread thread = new AlgorithmicThread(dataStore,i,offset,target);
    thread.getResult();//单线程查找
    //thread.start();//多线程查找 
    }
    dataStore.display();
    }}class DataStore{
    int[] data;//原始数字列表
    int size;//数子个数

    List<String> list;//符合要求的数字组合列表

    public DataStore(int[] data){
    if(data == null) throw new NullPointerException();
    this.data = data;
    this.size = data.length;
    list = new ArrayList<String>();
    }

    /**
     * 获取一个线程安全的列表list
     * @return 线程安全的List
     */
    public List<String> getResultList(){
    return Collections.synchronizedList(list);
    }

    /**
     * @return 原始的数字数组
     */
    public int[] getData(){
    return data;
    }

    public int getSize(){
    return size;
    }

    /**
     * 展示符合要求的数字组合结果
     */
    public void display(){
    for(int i = 0; i < list.size(); i++){
    System.out.println(list.get(i));
    }
    System.out.println("一共   " + list.size()+ " 个数字组合符合 要求 .");
    }
    }class AlgorithmicThread extends Thread{ DataStore dataStore; 
    int count;//数字组合个数
    int offset;//范围宽度
    int target;//目标数字
    List<String> list;

    public AlgorithmicThread(DataStore dataStore,int count,int offset,int target){
    this.dataStore = dataStore;
    this.count = count;
    this.offset = offset;
    this.target = target;
    this.list = dataStore.getResultList();
    }

    /**
     * 这是数字组合算法,根据传递的数字组合个数count,创建一个数组array,用于存储可能的数字组合,
     * 每次从dataStore中选择一个数字放入array时判断结果是否合格,合格存入dataStore的列表list中;
     */
    public void getResult(){
    int[] array = new int[count];

    int forntIndex = 0;
    int rearIndex = count-1;
    int nCount = dataStore.getSize() - count;
    for(int i = 0; i <= nCount; i++){
    int tempIndex = 0;
    tempIndex = forntIndex;
    for(int m = 0; m < count; m++){
    array[m] = dataStore.getData()[tempIndex++];
    }
    getSumResult(list, array, (target - offset), (target + offset));

    rearIndex++;
    forntIndex++;

    tempIndex = 0;
    int index = rearIndex;
    for(int n = (count-1); n > 0; n--){
    for(int j = (nCount-i); j > 0; j--){
    array[n] = dataStore.getData()[index++];
    getSumResult(list, array, (target - offset), (target + offset));
    }
    index = rearIndex-(++tempIndex);
    }
    }
    }

    @Override
    public void run() {
    super.run();
    getResult();
    }


    /**
     * 判断数字组合是否符合要求
     * @param resultList
     * @param array
     * @param start
     * @param end
     */
    public void getSumResult(List<String> resultList,int[] array, int start, int end){
    int sum = 0;
    for(int i = 0; i < array.length; i++){
    sum += array[i];
    }
    if(sum >= start && sum <= end){
    resultList.add(Arrays.toString(array));
    }
    }
    }