最近我试图向某人解释将递归代码转换为迭代是多么“容易”。简单的因子或纤维实例实际上很容易解释。然后我们切换到二叉树,不幸的是我无法用简单的迭代替换替换简单的递归代码。
以下是要替换的代码:
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语句:)
任何想法都非常受欢迎。
答案 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