Java 如何查找数组中包含相等和的子集:
如何在数组中查找包含相等和的子集。 比如说Java 如何查找数组中包含相等和的子集:,java,data-structures,Java,Data Structures,如何在数组中查找包含相等和的子集。 比如说 {1,2,3,4,2}->{1,2,3} && {4,2} {1,1,3,3,2,8}->{1,3,3,2}&&{1,8} {1,3,4,7}->no subset 我尝试了以下代码,但没有得到适当的输出 import java.util.* public static void main(String[] args) { int arr[] = {1,3,4,7}; int sum
{1,2,3,4,2}->{1,2,3} && {4,2}
{1,1,3,3,2,8}->{1,3,3,2}&&{1,8}
{1,3,4,7}->no subset
我尝试了以下代码,但没有得到适当的输出
import java.util.*
public static void main(String[] args) {
int arr[] = {1,3,4,7};
int sum = getSum(arr, arr.length);
int[] solution = new int[arr.length];
find(arr, 0, 0, sum, solution);
}
public static int getSum(int arr[], int n) {
float sum = 0f;
for (int i = 0; i < n; i++)
sum = sum + arr[i];
return Math.round(sum / 2);
}
public static void find(int[] A, int currSum, int index, int sum,
int[] solution) {
if (currSum == sum) {
System.out.println("\nSum found");
for (int i = 0; i < solution.length; i++) {
if (solution[i] == 1) {
System.out.print(" " + A[i]);
}
}
} else if (index == A.length) {
return;
} else {
solution[index] = 1;// select the element
currSum += A[index];
find(A, currSum, index + 1, sum, solution);
currSum -= A[index];
solution[index] = 0;// do not select the element
find(A, currSum, index + 1, sum, solution);
}
return;
}
输入数组:1,1,3,3,2,8
1 3 3 2
1 8
1 3 3 2
1 8
输入数组:1,3,4,7
1 3 4
1 7
要解决这个问题,您需要在代码中至少有3个嵌套循环 sudocode会像
for (i=0,i< array.length-1,i++){
for(k=i;k<array.length-1,k++){
fsum=findSum(i/*from*/,k/*to*/,array);
ssum=0;
for(x=k,x<array.length,x++){
secondsum=findSum(k,x,array);
if(fsum==ssum){
prend(i,k,array);
print(k,x,array);
break;
}
}
}
}
for(i=0,i 对于(k=i;k而言,代码的重复部分工作正常。在相当外围的部分中只有两个小缺陷:
如果两个子集仅在数和为偶数的情况下才存在,则你的代码不考虑这一要求,这是关于{1,3,4} 7}失败的原因。为此,主函数的主体被稍微修改,以便仅对偶数进行递归。
你应该把重复的内容分类,这样可以防止关于{1,2,3,4,2}和{1,1,3,3,2,8}的重复。为此,只需存储生成的子集。然后,在删除重复项后,打印出剩余子集。为方便起见,这两个功能都封装在添加的SubsetPair类中,该类分别提供用于存储和打印的方法storeSubsetPair和printSubsetPairList。
修改后的代码为:
import java.util.*;
public class Main {
public static void main(String[] args) {
int arr[] = {1,3,4,7};
int sum = getSum(arr, arr.length);
int[] solution = new int[arr.length];
// find(arr, 0, 0, sum, solution); // REPLACED WITH: -----------------
if (sum % 2 == 0) {
sum = Math.round(sum / 2f);
find(arr, 0, 0,sum, solution);
}
SubsetPair.printSubsetPairList();
// -------------------------------------------------------------------
}
public static int getSum(int arr[], int n) {
// float sum = 0f; // REPLACED WITH: ---------------------------------
int sum = 0;
// -------------------------------------------------------------------
for (int i = 0; i < n; i++)
sum = sum + arr[i];
// return Math.round(sum / 2); // REPLACED WITH: ---------------------
return sum;
// -------------------------------------------------------------------
}
public static void find(int[] A, int currSum, int index, int sum,
int[] solution) {
if (currSum == sum) {
// System.out.println("\nSum found"); // REPLACED WITH: ----------
// for (int i = 0; i < solution.length; i++) {
// if (solution[i] == 1) {
// System.out.print(" " + A[i]);
// }
// }
SubsetPair.storeSubsetPair(A, solution);
// ---------------------------------------------------------------
} else if (index == A.length) {
return;
} else {
solution[index] = 1;// select the element
currSum += A[index];
find(A, currSum, index + 1, sum, solution);
currSum -= A[index];
solution[index] = 0;// do not select the element
find(A, currSum, index + 1, sum, solution);
}
return;
}
}
//NEW: Class for storage and print:
class SubsetPair {
private static List<SubsetPair> subsetPairList = new ArrayList<>();
private List<Integer> subset1 = new ArrayList<>();
private List<Integer> subset2 = new ArrayList<>();
//
// Storage of the subset pair
//
public static void storeSubsetPair(int[] A, int[] solution) {
SubsetPair subsetPair = new SubsetPair();
for (int i = 0; i < solution.length; i++) {
if (solution[i] == 1) {
subsetPair.subset1.add(A[i]);
} else {
subsetPair.subset2.add(A[i]);
}
}
if (!subsetPair.isDuplicate()) {
subsetPairList.add(subsetPair);
}
}
// Remove duplicates
private boolean isDuplicate() {
for (SubsetPair subsetPair : subsetPairList) {
if (isEqual(subset1, subsetPair.subset2) && isEqual(subset2, subsetPair.subset1) ||
isEqual(subset1, subsetPair.subset1) && isEqual(subset2, subsetPair.subset2)) {
return true;
}
}
return false;
}
private boolean isEqual(List<Integer> subset1, List<Integer> subset2) {
return subset1.containsAll(subset2) && subset2.containsAll(subset1);
}
//
// Output of the subset pairs
//
public static void printSubsetPairList() {
if (subsetPairList.size() == 0) {
System.out.println("No subset-pairs found!");
} else {
for (int i = 0; i < subsetPairList.size(); i++) {
subsetPairList.get(i).printSubsetPair(i + 1);
}
}
}
private void printSubsetPair(int i) {
System.out.print(i + ". Subset-Pair:\n");
System.out.print("Subset 1: ");
for (Integer i1 : subset1) {
System.out.print(i1 + " ");
}
System.out.println();
System.out.print("Subset 2: ");
for (Integer i2 : subset2) {
System.out.print(i2 + " ");
}
System.out.print("\n\n");
}
}
对于偶数和为18的{1,1,3,3,2,8}:
1. Subset-Pair:
Subset 1: 1 3 3 2
Subset 2: 1 8
对于奇数和为15的{1,3,4,7}:
No subset-pairs found!
对于偶数和为10的{3,1,1,2,2,1}:
1. Subset-Pair:
Subset 1: 3 1 1
Subset 2: 2 2 1
2. Subset-Pair:
Subset 1: 3 2
Subset 2: 1 1 2 1
对于偶数和为14的{2,4,8}:
No subset-pairs found!
正如在前面的评论中所述,该问题与“划分问题”有关,该问题的任务是确定一组多个正整数是否可以划分为两个等和的子集。这一点在
但这两个问题并不完全相同,因为“分区问题”的解决方案只需回答问题如果多集可以划分为两个子集,但不能明确地确定子集本身。您的代码有编译错误。getSum
方法无效,但您设置为int。请修复。这是一个经典问题,尽管不是那么容易:我已经更新了getSum方法。您的代码正在计算所有可能的结果。那么问题是什么?在您对编程技术有了充分的了解之前,不要学习语言和库。找到每个可能组合的总和,并将其(连同该组合)存储在排序图(RB树或其他)中。然后找到相等的总和。
1. Subset-Pair:
Subset 1: 3 1 1
Subset 2: 2 2 1
2. Subset-Pair:
Subset 1: 3 2
Subset 2: 1 1 2 1
No subset-pairs found!