Experiment 3. Stack and Queue

T1(用单链表实现栈的push,top,pop功能)

package Experiment3;


import java.util.Scanner;

public class testMyStack {
    public static void main(String[] args) {
        System.out.print("输入的元素个数为: ");
        Scanner sc = new Scanner(System.in);
        myStack stack = new myStack();
        int num = sc.nextInt();
        System.out.println("输入元素,push");
        for (int i = 0 ;i<num;i++)
            stack.push(sc.nextInt());

        System.out.println("栈顶元素: "+stack.top());
        System.out.print("pop()遍历栈:");
        while (!stack.isEmpty()){
            System.out.print(stack.pop()+ " ");
        }
        System.out.println();
    }
}


class myStack {                                        //创建栈
    static ListNode top;                               //头节点
    static int size;

    myStack(){
        size = 0;
        top = new ListNode(-1);
    }
    public static void push(int data)
    {
        ListNode newNode = new ListNode(data);           //运用头插法可以使得push和pop方法的时间复杂度达到O(1)!! 否侧在pop时都需要遍历链表
        newNode.next = top.next;
        top.next = newNode;
        size++;
    }
    public static int pop(){
        if(isEmpty())       throw new RuntimeException("Stack is empty");
        int temp = top.next.data;
        top.next = top.next.next;
        size--;
        return temp;
    }
    public static int top()
    {
        if(isEmpty())     throw new RuntimeException("Stack is empty");
        return top.next.data;
    }
    public static boolean isEmpty()
    {
        if(size!=0) return false;
        return true;
    }

}

class ListNode{                                            //创建链表的节点
    int data;
    ListNode next;
    ListNode(){}
    ListNode(int data){
        this.data = data;
    }
}


T2(使用不同的数据结构完成队列)

package Experiment3;

import java.util.Arrays;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;

public class testMyQueue {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入元素的个数: ");
        int num = sc.nextInt();
        queue_linkedList queue_linkedList = new queue_linkedList();
        queue_array queue_array = new queue_array(num);
        queue_circularArray queue_circularArray = new queue_circularArray(num);
        Queue<Integer> queue = new LinkedList<>();
        System.out.println("请输入你的元素,push");
        for (int i = 0;i<num;i++)
        {
            int temp = sc.nextInt();
            queue.offer(temp);
            queue_linkedList.push(temp);
            queue_array.push(temp);
            queue_circularArray.push(temp);
        }
        System.out.println("访问对头元素");
        System.out.println("queue.peek(): "+ queue.peek());
        System.out.println("queue_linkedList.peek(): "+ queue_linkedList.peek());
        System.out.println("queue_array.peek(): "+queue_array.peek());
        System.out.println("queue_circularArray.peek(): "+queue_circularArray.peek());
        System.out.println("利用pop()遍历栈");
//-----------------------------------------------------------------------------------
        System.out.println("queue的遍历");
        while (!queue.isEmpty())
        {
            System.out.print(queue.poll()+" ");
        }
        System.out.println();
//--------------------------------------------------------
        System.out.println("queue_linkedList的遍历");
        while (!queue_linkedList.isEmpty()){
            System.out.print(queue_linkedList.pop()+" ");
        }
        System.out.println();
//--------------------------------------------------------
        System.out.println("queue_array的遍历");
        while (!queue_array.isEmpty()){
            System.out.print(queue_array.pop()+" ");
        }
        System.out.println();
//--------------------------------------------------------
        System.out.println("queue_circularArray");
        while (!queue_circularArray.isEmpty()){
            System.out.print(queue_circularArray.pop()+" ");
        }
        System.out.println();



    }
}


class queue_linkedList{
     ListNode  front;
     ListNode rear;
     int size;
    queue_linkedList(){
        ListNode newNode = new ListNode();
        front = newNode;
        size = 0;
        rear = front;
    }
    public void push(int data)
    {
        ListNode newNode = new ListNode(data);
        rear.next = newNode;
        rear = rear.next;
        size++;
    }
    public int pop(){
        if(isEmpty()) throw new RuntimeException("队列为空");
        int temp = front.next.data;
        front.next = front.next.next;
        size--;
        return temp;
    }
    public int peek(){
        if(isEmpty()) throw new RuntimeException("队列为空");
        return front.next.data;
    }
    public boolean isEmpty()
    {
        if(size==0) return true;
        return false;
    }
}

class queue_array {
    int front;
    int rear;
    int size;
    int[] array;
    queue_array(int num)
    {
        array = new int[num];
        front = -1;
        rear = 0;
        size = 0;
    }
    public boolean isEmpty()
    {
        if(size==0) return true;
        return false;
    }
    public boolean isFull()
    {
        if(size==array.length||rear==array.length)                                                  //队列满了或者下标溢出
            return true;
        return false;
    }
    public void push(int data)
    {
        if(isFull()){
            System.out.println("队列已满或者数组下标溢出");
            System.out.println("数组自动扩容2倍");
            array = Arrays.copyOf(array,2*array.length);                                   //java数组的一种扩容方式
        }
        array[rear++] = data;
        size++;
    }
    public int pop()
    {
        if(isEmpty()) throw new RuntimeException("队列为空");
        size--;
        return array[++front];
    }
    public int peek(){
        if(isEmpty()) throw new RuntimeException("队列为空");
        return array[front+1];
    }
}


class queue_circularArray
{
    int front;
    int rear;
    int[] array;
    queue_circularArray(int num)                           //循环队列
    {
        front = 0;
        rear = 0;
        array = new int[num+1];
    }
    public boolean isEmpty()
    {
        if(rear == front) return true;
        return false;
    }
    public boolean isFull()
    {
        if(front==(rear+1)%array.length) return true;
        return false;
    }
    public void push(int data)
    {
        if(isFull()) throw new RuntimeException("队列已满");
        array[(++rear)%array.length] = data;

    }
    public int pop()
    {
        if(isEmpty()) throw new RuntimeException("队列为空");

        return array[(++front)%array.length];
    }
    public int peek()
    {
        if (isEmpty()) throw new RuntimeException("队列为空");

        return array[(front+1)%array.length];
    }
}

命令框内容:

请输入元素的个数: 
4
请输入你的元素,push
1
2
3
4
访问对头元素
queue.peek(): 1
queue_linkedList.peek(): 1
queue_array.peek(): 1
queue_circularArray.peek(): 1
利用pop()遍历栈
queue的遍历
1 2 3 4 
queue_linkedList的遍历
1 2 3 4 
queue_array的遍历
1 2 3 4 
queue_circularArray
1 2 3 4


T3(读文件并判断符号的平衡)

注意需要读完整的文件

package Experiment3;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

import java.util.Stack;

public class test3 {
    public static void main(String[] args) throws IOException {                                     //sc.next()中间不能带空格或者换行
    //-----------------------------------------                读取文件的全部内容                        //sc.nextLine()不能换行
        String fileName ="C:\\Users\\10258\\Desktop\\test3.txt";
        FileReader fileReader = new FileReader(fileName);

        BufferedReader bufferedReader = new BufferedReader(fileReader);

        String line =bufferedReader.readLine();
        StringBuffer buffer = new StringBuffer();
        boolean flag1 = true;
        boolean flag2 = true;
        Stack<Character> stack = new Stack<>();
        myStack_char stack_char = new myStack_char();
        while (line!=null){
            buffer.append(line);
            line = bufferedReader.readLine();
        }
        if(!mySolution.isValid(buffer,stack)){
            System.out.println("stack: not balance");
        }else{
            System.out.println("stack: balance");
        }
        if(!stack_char.isValid(buffer,stack_char)){
            System.out.println("myStack: not balance");
        }else{
            System.out.println("myStack: balance ");
        }
        bufferedReader.close();
        fileReader.close();



    }
    //----------------------------------------
}
class myStack_char {                                        //创建栈
    ListNode_char top;                               //头节点
    int size;

    myStack_char(){
        size = 0;
        top = new ListNode_char();
    }
    public  void push(char data)
    {
        ListNode_char newNode = new ListNode_char(data);           //运用头插法可以使得push和pop方法的时间复杂度达到O(1)!! 否侧在pop时都需要遍历链表
        newNode.next = top.next;
        top.next = newNode;
        size++;
    }
    public char pop(){
        if(isEmpty())       throw new RuntimeException("Stack is empty");
        char temp = top.next.data;
        top.next = top.next.next;
        size--;
        return temp;
    }
    public char top()
    {
        if(isEmpty())     throw new RuntimeException("Stack is empty");
        return top.next.data;
    }
    public  boolean isEmpty()
    {
        if(size!=0) return false;
        return true;
    }
    public  boolean  isValid(StringBuffer s,myStack_char stack) {

        for(int i = 0;i < s.length();i++)
        {
            if(s.charAt(i)=='('||s.charAt(i)=='['||s.charAt(i)=='{')
            {
                stack.push(s.charAt(i));
            }else if(s.charAt(i)=='/'&&s.charAt(++i)=='*'){
                stack.push('/');
                stack.push('*');
            }else if(Character.isLetter(s.charAt(i))) continue;
            else if(s.charAt(i)==')'&&stack.pop()!='(') return false;
            else if(s.charAt(i)==']'&&stack.pop()!='[') return false;
            else if(s.charAt(i)=='}'&&stack.pop()!='{') return false;
            else if(s.charAt(i)=='*'&&s.charAt(++i)=='/'){
                if(stack.pop()!='*') return false;
                if(stack.pop()!='/') return false;
            }

        }
        return stack.isEmpty();
    }
}


class ListNode_char{                                            //创建链表的节点
    char data;
    ListNode_char next;
    ListNode_char(){}
    ListNode_char(char data){
        this.data = data;
    }
}




class mySolution {

    public static boolean isValid(StringBuffer s,Stack<Character> stack) {
        for(int i = 0;i < s.length();i++)
        {
            if(s.charAt(i)=='('||s.charAt(i)=='['||s.charAt(i)=='{')
            {
                stack.push(s.charAt(i));
            }else if(s.charAt(i)=='/'&&s.charAt(++i)=='*'){
                stack.push('/');
                stack.push('*');
            }else if(Character.isLetter(s.charAt(i))) continue;
            else if(s.charAt(i)==')'&&stack.pop()!='(') return false;
            else if(s.charAt(i)==']'&&stack.pop()!='[') return false;
            else if(s.charAt(i)=='}'&&stack.pop()!='{') return false;
            else if(s.charAt(i)=='*'&&s.charAt(++i)=='/'){
                if(stack.pop()!='*') return false;
                if(stack.pop()!='/') return false;
            }

        }
        return stack.isEmpty();
    }
}

测试用例:

 注意:文件路径需要自己设置,在记事本中更改后需要Ctrl+s保存再测试

代码还是不能直接测试,代码中含大量的自己设置的字符串符号和char里自己设置的符号以及注释//等,对只含字母和符号有较好效果


 T5(中缀表达式转后缀表达式,利用后缀表达式计算)

package Experiment3;
import java.util.Scanner;
import java.util.Stack;

public class test5 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String infix = sc.nextLine();
        System.out.println(infix);
        String[] strArray = infix.split(" ");
        String postfix = Solution.transform(strArray);
        System.out.println("转成后缀表达式: "+postfix);
        System.out.println("答案: "+Solution.evalRPN(postfix.split(" ")));
    }
}


class Solution {
    public static int evalRPN(String[] tokens) {
        Stack<Integer> stack = new Stack<>();
        for(String s : tokens)
        {
            if(s.equals("+"))
            {
                stack.push(stack.pop()+stack.pop());
            }else if(s.equals("-")){
                stack.push(-stack.pop()+stack.pop());
            }else if(s.equals("*"))
            {
                stack.push(stack.pop()*stack.pop());
            }else if(s.equals("/")){
                int a = stack.pop();
                int b = stack.pop();
                stack.push(b/a);
            }else{
                stack.push(Integer.parseInt(s));
            }
        }
        return stack.pop();
    }
    public static String transform(String[] infix)                               //较复杂,需要注意判断的先后顺序
    {
        Stack<String> stack1 = new Stack<>();
        Stack<String> stack2 = new Stack<>();
        for(String a: infix)
        {
            if(a.equals("+")||a.equals("-")||a.equals("*")||a.equals("/")||a.equals("(")||a.equals(")")){
                if(a.equals(")")) {
                    while (!stack1.peek().equals("(")){
                        stack2.push(stack1.pop());
                    }
                    stack1.pop();
                }
                else if(stack1.isEmpty()||stack1.peek().equals("(")||a.equals("(")){                                           //空栈也直接压入
                    stack1.push(a);
                }

                else if((stack1.peek().equals("+")||stack1.peek().equals("-"))&&(a.equals("*")||a.equals("/"))){
                    stack1.push(a);
                }
                else{
                    stack2.push(stack1.pop());
                    stack1.push(a);
                }
            }else{
                stack2.push(a);
            }
        }
        while (!stack1.isEmpty()){
            stack2.push(stack1.pop());
        }
        String result = "";
        while (!stack2.isEmpty()){
            result = stack2.pop()+" "+result;
        }
        return result;
    }

}

一个中缀转后缀的例子:

 测试用例:

要求输入的公式各种数字和符号之间用空格隔开

仅做了两个测试用例,无法保证这个一定准确


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值