对于练习,我必须添加数组的值,直到达到某个值,显示所有可能的组合。
示例:value = 4,array = {1,2,3}
可能的组合是:1 + 1 + 1 + 1,1 + 1 + 2,1 + 2 + 1,1 + 3 + 2 + 1 + 1,2 + 2,3 + 1
但是,我的代码似乎不起作用:
ggplot(df, aes(x,y, group=id)) +
geom_line() +
geom_line(data=df[1:10,], aes(x,y, group=id), size=5)
输出:
public static void main(String[] args) {
double[] array = { 1., 2., 3. };
double value = 4.;
for (int i = 0; i < array.length; i++) {
addNumber(array, value, i);
}
}
public static void addNumber(double[] array, double value, int index) {
double startNumber = array[index];
double checkSum = 0;
for (int i = 0; i < array.length; i++) {
checkSum += array[i] + startNumber;
if (checkSum == value){
System.out.println(startNumber + " + " + array[i] + " = " + checkSum);
} else if (checkSum < value){
moreNumbers(array, value, checkSum);
}
checkSum = 0;
}
}
public static void moreNumbers (double[] array, double value, double current){
if (current == value){
System.out.println(current);
} else if (current < value) {
for (int i = 0; i < array.length; i++){
current += array[i];
System.out.println("+ " + array[i] + " = " + current);
}
moreNumbers(array, value, current);
}
}
我相信我找不到合适的算法,因为我只获得了一些组合,但并非全部。
我的问题是:我正在寻找一种算法来帮助我理解这个练习,这是逻辑,而不是最终的代码。
编辑:在本练习的进一步发展中,我必须使用0.5或0.2之类的数字,但数字总是正数,所以这是我希望找到答案的另一个问题。答案 0 :(得分:2)
这是基于组合技术的解决方案之一。
<强>算法:强>
例如,如果输入为4
,那么length = 4的一些不同组合将如下所示:
1 1 1 1
1 1 1 2
.
.
2 1 2 3
.
.
3 3 3 3
现在,我们只打印1 1 1 1
,因为它总结为输入,即4
并满足条件。
同样,对于length = 3
,一些不同的组合将如下:
1 1 1
1 1 2
.
.
1 2 1
.
.
3 3 3
现在,我们只打印1 1 2
,1 2 1
和2 1 1
,因为它们都满足总和条件。
以下是如何计算不同组合的简要说明:
(它使用递归计算给定长度的所有组合)
代码段:
class Combinations
{
/* Constants Array (Sorted) */
private static final double[] ARR_CNST = {0.1,0.2,0.3};
/* Size of Constant Array */
private static final int SIZE = 3;
public static void main (String[] args)
{
/* Input Number */
double input = 0.4;
/* Start Permutations {Length --> 1} */
for(int i = (int) (input/ARR_CNST[0]); i > 0; i--) {
double[] storage = new double[i];
/* Fill Array With Least Element */
Arrays.fill(storage,ARR_CNST[0]);
/* Check Sum Condition */
if(check(storage,input)) {
/* Print */
print(storage);
}
/* Calculate Rest of the Combinations */
calc(storage, input);
}
}
private static void calc(double[] arr, double input) {
/* Increment Last Element if not MAX */
if(arr[arr.length - 1] < ARR_CNST[SIZE - 1]) {
int k = 0;
while(k < SIZE && arr[arr.length - 1] != ARR_CNST[k++]);
arr[arr.length - 1] = ARR_CNST[k];
if(check(arr,input)) {
print(arr);
}
calc(arr, input);
}
/* Increment & Reset */
int i = arr.length - 1;
while(i >= 0 && arr[i] >= ARR_CNST[SIZE - 1])
i--;
if(i >= 0) {
int k = 0;
while(k < SIZE && arr[i] != ARR_CNST[k++]);
arr[i] = ARR_CNST[k];
for(int x = i + 1; x < arr.length; x++) {
arr[x] = ARR_CNST[0];
}
if(check(arr,input)) {
print(arr);
}
calc(arr, input);
}
/* Return */
return;
}
/* Check Sum Condition */
private static boolean check(double[] arr, double input) {
double sum = 0;
for(int i = 0; i < arr.length; i++) {
sum += arr[i];
}
if(sum == input) {
return true;
}
return false;
}
/* Print Array Values */
private static void print(double[] arr) {
StringBuilder sb = new StringBuilder();
for(int i = 0; i < arr.length; i++) {
sb.append(arr[i] + " + ");
}
System.out.println(sb.substring(0,sb.length() - 3));
}
}
输出:
0.1 + 0.1 + 0.1 + 0.1
0.1 + 0.1 + 0.2
0.1 + 0.2 + 0.1
0.2 + 0.1 + 0.1
0.1 + 0.3
0.2 + 0.2
0.3 + 0.1
答案 1 :(得分:2)
这似乎可以通过递归轻松解决,如下所示:
获得4和{1,2,3}的解决方案(下面写成解决方案(4,{1,2,3})就像获得解决方案
在每一步,你减少了数字(当然,如果可用数字列表中没有0),那么你确定递归将完成。
您可以有两个结果:
还有另一件需要注意的事项:浮点平等。 ==每次都不会工作。
代码如:
public static void main(String[] args) {
ArrayList<String> solutions = new ArrayList<String>();
solve("", 1.0d, new Double[] {0.2d, 0.50d}, solutions);
System.out.println(solutions);
// [0.2 + 0.2 + 0.2 + 0.2 + 0.2, 0.5 + 0.5]
solutions.clear();
solve("", 4d, new Double[] {1d, 2d, 3d}, solutions);
System.out.println(solutions);
// [1.0 + 1.0 + 1.0 + 1.0, 1.0 + 1.0 + 2.0, 1.0 + 2.0 + 1.0, 1.0 + 3.0, 2.0 + 1.0 + 1.0, 2.0 + 2.0, 3.0 + 1.0]
}
public static void solve(String subSolution, Double remaining, Double[] authorizedNumbers, List<String> solutions) {
if (doubleEquals(remaining, 0d)) {
solutions.add(subSolution);
} else {
for(Double authorizedNumber : authorizedNumbers) {
if (doubleEquals(authorizedNumber, remaining)) {
solutions.add(subSolution + authorizedNumber);
} else if (authorizedNumber < remaining) {
solve(subSolution + authorizedNumber + " + ", remaining - authorizedNumber, authorizedNumbers, solutions);
}
}
}
}
public static boolean doubleEquals(double d1, double d2) {
return Math.abs(d1 - d2) < 0.000000001d;
}
答案 2 :(得分:1)
一般方法是:
这可以这样实现:
public static void startRecursion(int target, int[] numbers) {
int min = numbers[0];
for (int i = 1; i < numbers.length; ++i) {
min = Math.min(min, numbers[i]);
}
// We need to choose at most ceil(target / min) numbers.
int maxPicks = (target + min - 1) / min;
recurse(new int[maxPicks], 0, 0, target, numbers);
}
private static void recurse(
int[] picked, int numPicked, int sumOfPicked,
int target, int[] numbers) {
if (sumOfPicked == target) {
// We reached the target! Print out the numbers we chose to get here.
for (int i = 0; i < numPicked; ++i) {
if (i != 0) System.out.print(" + ");
System.out.print(picked[i]);
}
System.out.println(" = " + target);
} else if (sumOfPicked < target) {
// We haven't reached the target yet.
// Go through each of the numbers that you can choose from numbers
// in turn, increasing the sum by this amount.
for (int i = 0; i < numbers.length; ++i) {
picked[numPicked] = numbers[i];
recurse(
picked, numPicked + 1, sumOfPicked + numbers[i],
target, numbers);
}
} else {
// We have overshot the target. Since no numbers are negative,
// we can't get back to the target again.
}
}