没有堆栈和goto的迭代递归 - 只是一个理论练习

时间:2017-02-25 20:05:17

标签: algorithm recursion

最近我试图向某人解释将递归代码转换为迭代是多么“容易”。简单的因子或纤维实例实际上很容易解释。然后我们切换到二叉树,不幸的是我无法用简单的迭代替换替换简单的递归代码。

以下是要替换的代码:

public class Test {
public static void bincR2(int i,int k, String buff) {
    if(i<k) {
        bincR2(i+1,k,buff + '0');
        bincR2(i+1,k,buff + '1');
    }
    else { 
        System.out.println(buff);
    }
}    

public static void bincI(int k, String buff) {
// ????
}   

public static void main(String[] args) {
    int n = 3;
    String b = "";
    bincR2(0,n, b);     
    bincI(n, b);

}   
}

结果应该打印出从0到2 ^ n-1的所有数字的二进制表示。对于n = 3,显然它是: 000 001 010 011 ... 111

当然,我可以在循环中生成这样一组字符串,从简单的字符串格式化到移动数字和检查最后一位,有几种不同的方式。但我正在寻找尽可能接近递归方法的解决方案。我不想使用自己的堆栈和“goto”语句或任何高级字符串方法,只是循环,条件和变量 - 它必须以某种方式可能,如此处的几个线程中所述。选择Java是因为没有goto语句:)

任何想法都非常受欢迎。

2 个答案:

答案 0 :(得分:1)

嗯,你需要产生2 ^ n个值。只有没有递归的循环你就无法得到任何超过多项式复杂性的东西(你可以吗?除非你迭代到n中不是多项式的东西,但是你不是模仿递归解决方案,不是吗?),所以我担心你需要弥补空间复杂性 - 如下所示,但这有点作弊,因为它仍然“实现自己的堆栈”。我有兴趣知道自己更好的解决方案。

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

class Main {

    public static void main(String[] args) {

        int N = 4;

        List<String> result = new ArrayList<>();
        result.add("");

        for (int i = 0; i < N; i++) {
            List <String> tmp = new ArrayList<>();
            for (String str : result) {
                tmp.add(str + "0");
                tmp.add(str + "1");
            }
            result = tmp;
        }

        for (String str : result) {
            System.out.println(str);
        }

    }
}

在评论此答案之前,请确保您了解问题,而不仅仅是生成所有二进制字符串。

答案 1 :(得分:1)

当然,这可以通过两个循环模仿递归作为频率的表达来完成:从2^(k-1)2^0的外循环和从0到{{的内循环1}}。保留一个与外循环相对应的计数器变量,用于标记循环长度。每次循环完成后,从附加&#34; 0&#34; s切换到追加&#34; 1&#34; s。

例如,2^k - 1

k = 3, Array length = 2^3 = 8, Cycles = 2^2, 2^1, 2^0