کالکشن ها در جاوا: آموزش کار با Stack + مثال های کاربردی

کالکشن ها در جاوا: آموزش کار با Stack + مثال های کاربردی

معرفی پشته (Stack)

پشته (Stack) یکی از پیاده‌سازی ها در ساختار داده است، در پشته (Stack) دسترسی به عناصر یک طرفه است و بر خلاف لیست که میتونیم به عناصر با index دسترسی داشته باشیم در پشته فقط میتونیم آخرین عنصری که اضافه کردیم رو صدا بزنیم و برای دسترسی به عنصر بعدی باید آخرین عنصر از Stack خارج (حذف) بشه و پشته (Stack) معروفه به last-in-first-out به زبون خودمونی دیر اومدی میخوای زود بری :)

یک لیوان رو در نظر بگیرید که داخلش میخوایم چندتا توپ بندازیم، برای دسترسی به اولین توپی که انداختیم، باید توپ های بعدی رو بیاریم بیرون؛ نگهداری، دسترسی و حذف عناصر در استک (Stack) شبیه همینه.

ساختار پشته (Stack)
ساختار پشته (Stack)

کار با پشته (Stack)

در جاوا کلاس Stack از Vector ارث‌بری میکنه؛ با اینکه Stack در جاوا از Vector پیاده‌سازی میشه، ولی پیاده‌سازی Stack با LinkedList بهینه تره.

ارث‌بری کلاس Stack از کلاس Vector
ارث‌بری کلاس Stack از کلاس Vector

در نمودار UML زیر متد های Stack با توضیحاتشون آورده شده است.

java.util.Stack
+Stack() یک نمونه از Stack ایجاد می کنه.
+isEmpty() اگه عنصری داخل Stack نباشه مقدار true رو بر میگردونه.
+peek(): E آخرین عنصری که به Stack اضافه شده رو بر میگردونه.
+pop(): E آخرین عنصری که به Stack اضافه شده رو حذف می کنه و بر میگردونه.
+push(e: E): boolean عنصر e رو به Stack اضافه می کنه.
+search(o: Object): int موقعیت (index) عنصر مطابق با o در Stack رو بر می گردونه.

پیچیدگی زمان add, pop, peek و push برابر با O(1) است.

میخوایم اسم شهر ها رو داخل Stack ذخیره کنیم و سپس با استفاده از حلقه while اسم شهر ها رو حذف و چاپ کنیم.

Stack<String> cities = new Stack<>();

cities.push("Tehran");
cities.push("Arak");
cities.push("Isfahan");
cities.push("Tabriz");
cities.push("Mashhad");

System.out.println("Displaying cities: ");

while(!cities.isEmpty())
   System.out.print(cities.pop() + " ");

System.out.println();
        
        

میخوایم با استفاده از پشته (Stack) یک پروژه ی ماشین حساب بنویسیم، در این پروژه ماشین حساب یک عبارت مثل 2*5+(4/2)-32 رو حساب می کنه.

public class EvaluateExpression {

     public double evaluateExpression(String expression) {

        Stack<Double> operands = new Stack<>();
        Stack<Character> operators = new Stack<>();

        expression = expression.trim(); //remove every space in expression
        expression = insertBlanks(expression);

        String[] tokens = expression.split("\\s");

        for (String token : tokens) {

            if (!token.isEmpty()) {

                if (token.charAt(0) == '+' || token.charAt(0) == '-') {

                    while (
                            !operators.isEmpty() && (operators.peek() == '+' || operators.peek() == '-' || operators.peek() == '*' || operators.peek() == '/')
                    ) {
                        processAnOperation(operators, operands);
                    }

                    operators.push(token.charAt(0));

                } else if (token.charAt(0) == '*' || token.charAt(0) == '/') {

                    while (!operators.isEmpty() && (operators.peek() == '*' || operators.peek() == '/')) {
                        processAnOperation(operators, operands);
                    }

                    operators.push(token.charAt(0));

                } else if (token.charAt(0) == '(') {

                    operators.push('(');

                } else if (token.charAt(0) == ')') {

                    while (operators.peek() != '(') {
                        processAnOperation(operators, operands);
                    }
                    operators.pop();

                } else {
                    operands.push(Double.parseDouble(token));
                }
            }
        }

        while (!operators.isEmpty())
            processAnOperation(operators, operands);

        return operands.pop();
    }


    private static void processAnOperation(Stack<Character> operators, Stack<Double> operands) {
        char op = operators.pop();
        double operand0 = operands.pop();
        double operand1 = operands.pop();

        switch (op) {
            case '*' -> operands.push(operand1 * operand0);
            case '/' -> operands.push(operand1 / operand0);
            case '-' -> operands.push(operand1 - operand0);
            case '+' -> operands.push(operand1 + operand0);
        }
    }

    private static String insertBlanks(String s) {
        StringBuilder result = new StringBuilder();

        for (int i = 0; i < s.length(); i++) {
            char ch = s.charAt(i);
            if (ch == '+' || ch == '-' || ch == '*' || ch == '/' || ch == '(' || ch == ')')
                result.append(" ").append(ch).append(" ");
            else result.append(ch);
        }

        return result.toString();
    }
}
        

خلاصه

  • پشته (Stack) یک ساختار داده last-in-first-out است.
  • کلاس Stack در جاوا از کلاس Vector ارث‌بری می کنه.

بازخورد و دیدگاه‌ ها

اولین نفری باشید که در این صفحه نظر می‌دهید

notifications برای اطلاع از جدیدترین مطالب و پست های مرتبط، عضو کانال تلگرام ما بشید.

arrow_drop_up
کپی شد!