扩展的递归方法不关心二进制数

时间:2013-03-20 00:38:26

标签: java algorithm recursion

我正在尝试编写一个将“---”之类的输入转换为000,001,010,011,100,101,110和111的函数。另一个例子是“1--” - > 100101110111。到目前为止,这是我的代码,但它只是产生了一些解决方案:

static void expandPLA(char[]plaRow){
        boolean sawDontCare=false;
        for(int x = 0; x< plaRow.length; x++){
            if(plaRow[x]=='-'){
                sawDontCare=true;
                plaRow[x]='0';
                expandPLA(plaRow);
                plaRow[x]='1';
                expandPLA(plaRow);
            }
        }
        if(!sawDontCare)
            arrayList.add(plaRow);    
    }

arrayList保存输出值。有谁看到了什么问题?

3 个答案:

答案 0 :(得分:2)

我为您创建了一个示例实现,它打印了一个如上所示的值列表。当然,你可以做任何你喜欢的事情来代替打印到控制台:

import java.util.*;
import java.lang.*;

class Main {

    public static void expandPLA(char[] pla) {

        // How many don't cares are we handling
        int empties = 0;
        for (int i = 0; i < pla.length; i++) {
            if (pla[i] == '-') { empties++; }
        }

        // Now we know we're counting from 0 to 2^empties in binary
        for (int j = 0; j < Math.pow(2,empties); j++) {

            // For each value of j we're going to create a new string pattern
            // and fill in each don't care with the correct digit of j
            String pattern = String.copyValueOf(pla);
            String bin = Integer.toBinaryString(j);

            // Pad bin with zeros
            int pad = empties - bin.length();
            for (int z = 0; z < pad; z++) {
                bin = "0" + bin;
            }

            // For each empty spot we're going to replace a single '-' with
            // the next most significant digit
            for (int k = 0; k < empties; k++) {
                char digit = bin.charAt(k);
                pattern = pattern.replaceFirst("-", String.valueOf(digit));
            }

            // We're just going to print this out for now, but you can do
            // whatever it is you want at this point.
            System.out.println(pattern);

        }

    }

    public static void main (String[] args) throws java.lang.Exception {
        Main.expandPLA(new char [] { '1', '-', '-', '1', '-', '1', '-', '-' });
    }

}

注意:我上面的算法可能会收紧很多。我懒得知道如何用0填充二进制数字,并且有可能有更好的方法将我的数字输入到不关心空间而不是字符串替换。认为这是一个概念证明,可以更多的记忆和时间效率,但我相信它优于递归。

答案 1 :(得分:0)

如果您真的想要递归,那么这样的事情应该有效:

static final char[] digits = new char[]{'0','1'};

private void expandPLA(char[] plaRow, char[] value, int x) {
    if (x == plaRow.length) {
        arrayList.add(value);
        return;
    }
    if (plaRow[x] == '-') {
        for (char digit : digits) {
            value[x] = digit;
            expandPLA(plaRow, value, x + 1);
        }
    } else {
        value[x] = plaRow[x];
        expandPLA(plaRow, value, x + 1);
    }
}

答案 2 :(得分:0)

它是递归的,但它不是Java。

(define (expand-pla code)
  (define (cons-of x) (lambda (l) (cons x l)))
  (define cons-1 (cons-of #\1))
  (define cons-0 (cons-of #\0))

  (map list->string
       (let building ((codes  (string->list code)))
         (if (null? codes)
             (list '())
             (let ((rest (building (cdr codes))))
               (case (car codes)
                 ((#\0) (map cons-0 rest))
                 ((#\1) (map cons-1 rest))
                 ((#\-) (append (map cons-0 rest)
                                (map cons-1 rest)))))))))

也许你会发现它很有趣。并且,它的工作原理:

> (expand-pla "1--")
("100" "101" "110" "111")

这是一个尾递归版本。

(define (expand-pla code)
  (define (cons-of x) (lambda (l) (cons x l)))
  (define cons-1 (cons-of #\1))
  (define cons-0 (cons-of #\0))
  (define (compose f g) (lambda (x) (f (g x))))

  (let building ((codes (string->list code)) (result (list '())))
    (if (null? codes)
        (map (compose list->string reverse) result)
        (building (cdr codes)
                  (case (car codes)
                    ((#\0) (map cons-0 result))
                    ((#\1) (map cons-1 result))
                    ((#\-) (append (map cons-0 result)
                                   (map cons-1 result))))))))