【问题标题】:Replacing String in Java to get all variations在 Java 中替换字符串以获取所有变体
【发布时间】:2019-11-23 20:17:20
【问题描述】:

早安,

我正在尝试打印某个字符串的所有变体。例如,我们有这个输入:AB0C0。第 3 和第 5 位的 0 应视为变量。可变字符是 1、2、3,将被放置在 0 的位置。这意味着,这些将是此输入的所有可能变化:

  1. AB1C1
  2. AB2C1
  3. AB3C1
  4. AB1C2
  5. AB1C3
  6. AB2C2
  7. AB2C3
  8. AB3C2
  9. AB3C3

这只是一个例子。在 5 个字符的长字符串中放置 1 到 5 个变量。我面临的问题是,无论输入中有多少变量,无论它们在哪里,它都应该生成所有变体。

Scanner scanner = new Scanner (System.in);
System.out.println("Enter the key consisting of 5 characters:");
String input = scanner.next();
String strOutput1 = input.replaceFirst("0","1");
String strOutput1A = input.replace("0","1");
String strOutput2 = input.replaceFirst("0","2");
String strOutput3 = input.replaceFirst("0","3");
String strOutput4 = input.replaceFirst("0","4");
String strOutput5 = input.replaceFirst("0","5");
System.out.println(strOutput1.toUpperCase());
System.out.println(strOutput1A.toUpperCase());
System.out.println(strOutput2.toUpperCase());
System.out.println(strOutput3.toUpperCase());
System.out.println(strOutput4.toUpperCase());
System.out.println(strOutput5.toUpperCase());

热烈欢迎任何建议。

【问题讨论】:

  • 基于您的示例中分配了值 1,2 和 3 的变量是什么?因为字符串中的已知字符数是 3?即A、B、C?
  • @MarwaEldawy 0 是应从输入中检测到的变量。所以 A、B 和 C 是已知的,不应更改。再举个例子:A00BC,我们同样有 9 种不同的组合,分别是数字 1、2 和 3:A11BC、A12BC、A13BC、A21BC、A22BC、A23BC、A31BC、A32BC、A33BC。
  • 我理解这个例子。我的问题是:如果我们有这样的字符串:A00BCDE。 00 应该取什么值? 1,2和3也?这个例子怎么样: A0000 ? 0000 应该取什么值?
  • 或者你的意思是字符串总是包含 5 个字符,有 2 个变量?
  • @MarwaEldawy 总是有 5 个字符可以有 1 到 4 个零,需要用我们的值替换,它们总是 1、2、3。通过数学,我们得到两个变量3^2=9 组合,3 个变量我们得到 3^3=27 个组合,4 个变量我们得到 3^4=81 个组合。

标签: java string replace variations


【解决方案1】:

这个呢:

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

public class Main {

public static void main(String[] args) throws Exception {
    Scanner scanner = new Scanner(System.in);
    System.out.println("Enter the key consisting of 5 characters:");
    String input = scanner.next();

    //find positions of '0' in input
    List<Integer> varPositions = findVarPositions(input);

    //create permutations
    List<String> permutations = new ArrayList<>();
    permutations.add(input);//AB0C0
    for (int position : varPositions) {
        permutations = permutateAtPosition(permutations, position);
    }

    //print permutations
    for (String permutation : permutations) {
        System.out.println(permutation.toUpperCase());
    }
}

private static List<Integer> findVarPositions(String input) {
    List<Integer> varPositions = new ArrayList<>();
    int lastVarPosition = -1;
    while ((lastVarPosition = input.indexOf('0', lastVarPosition + 1)) != -1) {
        varPositions.add(lastVarPosition);
    }
    return varPositions;
}

private static List<String> permutateAtPosition(List<String> partialyPermutated, int position) {
    List<String> result = new ArrayList<>();
    char[] replacements = {'1', '2', '3', '4', '5'};
    for (String item : partialyPermutated) {
        for (int i = 0; i < replacements.length; i++) {
            String output = replaceCharAt(item, position, replacements[i]);
            result.add(output);
        }
    }
    return result;
}

private static String replaceCharAt(String input, int position, char replacement) {
    //converting to char array, because there's no method like
    //String.replaceAtPosition(position, char)
    char[] charArray = input.toCharArray();
    charArray[position] = replacement;
    return new String(charArray);
}

}

它不固定于变量的数量。

这个想法是提取'0'的位置,然后调用permutateAtPosition方法,该方法采用部分排列的列表并将其再排列一层。

对于“a0b0c0”和值 1-2,它将是 ['a0b0c0'],然后是 ['a1b0c0','a2b0c0'],然后是 ['a1b1c0','a1b2c0','a2b1c0','a2b2c0' ],最后是 ['a1b1c1','a1b1c2','a1b2c1','a1b2c2','a2b1c1','a2b1c2','a2b2c1''a2b2c2']。

此解决方案将所有内容保存在内存中,因此在一般情况下(无限输入字符串),使用深度优先会更明智。

【讨论】:

  • 完美地完成了这项工作。非常感谢!
【解决方案2】:

我为您准备了另一个解决方案。 第一步,获取变量的数量:

int variableCount = 0;
for (int i = 0; i < 5; i++) {
    if (input.charAt(i) == '0') {
        variableCount++;
    }
}

然后计算我们期望的结果数量:

int countMax = (int)Math.pow(4,variableCount);

最后,以4为底数。用0填充数字并替换原始输入的0:

for (int i = 0; i < countMax; i++) {
    String paddedNumbers = format("%" + variableCount + "s",Integer.toString(i, 4)).replace(" ", "0");
    int replacedCount = 0;
    char[] outputChars = input.toCharArray();
    for (int j = 0; j < 5; j++) {
        if (input.charAt(j) == '0') {
            outputChars[j] = paddedNumbers.charAt(replacedCount);
            replacedCount++;
        }
    }
    System.out.println(outputChars);
}

【讨论】:

  • 感谢您的发帖。我真的很喜欢这个概念,因为它可以用于更多情况。您能否进一步详细说明如何处理最后一个字符串中定义的“格式”?我在代码中没有看到对它的其他引用。
  • 是的,它是 String.format()。它所做的是格式化字符串并将变量输入到该字符串。在这种情况下,我使用填充函数在实际数字前面添加空格,因此如果 variableCount 为 2,则“3”变为“3”。这些空格随后被 0 替换。所以它变成了“03”。
猜你喜欢
  • 2013-12-31
  • 2022-08-17
  • 2012-09-05
  • 2013-03-16
  • 2020-08-24
  • 1970-01-01
  • 1970-01-01
  • 2017-03-23
  • 2013-01-04
相关资源
最近更新 更多