package com.test;
import java.util.Stack;
public class FibnaciStack {
public static <T> void printStack(Stack<T[]> stack) {
System.out.println("STACK:BEGIN");
int STACK_SIZE = stack.size();
System.out.println("b,s,n");
for (int i = STACK_SIZE; i > 0; i--) {
T[] objs = stack.get(i - 1);
for (T obj : objs) {
System.out.print(obj + ",");
}
System.out.println();
}
System.out.println("STACK:END");
}
public static void c2(int n) {
long s = 0, rt = 0;
int branch = 0;
Stack<Object[]> stack = new Stack<>();
while (true) {
if (n < 2) {
// this will goto last one, as nothing to operate
// pop next things to operate, define $rt as last result in {0,1}
// we have the result, there is no need for current stack.
rt = n;
System.out.println("Print $$n<2, n=" + n);
} else {
switch (branch) {
// Push F(n), F(n-2), F(n-2-2)
// TODO STEP1 压栈操作
case 0: {
do {
stack.push(new Object[]{branch, 0l, n});
n -= 2;
} while (n >= 2);
System.out.print("branch=0,");
printStack(stack);
System.out.println("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$");
continue;
}
// F(n+1) = F(n) + F(n-1)
// Push F(n) and handle F(n-1)
// TODO STEP2 保留 $rt 结果,F(n) 分支压栈; F(n-1) 到 $branch0 再压栈
// $branch=1 的情况就是有 $rt 中间结果
case 1: {
// push the F(n):
// 1. $branch will be 2 when (n--) <=2 in next step;(Refer TODO $2)
// 2. Otherwise $branch will remain 0 for stack push(Refer TODO $1)
// 最终结果还是保留在了 $s=$rt,中间结果
stack.push(new Object[]{branch, rt, n});
// process F(n-1):
// Goto $BRANCH=0 if (n--)>=2 ;
// Otherwise goto n<2 and then go to TODO $$Popup;
n--;
// goto branch0,将 n-- 结果压栈
// TODO $1
branch = 0;
System.out.print("branch=1,");
printStack(stack);
System.out.println("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$");
continue;
}
/** TODO STEP3 更新当前 $rt:
*
* 1. n >=2 时, $rt 下次直接被保留 到 $branch1 压栈
* 2. n < 2 时,$rt 会被跟新 $rn = n
*/
case 2: {
// 1. calc rs til now in one F(n),calc from $BRANCH=1, $BRANCH++
// we have the result, there is no need for current stack.
// 2. Stack will be popup, if the popped $branch==1, we
// will be here again
System.out.println("We have the previous Result!!");
rt += s;
break;
}
default:
break;
}
}
if (stack.isEmpty()) {
System.out.println("Result is :" + rt);
return;
}
// TODO $$Popup
/**
* TODO STEP4 弹出操作栈
* 1. 弹出 branch0 ->1 下次操作保留 TODO $rt;
* 2. 弹出 branch1 ->2 下次操作更新 TODO $rt+=s;
*/
Object[] t = stack.pop();
branch = (Integer) t[0];
s = (Long) t[1];
n = (Integer) t[2];
System.out.println("POPUP Branch=" + branch + " s=" + s + " n=" + n + " rt=" + rt);
printStack(stack);
System.out.println("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$");
// TODO $2
branch++;
}
}
public static void main(String[] args) {
c2(6);
}
}