插入加号时查找数字的所有组合

时间:2017-10-02 04:38:54

标签: java algorithm recursion

我正在研究练习算法问题,似乎无法解决这个问题。我给的是1234这样的数字。在向其中添加+符号时,我需要找到该数字的不同组合。答案中可以有多个加号。因此结果看起来像1+2341+2+3412+34等。我知道如何找到不同的子字符串,但不知道如何添加它们。这就是我所拥有的:

public static void findCombos(String string){
    List<String> substrings = new ArrayList<>();
    for( int i = 0 ; i < string.length() ; i++ )
    {
        for( int j = 1 ; j <= string.length() - i ; j++ )
        {
            String sub = string.substring(i, i+j);
            substrings.add(sub);
        }
    }
    System.out.println(substrings);
}

如果将数字转换为字符串,则只存储不同的子字符串。我如何将这些组合在一起以创建正确的字符串。我正在考虑使用前缀进行递归,但无法做到这一点。

这与排列问题不同,因为我被要求以相同的顺序保留数字,但是将+添加到其中。

1 个答案:

答案 0 :(得分:1)

您希望生成参数arg的所有可能分区。 参数arg可以分为arg.length - 1个点。 这里我使用布尔数组(divisors[N])来记住您是否要在字符arg[N]arg[N + 1]之间进行拆分。 在递归流程中生成divisors数组的所有可能版本 - 当您到达结束时,然后执行字符串除法,并保存结果。

public static void cover(final String arg) {
    final List<Set<String>> result = new ArrayList<>();

    final boolean[] divisors = new boolean[arg.length() - 1];
    processDivisors(divisors, 0, arg, result);

    System.out.println(result);
    // now the result contains the divisions, we can do something with it
    doSomethingWithResult(result);
}

private static void processDivisors(final boolean[] divisors,
                                    final int position,
                                    final String arg,
                                    /* out */ final List<Set<String>> result) {

    if (position == arg.length() - 1) {
        final Set<String> computedDivision = computeDivision(arg, divisors);
        result.add(computedDivision);
        return;
    }
    divisors[position] = true;
    processDivisors(divisors, position + 1, arg, result);
    divisors[position] = false;
    processDivisors(divisors, position + 1, arg, result);
}

private static Set<String> computeDivision(final String arg, final boolean[] divisors) {
    final Set<String> computedDivision = new TreeSet<>();
    int start = 0;
    for (int i = 0; i < divisors.length; ++i) {
        if (divisors[i]) {
            computedDivision.add(arg.substring(start, i + 1));
            start = i + 1;
        }
    }
    computedDivision.add(arg.substring(start, arg.length()));
    return computedDivision;
}

private static void doSomethingWithResult(final List<Set<String>> result) {
    for (final Set<String> coverage : result) {
        final String message = String.join("+", coverage);
        System.out.println(message);
    }
}

我坚信这段代码并不完美,可以某种方式进行优化。 顺便说一句。如果在进行除法时需要执行任何额外操作,则可以修改computeDivison方法。但肯定不会使用该部分进行打印 - 首先生成输出,然后在不同的代码段中进行处理会更明智。