添加/减去数字的算法,以查找是否可以编号?

时间:2014-02-28 02:32:52

标签: algorithm numbers computer-science addition

我想知道是否有一种有效的预制算法来确定一组数字的和/差是否可以等于不同的数字。例如:

5,8,10,2,使用+或 - ,等于9。 5 - 8 = -3 + 10 = 7 + 2 = 9

如果存在预先存在的算法,那么它的名称是什么。如果没有,我可以弄清楚如何编程,虽然它可能效率不高。

谢谢!

3 个答案:

答案 0 :(得分:2)

是的,这基本上是背包问题,但它可以使用动态编程在伪多项式时间内计算。

我几个月前就做过了,所以也许这个java代码可以帮助你,如果你想实现它:

public void solve() {
    while (this.isEnd() == false) {
        int priceSum = this.getItemsInstance().getTotalPrice()/divide;
        int numOfItems = this.getItemsInstance().itemCount();
        int maxWeight = this.getItemsInstance().getMaxWeight();

        int[][] array = new int[numOfItems + 1][priceSum + 1];
        boolean[][] arrayCounted = new boolean[numOfItems + 1][priceSum + 1];

        for (int i = 0; i < numOfItems + 1; i++) {
            array[i][0] = 0;
            arrayCounted[i][0] = true;
        }

        int max = 0;
        int price = 0;
        for (int j = 1; j < priceSum + 1; j++) {
            for (int i = 1; i < numOfItems + 1; i++) {
                int temp = W(i, j, array, arrayCounted);
                if (temp <= maxWeight) {
                    max = temp;
                    price = j;
                }
            }
        }
    }
}

private int W(int i, int c, int[][] array, boolean[][] arrayCounted) {
    if (c < 0) {
        return MAX_PRICE / divide;
    }
    if (i == 0) {
        if (c == 0) {
            return 0;
        } else {
            return MAX_PRICE / divide;
        }
    }

    if (arrayCounted[i][c]) {
        return array[i][c];
    }

    arrayCounted[i][c] = true;
    array[i][c] = Math.min(W(i - 1, c, array, arrayCounted), W(i - 1, c - this.items[i - 1].price/divide, array, arrayCounted) + this.items[i - 1].weight);
    return array[i][c];
}

答案 1 :(得分:0)

如果问题是要通过添加或减去列表/数组的每个元素来找到给定的数字,则

不是NP问题。如果您考虑AP。这是C ++中的示例代码

Chars

这应该有所帮助。我认为。

答案 2 :(得分:0)

我实际上编写了一个简单的Java程序,但实际上我并不了解背包策略。这是我自己的解决方案。希望这会有所帮助

import java.util.ArrayList;
import java.util.List;

public class Puzzle {

    public static void main(String[] args) {

        int targetNumber = 0;
        int min = 2147483647;

        int[] numbers = {-10, -30, -20, -50};
        //int[] numbers = {0,0,0,0};
        //int[] numbers = {7, 2, 10};
        //int[] numbers = {1, 2, 3, 4, 5};
        //int[] numbers = {1000, 2, 3, 4, 100};
        char set[] = {'+', '-'};
        min = getNumberClosestToTarget(numbers, set, min, targetNumber);
        System.out.println(String.format(" %d is closest to %d", min, targetNumber));
    }

    private static int getNumberClosestToTarget(int[] numbers, char[] set, int min, int targetNumber) {

        List<String> operators = new ArrayList<>();

        computeAllOperatorsCombination(set, "", set.length, numbers.length - 1, operators);

        for (String operatorString : operators) {
            String[] ops = operatorString.split("");
            int sum = computeSum(numbers, ops, numbers.length - 1);
            min = getClosestToTarget(min, targetNumber, sum);
        }

        return min;
    }


    static int computeSum(int[] numbers, String[] operators, int index) {

        int result = numbers[index];

        if (index == 0) {
            return result;
        } else {
            switch (operators[index - 1]) {
                case "+":
                    return computeSum(numbers, operators, index - 1) + result;
                case "-":
                    return computeSum(numbers, operators, index - 1) - result;
            }

            return result;
        }
    }

    static void computeAllOperatorsCombination(char set[], String prefix, int n, int k, List<String> result) {
        if (k == 0) {
            result.add(prefix);
            return;
        }

        for (int i = 0; i < n; i++) {
            String newPrefix;
            newPrefix = prefix + set[i];
            computeAllOperatorsCombination(set, newPrefix, n, k - 1, result);
        }
    }

    private static int getClosestToTarget(int min, int targetNumber, int r) {
        int distance = Math.abs(targetNumber - r) < Math.abs(r - targetNumber) ? Math.abs(targetNumber - r) : Math.abs(r - targetNumber);
        if (distance < Math.abs(min)) {
            min = distance;

            if (r < 0) {
                min = -distance;
            }
        }
        return min;
    }
}