Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/spring-mvc/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 基于模式生成所有二进制数_Java_Algorithm - Fatal编程技术网

Java 基于模式生成所有二进制数

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

给定一个模式,我们需要通过用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<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());

你可以

  • 计算通配符或
    x
    s的数量。这是需要迭代的位数
  • 迭代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
  • 输出结果
  • 这被限制在63次出现
    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);
            }
        }