Java 基于模式生成所有二进制数
给定一个模式,我们需要通过用0和1填充模式中缺失的位置来生成所有可能的二进制数Java 基于模式生成所有二进制数,java,algorithm,Java,Algorithm,给定一个模式,我们需要通过用0和1填充模式中缺失的位置来生成所有可能的二进制数 E.g. Pattern = "x1x"; Output = [010, 110, 011, 111] 我通过创建一个方法calculate解决了这个问题 public static List<String> calculate(String input, int currentIndex) { List<String> result = new ArrayList<Stri
E.g. Pattern = "x1x";
Output = [010, 110, 011, 111]
我通过创建一个方法calculate
解决了这个问题
public static List<String> calculate(String input, int currentIndex) {
List<String> result = new ArrayList<String>();
if(currentIndex > input.length()-1) {
result.add("");
return result;
}
for(String fragment: calculate(input, currentIndex + 1)) {
if(input.charAt(currentIndex)=='x') {
result.add('0' + fragment);
result.add('1' + fragment);
}
else {
result.add(input.charAt(currentIndex) + fragment);
}
}
return result;
}
公共静态列表计算(字符串输入,int currentIndex){
列表结果=新建ArrayList();
如果(currentIndex>input.length()-1){
结果:添加(“”);
返回结果;
}
for(字符串片段:计算(输入,currentIndex+1)){
如果(输入字符(当前索引)='x'){
结果。添加('0'+片段);
结果。添加('1'+片段);
}
否则{
添加(input.charAt(currentIndex)+片段);
}
}
返回结果;
}
我们是否有办法利用给定的模式,设计出更快和/或更干净的解决方案。我已经知道非递归解决方案会更好。Java 8特性也很受欢迎。在反射方面,使用递归和回调是更有效的方法。注意:这将创建很少的对象(可能是3个,而不管结果的数量如何)
publicstaticvoidmain(字符串[]args){
printForPattern(“x1x”,System.out::println);
}
私有静态void printForPattern(字符串模式,使用者){
printForPattern(pattern,new StringBuilder(),consumer);
}
私有静态void printForPattern(字符串模式、StringBuilder sb、使用者){
int length=sb.length();
if(pattern.length()=长度){
接受(某人);
返回;
}
char ch=模式字符(长度);
如果(ch='x'| | ch='0'){
某人附加('0');
printForPattern(pattern,sb,consumer);
某人设定长度(长度);
}
如果(ch='x'| | ch='1'){
某人附加('1');
printForPattern(pattern,sb,consumer);
某人设定长度(长度);
}
}
要将其添加到列表中,您可以执行以下操作
List<String> results = ...
printForPattern("x1x", s -> results.add(x.toString()));
列出结果=。。。
printForPattern(“x1x”,s->results.add(x.toString());
你可以
- 计算通配符或
s的数量。这是需要迭代的位数x
- 迭代2^^{x的个数),这将为那些
提供所有可能的位x
- 将这些生成的
与提供的位模式合并x
公共类主目录{
静态最终类BinaryStringList扩展了AbstractList{
私有最终字符[]字符;
私人最终整数大小;
私有最终StringBuilder sb=新StringBuilder();
BinaryStringList(字符串模式){
chars=pattern.toCharArray();
整数计数=0;
for(char c:chars){
如果(c!=“0”&&c!=“1”&&c!=“x”){
抛出新的IllegalArgumentException();
}
如果(c='x'){
计数++;
如果(计数>30){
抛出新的IllegalArgumentException();
}
}
}
size=(int)Math.pow(2,count);
}
@凌驾
公共整数大小(){
返回大小;
}
@凌驾
公共字符串get(int i){
如果(i<0 | | i>=size){throw new IndexOutOfBoundsException()}
sb.设定长度(0);
int place=0;
for(字符a:字符){
sb.append(a='x'?((i>>place++&1)==0?'0':'1'):a);
}
使某人返回字符串();
}
}
公共静态void main(字符串[]args){
System.out.println(新的二进制字符串列表(“0xx1x”);
}
}
这种方法的优点是实例化一个新的
BinaryStringList
实际上是即时的。只有在您对它进行迭代时,它才真正起作用。如果出现n
字符x
,您可以通过将计数器从0
递增到2^n-1
。然后从计数器中取出一个位,为每个x
决定是否应将其替换为0
或1
因此,该算法的概要如下:
x
的出现次数0
循环到2^n-1
。
x
x
,因为我们在long
中用光了空间。但无论如何,列举超过2^63个解决方案需要非常非常长的时间,所以我认为这不是一个实际问题
代码:
private静态无效枚举位模式(字符串模式){
int len=pattern.length();
int xCount=0;
对于(int-iChar=0;iChar=1;
}否则{
附加(ch);
}
}
System.out.println(生成器);
}
}
尽管递归无疑更加优雅,但编写一个函数也很容易,它接受一个模式和一个二进制字符串,并根据该模式生成下一个二进制字符串。然后,您只需要从通过将模式中的所有x
更改为0
s而创建的字符串开始,并迭代后续字符串,直到找到一个没有的字符串
要查找给定模式的字符串的后续项,请向后遍历字符串和模式。在每个字符位置:
- 如果模式字符是
:x
- 如果字符串是
,请将其更改为1
0
- 如果字符串小于c
List<String> results = ... printForPattern("x1x", s -> results.add(x.toString()));
public class Main { static final class BinaryStringList extends AbstractList<String> { private final char[] chars; private final int size; private final StringBuilder sb = new StringBuilder(); BinaryStringList(String pattern) { chars = pattern.toCharArray(); int count = 0; for (char c : chars) { if (c != '0' && c != '1' && c != 'x') { throw new IllegalArgumentException(); } if (c == 'x') { count++; if (count > 30) { throw new IllegalArgumentException(); } } } size = (int) Math.pow(2, count); } @Override public int size() { return size; } @Override public String get(int i) { if (i < 0 || i >= size) { throw new IndexOutOfBoundsException(); } sb.setLength(0); int place = 0; for (char a : chars) { sb.append(a == 'x' ? ((i >> place++ & 1) == 0 ? '0' : '1') : a); } return sb.toString(); } } public static void main(String[] args) { System.out.println(new BinaryStringList("0xx1x")); } }
private static void enumBitPatterns(String pattern) { int len = pattern.length(); int xCount = 0; for (int iChar = 0; iChar < len; ++iChar) { if (pattern.charAt(iChar) == 'x') { ++xCount; } } StringBuilder builder = new StringBuilder(len); long enumCount = 1L << xCount; for (long iEnum = 0; iEnum < enumCount; ++iEnum) { builder.delete(0, len); long val = iEnum; for (int iChar = 0; iChar < len; ++iChar) { char ch = pattern.charAt(iChar); if (ch == 'x') { builder.append((char)('0' + (val & 1))); val >>= 1; } else { builder.append(ch); } } System.out.println(builder); } }
- 如果字符串是