从一个整数数组中找出总和为S的所有子集

17 篇文章 0 订阅
10 篇文章 0 订阅
本文将记录实现“从一个整数数组中找出总和为S的所有子集”功能的两种方法。

1. 使用Stack来实现

2. 不借助Stack来实现。

[u][b]使用Stack来实现[/b][/u]

import java.util.Stack;

public class GetAllSubsetByStack {

/** Set a value for target sum */
public static final int TARGET_SUM = 15;

private Stack<Integer> stack = new Stack<Integer>();

/** Store the sum of current elements stored in stack */
private int sumInStack = 0;

public void populateSubset(final int[] data, int fromIndex, int endIndex) {

if (sumInStack >= TARGET_SUM) {
if (sumInStack == TARGET_SUM) {
print(stack);
}
// there is no need to continue when we have an answer
// because nothing we add from here on in will make it
// add to anything less than what we have...
return;
}

for (int currentIndex = fromIndex; currentIndex < endIndex; currentIndex++) {

if (sumInStack + data[currentIndex] <= TARGET_SUM) {
stack.push(data[currentIndex]);
sumInStack += data[currentIndex];

/*
* Make the currentIndex +1, and then use recursion to proceed
* further.
*/
populateSubset(data, currentIndex + 1, endIndex);
sumInStack -= (Integer) stack.pop();
}
}
}

/**
* Print satisfied result. i.e. 15 = 4+6+5
*/

private void print(Stack<Integer> stack) {
StringBuilder sb = new StringBuilder();
sb.append(TARGET_SUM).append(" = ");
for (Integer i : stack) {
sb.append(i).append("+");
}
System.out.println(sb.deleteCharAt(sb.length() - 1).toString());
}
}


方法调用的类:

public class Main {

private static final int[] DATA = { 1, 3, 4, 5, 6, 2, 7, 8, 9, 10, 11, 13,
14, 15 };

public static void main(String[] args) {
GetAllSubsetByStack example = new GetAllSubsetByStack();
example.populateSubset(DATA, 0, DATA.length);
}
}


[u][b]不借助Stack来实现[/b][/u]

import java.util.Arrays;

public class GetAllSubsets {

/** Set a value for target sum */
public static final int TARGET_SUM = 15;

public void populateSubset(final int[] data, int fromIndex,
final int[] stack, final int stacklen, final int target) {
if (target == 0) {
// exact match of our target. Success!
printResult(Arrays.copyOf(stack, stacklen));
return;
}

while (fromIndex < data.length && data[fromIndex] > target) {
// take advantage of sorted data.
// we can skip all values that are too large.
fromIndex++;
}

while (fromIndex < data.length && data[fromIndex] <= target) {
// stop looping when we run out of data, or when we overflow our
// target.
stack[stacklen] = data[fromIndex];
populateSubset(data, fromIndex + 1, stack, stacklen + 1, target
- data[fromIndex]);
fromIndex++;
}
}

private void printResult(int[] copyOf) {
StringBuilder sb = new StringBuilder();
sb.append(TARGET_SUM).append(" = ");
for (Integer i : copyOf) {
sb.append(i).append("+");
}
System.out.println(sb.deleteCharAt(sb.length() - 1).toString());
}
}


方法调用的类:
public class Main {

private static final int[] DATA = { 1, 3, 4, 5, 6, 2, 7, 8, 9, 10, 11, 13,
14, 15 };

public static void main(String[] args) {
GetAllSubsets example = new GetAllSubsets();
example.populateSubset(DATA, 0, new int[DATA.length], 0, 15);
}
}



两种实现方法都会打印出如下的结果:

15 = 1+3+4+5+2
15 = 1+3+4+7
15 = 1+3+5+6
15 = 1+3+2+9
15 = 1+3+11
15 = 1+4+2+8
15 = 1+4+10
15 = 1+5+2+7
15 = 1+5+9
15 = 1+6+8
15 = 1+14
15 = 3+4+6+2
15 = 3+4+8
15 = 3+5+7
15 = 3+2+10
15 = 4+5+6
15 = 4+2+9
15 = 4+11
15 = 5+2+8
15 = 5+10
15 = 6+2+7
15 = 6+9
15 = 2+13
15 = 7+8
15 = 15


转载请注明出处: [url]http://mouselearnjava.iteye.com/blog/1985360[/url]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值