package com.interview.books.ccinterview; /** * Created_By: stefanie * Date: 14-12-13 * Time: 上午11:45 */ public class CC5_ThreeStackFlexible { static 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 totalSize){ if(start <= index && index <= start + capacity) return true; else if(start + capacity > totalSize && index < (start + capacity) % totalSize) return true; return false; } } int stackCount; int defaultSize; int totalSize; StackData[] stacks; int[] buffer; public CC5_ThreeStackFlexible(int count, int capacity){ this.stackCount = count; this.defaultSize = capacity; this.totalSize = defaultSize * stackCount; this.stacks = new StackData[]{ new StackData(0, defaultSize), new StackData(defaultSize, defaultSize), new StackData(defaultSize * 2, defaultSize) }; this.buffer = new int[totalSize]; } public void push(int stackIdx, int value) throws Exception { StackData stack = stacks[stackIdx]; if(stack.size >= stack.capacity){ if(numberOfElements() >= totalSize){ throw new Exception("Out of space"); } else { expand(stackIdx); } } stack.size++; stack.pointer = nextElement(stack.pointer); buffer[stack.pointer] = value; } public int pop(int stackIdx) throws Exception { StackData stack = stacks[stackIdx]; if(stack.size == 0){ throw new Exception("Empty Stack"); } int value = buffer[stack.pointer]; buffer[stack.pointer] = 0; stack.pointer = previousElement(stack.pointer); stack.size--; return value; } public int peek(int stackIdx) throws Exception { StackData stack = stacks[stackIdx]; if(stack.size == 0){ throw new Exception("Empty Stack"); } return buffer[stack.pointer]; } public boolean isEmpty(int stackIdx){ StackData stack = stacks[stackIdx]; return stack.size == 0; } private int numberOfElements(){ int total = 0; for(int i = 0; i < stacks.length; i++) total += stacks[i].size; return total; } private int nextElement(int index){ if(index + 1 == totalSize) return 0; return index + 1; } private int previousElement(int index){ if(index == 0) return totalSize - 1; else return index - 1; } private void shift(int stackIdx){ StackData stack = this.stacks[stackIdx]; if(stack.size >= stack.capacity){ int nextStack = (stackIdx + 1) % stackCount; shift(nextStack); stack.capacity++; } for(int i = (stack.start + stack.capacity - 1) % totalSize; stack.isWithinStack(i, totalSize); i = previousElement(i)){ buffer[i] = buffer[previousElement(i)]; } buffer[stack.start] = 0; stack.start = nextElement(stack.start); stack.pointer = nextElement(stack.pointer); stack.capacity--; } private void expand(int stackIdx){ shift((stackIdx + 1) % stackCount); stacks[stackIdx].capacity++; } public static void main(String[] args) throws Exception { CC5_ThreeStackFlexible stack = new CC5_ThreeStackFlexible(3, 2); stack.push(0, 1); stack.push(0, 2); stack.push(0, 3); stack.push(1, 1); stack.push(2, 1); stack.push(2, 2); try{ stack.push(2, 3); } catch (Exception e) { e.printStackTrace(); } System.out.println(stack.isEmpty(0)); System.out.println(stack.isEmpty(1)); System.out.println(stack.isEmpty(2)); System.out.println(stack.pop(2)); System.out.println(stack.pop(0)); System.out.println(stack.pop(0)); System.out.println(stack.pop(1)); try{ System.out.println(stack.pop(1)); } catch (Exception e) { e.printStackTrace(); } } }