`
lknh
  • 浏览: 25996 次
  • 性别: Icon_minigender_1
  • 来自: 广西
社区版块
存档分类
最新评论

子集和问题

阅读更多
http://www.iteye.com/topic/788198
数组a[]={3,5,2,4,1,8},要求从a中找出所有“和”等于10的子集。
关于这个问题大家有什么看法,我能想到的就是遍历。
解法一:
Java代码 
public static void main(String[] args) {  
int a[]={3,5,2,4,1,8};  
int sub[]=new int[a.length];  
int SUM=10;  
for(int i=0;i<a.length;i++){  
    int res=a[i];  
    sub[0]=a[i];  
    int nextIndex=i+1;  
    for(int j=i+1;j<a.length;j++){  
        res+=a[j];  
        sub[j-nextIndex+1]=a[j];  
        if(res==SUM){  
            for(int x=0;x<=j-nextIndex+1;x++){  
                System.out.print(sub[x]+((x<j-nextIndex+1)?"+":""));  
            }  
            System.out.println("="+SUM);  
            j=nextIndex++;  
            res=a[i];  
            continue;  
        }else if(res>10){  
            j=nextIndex++;  
            res=a[i];  
            continue;  
        }  
    }  
}  


public static void main(String[] args) {
int a[]={3,5,2,4,1,8};
int sub[]=new int[a.length];
int SUM=10;
for(int i=0;i<a.length;i++){
int res=a[i];
sub[0]=a[i];
int nextIndex=i+1;
for(int j=i+1;j<a.length;j++){
res+=a[j];
sub[j-nextIndex+1]=a[j];
if(res==SUM){
for(int x=0;x<=j-nextIndex+1;x++){
System.out.print(sub[x]+((x<j-nextIndex+1)?"+":""));
}
System.out.println("="+SUM);
j=nextIndex++;
res=a[i];
continue;
}else if(res>10){
j=nextIndex++;
res=a[i];
continue;
}
}
}

3+5+2=10
3+2+4+1=10
5+4+1=10
2+8=10

解法二:
这个问题和什么硬币兑换的问题是同构的,用递归算法最简洁:

Java代码 
import java.util.Stack;  
 
public class SubsetCalc {  
 
    private int[] a = { 8, 5, 4, 3, 2, 1 };  
    private int sum = 10;  
    private Stack<Integer> stack = new Stack<Integer>();  
    private int stackSum = 0;  
 
    private void calc(int from, int to) {  
        if (stackSum == sum) {  
            for (Integer i : stack)  
                System.out.print(i + " ");  
            System.out.println();  
            return;  
        }  
 
        for (int i = from; i < to; i++) {  
            if (stackSum + a[i] <= sum) {  
                stackSum += stack.push(a[i]);  
                calc(i + 1, to);  
                stackSum -= stack.pop();  
            }  
        }  
    }  
 
    public void subsets() {  
        calc(0, a.length);  
    }  
 
    public static void main(String[] args) {  
        new SubsetCalc().subsets();  
    }  


import java.util.Stack;

public class SubsetCalc {

private int[] a = { 8, 5, 4, 3, 2, 1 };
private int sum = 10;
private Stack<Integer> stack = new Stack<Integer>();
private int stackSum = 0;

private void calc(int from, int to) {
if (stackSum == sum) {
for (Integer i : stack)
System.out.print(i + " ");
System.out.println();
return;
}

for (int i = from; i < to; i++) {
if (stackSum + a[i] <= sum) {
stackSum += stack.push(a[i]);
calc(i + 1, to);
stackSum -= stack.pop();
}
}
}

public void subsets() {
calc(0, a.length);
}

public static void main(String[] args) {
new SubsetCalc().subsets();
}


可以参考一个很经典的走台阶问题。我写了一份代码,如下:
Java代码 
public class Compositor {  
    
  static int[] a = { 8, 5, 4, 3, 2, 1 };  
    
  static int sum = 10 ;  
    
  public static void main(String[] args)  
  {  
    for(int i = 0 ; i < a.length ;i++)  
      subSet(new LinkedList<Integer>(), i);  
    }  
    
  public static void printResult(List<Integer> numList)  
  {  
    for(int i = 0 ; i < numList.size() ; i++)  
    {  
      if(i > 0)  
        System.out.print("+");  
      System.out.print(numList.get(i));  
    }  
    System.out.println("="+sum);  
  }  
    
  public static void subSet(List<Integer> numList,int start)  
  {  
      int curNum = a[start];  
        
      int total =  0 ;   
      for(int k = 0 ; k < numList.size() ; k++)  
      {  
        total += numList.get(k);  
      }  
        
      if(total + curNum == sum)  
      {  
        numList.add(curNum);  
        printResult(numList);  
      }  
        
      if(total + curNum < sum)  
      {  
        numList.add(curNum);  
        for(int i = start+1 ; i < a.length; i++)  
        {  
          List<Integer>  newList = new LinkedList<Integer>();  
          newList.addAll(numList);  
          subSet(newList,i);  
        }  
      }  
  }  

分享到:
评论

相关推荐

    子集和问题子集和问题的一个实例为〈S,t〉。其中,S={x1,x2,...,xn}是一个正整数的集合,c

    子集和问题 Description 子集和问题的一个实例为〈S,t〉。其中,S={x1,x2,...,xn}是一个正整数的集合,c 是一个正整数。子集和问题判定是否存在S的一个子集S1,使得x∈S1,∑x=c. 试设计一个解子集和问题的回溯法...

    回溯法求解子集和问题

    回溯法是一种强大的算法策略,常用于解决组合优化问题,如子集和问题。这个问题的目标是从给定的一组整数中找出所有可能的子集,使得这些子集的元素和等于一个特定的目标值。在本案例中,我们将深入探讨如何使用回溯...

    5-1+_子集和问题_

    子集和问题的一个实例为?St?〈St〉。其中,S={x1,x2,…,xn}S={x1,x2,…,xn}是一个正整数的集合,c是一个正整数。子集和问题判定是否存在 S 的一个子集 S1,使得 ∑x∈S1x=c ∑x∈S1x=c。试设计一个解子集和...

    子集和问题(算法设计,acm)

    ### 子集和问题解析与实现 #### 一、子集和问题介绍 子集和问题(SubSet Sum Problem)是一个经典的计算机科学问题,在算法设计、数据结构、甚至密码学等领域都有广泛的应用。该问题的基本形式是:给定一组整数和一...

    算法设计实现题子集和问题c实现

    5-1 子集和问题 问题描述:子集和问题的一个实例为,t&gt;。其中,S={x1,x2,...,xn}是一个正整数的集合,c是一个正整数 。 子集和问题判定是否存在S 的一个子集S1,使得子集里的元素之和为c 试设计一个解子集和问题的...

    算法设计与分析-子集和问题

    ### 算法设计与分析:子集和问题 #### 问题定义 子集和问题是一种经典的计算机科学问题,属于NP完全问题。该问题的基本形式是:给定一个正整数集合\( S=\{x_1,x_2,…,x_n\} \)和一个正整数\( c \),询问是否存在...

    8603子集和问题

    "8603子集和问题" 这是一道典型的搜索算法问题,特别是子集和问题。给定一个整数集合 S={x1,x2,...,xn} 和一个整数 c,目标是找到 S 的一个子集 S1,使得 S1 的元素之和等于 c。 在这里,我们可以使用回溯算法来...

    子集和问题C++.txt

    子集和问题C++.txt

    子集和问题代码

    算法分析课程作业,C语言编写,可能需要用input.txt输入,子集和问题代码

    实现5-1子集和问题.cpp

    实现5-1子集和问题.cpp

    完全多项式时间近似算法(子集和问题)

    子集和。近似算法能够获得近似值和近似解,并且是一种完全多项式时间近似方案。 包括指数时间算法、修整算法、近似算法,可以获得近似值和近似解

Global site tag (gtag.js) - Google Analytics