Cracking the Coding Interview Q3.1

Describe how you could use a single array to implement three stacks. 

 

思路1:fixed division

package Question3_1;

import java.util.EmptyStackException;

public class Question {
    static int stackSize = 10;
    static int [] buffer = new int [stackSize * 3];
    
    // 3 stack pointers to keep track of the index of the top element
    static int [] stackPointer = {-1, -1, -1};
    public static void main(String [] args) throws Exception  {
        push(2, 4);
        System.out.println("Peek 2: " + peek(2));
        push(0, 3);
        push(0, 7);
        push(0, 5);
        System.out.println("Peek 0: " + peek(0));
        pop(0);
        System.out.println("Peek 0: " + peek(0));
        pop(0);
        System.out.println("Peek 0: " + peek(0));
    }

    static void push(int stackNum, int value) throws Exception {
        /* Check that we have space for the next element */
        if (stackPointer[stackNum] + 1 >= stackSize) { 
            throw new FullStackException();
        }
        /* Increment stack pointer and then update top value*/        
        stackPointer[stackNum]++;
        buffer[absTopOfStack(stackNum)] = value;    
    }

    static int pop(int stackNum) throws Exception {
        if (isEmpty(stackNum)) {
            throw new EmptyStackException();
        }
        int value = buffer[absTopOfStack(stackNum)]; // Get top
        buffer[absTopOfStack(stackNum)] = 0; // Clear index
        stackPointer[stackNum]--; // Decrement pointer
        return value;
    }

    static int peek(int stackNum) {
        if (isEmpty(stackNum)) {
            throw new EmptyStackException();
        }        
        return buffer[absTopOfStack(stackNum)];
    }

    static boolean isEmpty(int stackNum) {
        return stackPointer[stackNum] == -1;
    }
    
    /* returns index of the top of the stack "stackNum", in absolute terms */
    static int absTopOfStack(int stackNum) {
        return stackNum * stackSize + stackPointer[stackNum];
    }    
}

 

思路2:

package Question3_1;

import CtCILibrary.AssortedMethods;

public class QuestionB {
    static int number_of_stacks = 3;
    static int default_size = 4;
    static int total_size = default_size * number_of_stacks;
    static StackData [] stacks = {new StackData(0, default_size), 
                                     new StackData(default_size, default_size), 
                                     new StackData(default_size * 2, default_size)};
    static int [] buffer = new int [total_size];

    public static void main(String [] args) throws Exception  {
        push(0, 10);
        push(1, 20);
        push(2, 30);
        
        push(1, 21);
        push(0, 11);
        push(0, 12);
        
        pop(0);
        
        push(2, 31);
        
        push(0, 13);
        push(1, 22);
        
        push(2, 31);
        push(2, 32);
        push(2, 33);
        push(2, 34);

        System.out.println("Final Stack: " + AssortedMethods.arrayToString(buffer));
        
        pop(1);
        push(2, 35);
        
        System.out.println("Final Stack: " + AssortedMethods.arrayToString(buffer));
    }
    
    public static int numberOfElements() {
        return stacks[0].size + stacks[1].size + stacks[2].size;
    }
    
    public static int nextElement(int index) {
        if (index + 1 == total_size) {
            return 0;
        } else {
            return index + 1;
        }
    }
    
    public static int previousElement(int index) {
        if (index == 0) {
            return total_size - 1;
        } else {
            return index - 1;
        }
    }
    
    public static void shift(int stackNum) {
        StackData stack = stacks[stackNum];
        if (stack.size >= stack.capacity) {
            int nextStack = (stackNum + 1) % number_of_stacks;
            shift(nextStack); // make some room
            stack.capacity++;
        }
        for (int i = (stack.start + stack.capacity - 1) % total_size; // end of array
                      stack.isWithinStack(i, total_size); 
                      i = previousElement(i)) {
            buffer[i] = buffer[previousElement(i)];
        }
        buffer[stack.start] = 0;
        stack.start = nextElement(stack.start); // move start start
        stack.pointer = nextElement(stack.pointer); // move stack pointer
        stack.capacity--; // return capacity to original
    }
    
    /* Expand stack by shifting over other stacks */
    public static void expand(int stackNum) {
        shift((stackNum + 1) % number_of_stacks);
        stacks[stackNum].capacity++;
    }

    static void push(int stackNum, int value) throws Exception {
        StackData stack = stacks[stackNum];
        /* Check that we have space */
        if (stack.size >= stack.capacity) {
            if (numberOfElements() >= total_size) { // Totally full
                throw new Exception("Out of space."); 
            } else { // just need to shift things around
                expand(stackNum);
            }
        }
        /* Find the index of the top element in the array + 1, 
         * and increment the stack pointer */    
        stack.size++;
        stack.pointer = nextElement(stack.pointer);        
        buffer[stack.pointer] = value;    
    }

    static int pop(int stackNum) throws Exception {
        StackData stack = stacks[stackNum];        
        if (stack.size == 0) {
            throw new Exception("Trying to pop an empty stack.");
        }
        int value = buffer[stack.pointer];
        buffer[stack.pointer] = 0;
        stack.pointer = previousElement(stack.pointer);
        stack.size--;
        return value;
    }

    static int peek(int stackNum) {
        StackData stack = stacks[stackNum];            
        return buffer[stack.pointer];
    }

    static boolean isEmpty(int stackNum) {
        StackData stack = stacks[stackNum];
        return stack.size == 0;
    }
}


package Question3_1;

public class StackData {
    public int start;
    public int pointer;
    public int size = 0;
    public int capacity;
    public StackData(int _start, int _capacity) {
        start = _start;
        pointer = _start - 1;
        capacity = _capacity;
    }
    
    public boolean isWithinStack(int index, int total_size) {
        // Note: if stack wraps, the head (right side) wraps around to the left. 
        if (start <= index && index < start + capacity) { 
            // non-wrapping, or "head" (right side) of wrapping case
            return true;
        } else if (start + capacity > total_size && 
                   index < (start + capacity) % total_size) {
            // tail (left side) of wrapping case
            return true;
        }
        return false;
    }
}

 

posted @ 2014-08-09 21:41  jdflyfly  阅读(267)  评论(0编辑  收藏  举报