13 February 2019

Fibnaci

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);
    }

}



blog comments powered by Disqus
Flag Counter