栈队串

来源:互联网 发布:ntp 端口 编辑:程序博客网 时间:2024/06/05 18:23
1、栈和队也是线性表,不过是对它们的操作进行了限制,都可能顺序和链式存储结构实现
2、栈是先进后出,队是先进先出。
3、进制的转换,10进制转成其它进制的一个公式 是
     10进制mod其它,在div其它  ,把mod 的余数存起,

     把div的结果不断得div其它直到为0,这个过程中mod的数最后反过来就是对应的进制结果

     基本实现:

    

  public class DigitalChange{

privateLinkedStackstack;

public DigitalChange() {

stack = new LinkedStack();

}

/**

* @param g 要转换的10进制数

* @param digit  要转换成什么进制的 

* @return

*/

public long getRs(int g,int digit) {

while(g/digit>0) {

stack.push(g%digit);

g = g/digit;

}

stack.push(g);

StringBuffer sb = new StringBuffer();

Object b ;

while((b=stack.pop())!=null) {

sb.append(b);

}

return Long.parseLong(sb.toString());

}

public static void main(String[] args)

{

DigitalChange dc = new DigitalChange();

long rs = dc.getRs(1348,2);

System.out.println(rs);

long rs2 = dc.getRs(10,2);

System.out.println(rs2);

}

   }


     
4、栈的顺序和链式结构的基本实现
     顺序
    public class Stack{
    private int size;
    private Object[] objects;
    private int length;
    private int addsize;
    
    public Stack(){
        size = 0;
        length = 10;
        objects = new Object[length];
        addsize = 10;
    }
    
    public void push(Object o) {
        sureCapicity(size+1);
        objects[size++] = o;
    }
    
    public Object pop() {
        if(size == 0) {
            return null;
        }else {
            Object t  = objects[--size];
            objects[size]=null;
            return t;
        }
    }
    public int size() {
        return size;
    }
    public Object getTop() {
        return size==0?null:objects[size-1];
    }
    
    public void sureCapicity(int size) {
        if(size>length) {
            // 如果满了,生成更大的空间
            Object[] temp = objects;
            objects = new Object[length+addsize];
            length+=addsize;
            for(int i=0; i<size; i++) {
                objects[i] = temp[i];
            }
        }
    }
    
    public static void main(String[] args)
    {
        Stack stack = new Stack();
        stack.push(1);
        stack.push(2);
        System.out.println(stack.pop());
        System.out.println(stack.pop());
        System.out.println(stack.pop());
    }
    
   }

  链式
   public class LinkedStack{
    private int size;
    private EntryC header;
    
    public LinkedStack() {
        size = 0;
        header = new EntryC(null,null);
    }
    
    public void push(Object d) {
        size++;
        EntryC c = new EntryC(d,header.next);
        header.next = c;
    }
    
    public Object pop() {
        if(header.next==null) return null;
        Object b = header.next.data;
        header = header.next;
        size--;
        return b;
    }
    
    public int size() {
        return size;
    }
    
    public Object getTop() {
        return header.next==null?null:header.next.data;
    }
    
    public static void main(String[] args)
    {
        LinkedStack stack = new LinkedStack();
        stack.push(1);
        stack.push(2);
        System.out.println(stack.pop());
        System.out.println(stack.pop());
        System.out.println(stack.pop());
    }
   }

   class EntryC {
    public Object data;
    public EntryC next;
    
    public EntryC(Object data,EntryC next) {
        this.data = data;
        this.next = next;
    }
   }

5、栈的基本运用,数制的转换
   原理:算出来的余数进栈,都出栈然后正好形成需要的结果
        基本实现:
        public class DigitalChange{
    private LinkedStack stack;
    public DigitalChange() {
        stack = new LinkedStack();
    }
    public int get8Rs(int g) {
        while(g/8>0) {
            stack.push(g%8);
            g = g/8;
        }
        stack.push(g);
        StringBuffer sb = new StringBuffer();
        Object b ;
        while((b=stack.pop())!=null) {
            sb.append(b);
        }
        return Integer.parseInt(sb.toString());
    }
    
    public static void main(String[] args)
    {
        DigitalChange dc = new DigitalChange();
        int rs = dc.get8Rs(1348);
        System.out.println(rs);
        int rs2 = dc.get8Rs(10);
        System.out.println(rs2);
    }
   }
   2、括号的匹配问题"()([{}])()"是匹配的,"[{]}"是错的
      原理:遇到左括号进栈,遇到右括号,栈里出一个,看是否匹配,如是不匹配就是失败,
               如果全匹配完,栈是空的不是对的,不是空的也是失败,
              基本实现:
              public class CharCheck{
    private LinkedStack stack;
    
    public CharCheck() {
        stack = new LinkedStack();
    }
    
    public boolean checkStrig(String str) {
        for(int i=0; i<str.length(); i++) {
            char c = str.charAt(i);
            if(c == '[' || c=='{' || c=='(') {
                stack.push(c);
            }else if(c == ']' || c=='}' || c==')') {
                char t = ((Character) stack.pop()).charValue();
                if(c==']' && t!='[') {
                    return false;
                }
                if(c==')' && t!='(') {
                    return false;
                }
                if(c=='}' && t!='{') {
                    return false;
                }
            }
        }
        return stack.pop()==null;
    }
    public static void main(String[] args){
        CharCheck che = new CharCheck();
        System.out.println(che.checkStrig("()()()"));
        System.out.println(che.checkStrig("[({[][]})]"));
        System.out.println(che.checkStrig("[][(][)]"));
        System.out.println(che.checkStrig("[[][][]"));
    }
   }
  3、表达式求值,也比较方便有栈来实现,
           实现原理:
            一个栈用来装数
            一个栈用来装操作符。
           过程:
              不停得读这个表达式, 数的话进数栈,操作符的话就和栈中第一个操作符优先级进行比较 ,如果是栈中的优先级大,则说明
              栈中的操作符可以操作,拿出操作符,拿出两个操作数,计算结果放入数栈,在从栈中拿出操作符与当前比较进行一样的判断和操作,如果是等于的话,就把栈
              中操作第一个操作符出栈,如果是小于就把操作符进栈。
         代码的基本实现:
         public class CalculateExpression  {
    /* 操作数的栈 */
    private LinkedStack<Integer> stackNumber;
    /* 操作符的栈 */
    private LinkedStack<Character> stackOperate;
    public CalculateExpression() {
        stackNumber = new LinkedStack<Integer>();
        stackOperate = new LinkedStack<Character>();
    }
    public int getRs(String str[]) {
        for(int i=0; i<str.length; i++) {
            String s = str[i];
            if(isChar(s)) {
                // 操作符的话
                // 拿出stackOperate一个
                Character s2 = stackOperate.getTop();
                if(s2 == null) {
                    stackOperate.push(s.charAt(0));
                }else {
                    char rs = compareOperate(s2,s.charAt(0));
                    switch (rs) {
                    case '=':
                        //操作出栈
                        stackOperate.pop();
                        break;
                    case '>':
                        // 操作出栈
                        char c = stackOperate.pop();
                        // 两个操作数出栈
                        int a = stackNumber.pop();
                        int b = stackNumber.pop();
                        int rs1 = caculate(b,a,c);
                        // 把操作结果入栈
                        stackNumber.push(rs1);
                        i--;
                        break;
                    case '<':
                        // 操作进栈
                        stackOperate.push(s.charAt(0));
                        break;
                    }
                }
            }else {
                // 数字进栈
                stackNumber.push(Integer.parseInt(s));
            }
         }
        while(stackOperate.getTop()!=null) {
            char c = stackOperate.pop();
            int a = stackNumber.pop();
            int b = stackNumber.pop();
            int rs1 = caculate(b,a,c);
            stackNumber.push(rs1);
        }
        
        return stackNumber.pop();
    }
    
    public int caculate(int a,int b,char c) {
        if(c=='+') {
            return a+b;
        }else if(c=='*') {
            return a*b;
        }else if(c=='-') {
            return a-b;
        }else{
            return a/b;
        }
        
    }
    
    public static void main(String[] args)
    {
        String[] str = new String[]{"1","+","2","*","(","3","-","4","+","5",")"};
        System.out.println(new CalculateExpression().getRs(str));
    }
    
    public boolean isChar(String s) {
        return (s.equals("+") || s.equals("-") || s.equals("*") || s.equals("/")|| s.equals("(")|| s.equals(")"));
    }
    
    public char compareOperate(char a,char b) {
        if(a=='(' && b==')') {
            return '=';
        }
        if((a=='+' || a =='-') && (b=='*'|| b=='/')) {
            return '<';
        }else if((a=='*'||a=='/')&&(b=='(')) {
            return '<';
        }else if(a=='(') {
            return '<';
        }else{
            return '>';
        }
    }
   }
6、如果正好你读到了我的这些文章,代码和文字都是自己当时临时写的, 可能有错, 也可能不完整。

7、递归:现实当中很多问题的计算过程是一样的,当条件满足某个值 的时候它会返回某个值,这样的问题反应到程序设计当中很多时候用递归来实现,
       递归的实现方式简化了程序的实现。如:1、计算数的阶乘:数i的=数(i-1)的阶乘*数i, 当数是1的时候就返回1,2、比如汉若塔的问题:就是当等于一
      的时候从x-z,当不等于一的时候把n-1从x-y通过z,再把n从x-z,再把n-1从y-z借助x,这是一个重复一样的,直到n==1.
8、在汇编实现函数调用时,它是通过把当前函数的相关信息传过去入栈,在目标函数执行完成时,在出栈找回原函数进行执行。
9、队的链式基本实现:
      public class QueueLinked<E> {
    /* 队头 */
    private EntryQueue<Integer> front;
    /* 队尾 */
    private EntryQueue<Integer> real;
       /* 队长 */
    private int size;
    
    public QueueLinked() {
        size = 0;
        front = real = new EntryQueue<Integer>(null, null);
    }
       /* 进队 */
       public void inqueue(int data) {
           EntryQueue<Integer> d = new EntryQueue<Integer>(data,null);
       real.next = d;
           real = d;
           if(front.next==null) {
               front.next = d;
           }
           size++;
       }
       /* 出队 */
       public Integer outqueue() {
           size--;
           Integer t= front.next.data;
           front = front.next;
       return t;
       }
       public static void main(String[] args) {
           QueueLinked<Integer> queue = new QueueLinked<Integer>();
           queue.inqueue(1);
           queue.inqueue(2);
           System.out.println(queue.outqueue());
           System.out.println(queue.outqueue());
       }
}
class EntryQueue<E> {
    public E data;
    public EntryQueue<E> next;
    
    public EntryQueue(E data,EntryQueue<E>  e) {
        this.data = data;
        this.next = e;
    }
}

10、队的顺序结构的基本实现,也叫循环队列
public class QueueArray
{
    private int size;
    private int length;
    private Integer[] datas;
    private int front;
    private int real;
    
    public QueueArray() {
        size = 0;
        length = 10;
        datas = new Integer[length];
        real = front = 0;
    }
    
    public boolean isEmpty() {
        return size==0;
    }
    
    public void inqueue(int d) {
        if(size == length) {
            throw new IndexOutOfBoundsException("队已经满了");
        }
        datas[real] = d;
        real = (real+1)%length;
        size++;
    }
    
    public int outqueue() {
        if(size==0) {
            throw new IndexOutOfBoundsException("队是空的");
        }
        int data = datas[front];
        front = (front+1)%length;
        size--;
        return data;
    }
    public static void main(String[] args)
    {
        QueueArray queue = new QueueArray();
        queue.inqueue(1);
        queue.inqueue(2);
        System.out.println(queue.outqueue());
        System.out.println(queue.outqueue());
        System.out.println(queue.outqueue());
    }
}
11、字符串的查找 方法:在子串和主串有很多相似的时候用KMP算法方式更快,当然 KMP查找算法也还有很多其它的利用场景,因为它有个特点优点就是主串不用回退。
        对于KMP算法,主要在于模式串的处理,在和主串不匹配的时候,怎么让主串的当前字符和模式串的哪个字符进行比较。这个和模式串的哪个字符比较要进行算出。
        算的过程和主串和模式串有相同之处,具体实现可百度相关文章,理解起来稍微有点复杂,实现起来比较简短。
           







原创粉丝点击