如何解决通过替换隐藏的“#”数字符号生成所有可能的字符串组合
我的任务是生成没有隐藏的 #
数字符号的行的所有可能组合。输入是 XOXX#OO#XO
,下面是输出应该是什么的例子:
XOXXOOOOXO
XOXXOOOXXO
XOXXXOOOXO
XOXXXOOXXO
我只能迭代地解决这个解决方案,我不知道如何解决这个问题,我已经研究了这个代码一周了。
这是我的代码:
import java.lang.Math;
public class help {
public static void main(String[] args) {
String str = new String("XOXX#OO#XO");
UnHide(str);
}
public static void UnHide(String str) {
//converting string to char
char[] chArr = str.toCharArray();
//finding all combinations for XO
char[] xo = new char[]{'X','O'};
int count = 0;
char perm = 0;
String s = "";
//finding amount of times '#' appears in string
for (int i = 0; i < str.length(); i++) {
if (chArr[i] == '#')
count++;
}
int[] combo = new int[count];
int pMax = xo.length;
while (combo[0] < pMax) {
// print the current permutation
for (int k = 0; k < count; k++) {
//print each character
//System.out.print(xo[combo[i]]);
perm = xo[combo[k]];
s = String.valueOf(perm);
char[] xoArr = s.toCharArray();
String strChar = new String(xoArr);
//substituting '#' to XO combo
for (int i = 0; i < chArr.length; i++) {
for (int j = 0; j < s.length(); j++) {
if (chArr[i] == '#') {
chArr[i] = xoArr[j];
strChar = String.copyValueOf(chArr);
i++;
}
}
i++;
if (i == chArr.length - 1) {
System.out.println(strChar);
i = 0;
}
}
}
System.out.println(); //print end of line
// increment combo
combo[count - 1]++; // increment the last index
//// if increment overflows
for (int i = count - 1; combo[i] == pMax && i > 0; i--) {
combo[i - 1]++; // increment previous index
combo[i] = 0; // set current index to zero
}
}
}
}
解决方法
由于您的输入有 2 个#,因此有 2n = 4 个排列。
如果从 0 数到 3,并查看二进制数,则会得到 00
、01
、10
和 11
,因此如果您使用也就是说,为 O
插入 0
和为 X
插入 1
,您可以使用简单的循环来做到这一点。
public static void unHide(String str) {
int count = 0;
for (int i = 0; i < str.length(); i++)
if (str.charAt(i) == '#')
count++;
if (count > 30)
throw new IllegalArgumentException("Too many #'s found. " + count + " > 30");
char[] buf = str.toCharArray();
for (int permutation = 0,end = 1 << count; permutation < end; permutation++) {
for (int i = buf.length - 1,bit = 0; i >= 0; i--)
if (str.charAt(i) == '#')
buf[i] = "OX".charAt(permutation >>> bit++ & 1);
System.out.println(buf);
}
}
测试
unHide("XOXX#OO#XO");
输出
XOXXOOOOXO
XOXXOOOXXO
XOXXXOOOXO
XOXXXOOXXO
,
您可以迭代使用 streams
生成所有可能的字符串组合,如下所示:
public static String[] unHide(String str) {
// an array of substrings around a 'number sign'
String[] arr = str.split("#",-1);
// an array of possible combinations
return IntStream
// iterate over array indices
.range(0,arr.length)
// append each substring with possible
// combinations,except the last one
// return Stream<String[]>
.mapToObj(i -> i < arr.length - 1 ?
new String[]{arr[i] + "O",arr[i] + "X"} :
new String[]{arr[i]})
// reduce stream of arrays to a single array
// by sequentially multiplying array pairs
.reduce((arr1,arr2) -> Arrays.stream(arr1)
.flatMap(str1 -> Arrays.stream(arr2)
.map(str2 -> str1 + str2))
.toArray(String[]::new))
.orElse(null);
}
// output to the markdown table
public static void main(String[] args) {
String[] tests = {"XOXX#OOXO","XOXX#OO#XO","#XOXX#OOXO#","XO#XX#OO#XO"};
String header = String.join("</pre> | <pre>",tests);
String matrices = Arrays.stream(tests)
.map(test -> unHide(test))
.map(arr -> String.join("<br>",arr))
.collect(Collectors.joining("</pre> | <pre>"));
System.out.println("| <pre>" + header + "</pre> |");
System.out.println("|---|---|---|---|");
System.out.println("| <pre>" + matrices + "</pre> |");
}
XOXX#OOXO |
XOXX#OO#XO |
#XOXX#OOXO# |
XO#XX#OO#XO |
---|---|---|---|
XOXXOOOXO |
XOXXOOOOXO |
OXOXXOOOXOO |
XOOXXOOOOXO |
该过程可能最好计算排列数,然后遍历每个排列以定义要使用的字符组合。
为此,我们必须将置换数除以与我们要替换的字符的索引相关的某个值,该值将作为要交换到的字符的索引。
public static void test(String word) {
// Should be defined in class (outside method)
String[] replaceChars = {"O","X"};
char replCharacter = '#';
String temp;
int charIndex;
int numReplaceable = 0;
// Count the number of chars to replace
for (char c : word.toCharArray())
if (c == replCharacter)
numReplaceable++;
int totalPermutations = (int) Math.pow(replaceChars.length,numReplaceable);
// For all permutations:
for (int permNum = 0; permNum < totalPermutations; permNum++) {
temp = word;
// For each replacement character in the word:
for (int n = 0; n < numReplaceable; n++) {
// Calculate the character to swap the nth replacement char to
charIndex = permNum / (int) (Math.pow(replaceChars.length,n))
% replaceChars.length;
temp = temp.replaceFirst(
replCharacter + "",replaceChars[charIndex]);
}
System.out.println(temp);
}
}
哪些可以产生:
java Test "#TEST#"
OTESTO
XTESTO
OTESTX
XTESTX
这也可以用于任意数量的字符,只需在 replaceChars
中添加更多字符即可。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。