Модераторы: LSD, AntonSaburov
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Строковый калькулятор 
V
    Опции темы
Владислав95
Дата 15.8.2013, 21:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 3
Регистрация: 15.8.2013

Репутация: нет
Всего: нет



Создаю строковый калькулятор, используя алгоритм обратная польская запись. В некоторых случаях код работает, в большинстве случаев работает неправильно. Подскажите, пожалуйста, в чём проблема. 

Код

import java.io.IOException;
import java.util.ArrayList;
import java.util.Stack;
 
public class Calculator {
    static String opn = "";
    static Stack stack;
    static int priority;
    static char temp;
 
    static int currentPriority;
    static double first;
    static double second;
 
    public static void main(String[] args) throws IOException {
        stack = new Stack();
        System.out.println("Enter string: ");
        String s = DataInput.getString();
 
        /**
         * Цикл переводит выражение о Обратную Польскую Нотацию.
         */
        for (int i = 0; i < s.length(); i++) {
 
            /**
             * помещение числа в строку
             * */
            if (Character.isDigit(s.charAt(i))) {
                opn += s.charAt(i);
            }
 
            /**
             * если на вход приходит символ
             * */
            else if (s.charAt(i) == '+' || s.charAt(i) == '-'
                    || s.charAt(i) == '*' || s.charAt(i) == '/'
                    || s.charAt(i) == '^' || s.charAt(i) == '('
                    || s.charAt(i) == ')') {
                /*
                 * if (i > 0 && opn.charAt(opn.length() - 1) != ' ') opn += ' ';
                 * // (1+2)*4+3 // 3 + 4 * 2 / (1 - 5)^2
                 */
                /**
                 * определяется приоритет операции
                 * */
                switch (s.charAt(i)) {
                case '^':
                    priority = 3;
                    break;
                case '/':
                    priority = 2;
                    break;
                case '*':
                    priority = 2;
                    break;
                case '+':
                    priority = 1;
                    break;
                case '-':
                    priority = 1;
                    break;
                case '(':
                    priority = 0;
                    break;
                }
 
                /**
                 * если стек пустой
                 * */
 
                if (stack.empty()) {
                    stack.push(s.charAt(i));
                }
 
                /**
                 * если скобка, помещаем в стек
                 * */
                else if (s.charAt(i) == '(') {
                    stack.push(s.charAt(i));
                }
 
                /**
                 * если закрывающая скобка, то извлекаем символы из стека в
                 * выходную строку до тех пор, пока не встретим в стеке
                 * открывающую скобку
                 * */
                else if (s.charAt(i) == ')') {
                    while (!stack.empty()) {
                        if ((Character) stack.peek() == '(')
                            break;
                        if (!stack.empty() && (Character) stack.peek() != '(') {
                            opn += stack.pop();
                        }
 
                    }
 
                    if (!stack.empty() && (Character) stack.peek() == '(') {
                        stack.pop();
                    }
 
                }
 
                /**
                 * если стек не пустой, определяется приоритет верхнего символа
                 * стека.
                 * */
                else if (!stack.empty()) {
                    temp = (Character) stack.peek();
                    switch (temp) {
                    case '^':
                        currentPriority = 3;
                        break;
                    case '/':
                        currentPriority = 2;
                        break;
                    case '*':
                        currentPriority = 2;
                        break;
                    case '+':
                        currentPriority = 1;
                        break;
                    case '-':
                        currentPriority = 1;
                        break;
                    case '(':
                        currentPriority = 0;
                        break;
                    }
 
                    //
                    /**
                     * если находящиеся в нем символы (а находится в нем могут
                     * только знаки операций и открывающая скобка) имеют меньший
                     * приоритет, чем приоритет текущего символа, то помещаем
                     * текущий символ в стек.
                     */
                    if (currentPriority < priority) {
                        stack.push(s.charAt(i));
                    }
                    //
                    /**
                     * Если символ, находящийся на вершине стека имеет
                     * приоритет, больший или равный приоритету текущего
                     * символа, то извлекаем символы из стека в выходную строку
                     * до тех пор, пока выполняется это условие
                     */
                    else if (currentPriority >= priority) {
                        while (!stack.empty()) {
 
                            temp = (Character) stack.peek();
                            switch (temp) {
                            case '^':
                                currentPriority = 3;
                                break;
                            case '/':
                                currentPriority = 2;
                                break;
                            case '*':
                                currentPriority = 2;
                                break;
                            case '+':
                                currentPriority = 1;
                                break;
                            case '-':
                                currentPriority = 1;
                                break;
                            case '(':
                                currentPriority = 0;
                                break;
                            }
                            /*
                             * if(currentPriority<priority) break;
                             */
                            if (currentPriority >= priority)
                                opn += (Character) stack.pop();
                            else
                                break;
 
                        }
 
                    }
 
                }
 
            }
        }
 
        while (!stack.empty()) {
            if ((Character) stack.peek() == '(')
                stack.pop();
            else
                opn += stack.pop();
        }
 
        System.out.println("Our OPN:" + opn);
 
        /**
         * считаем выражение в ОПН
         * */
        Stack newstack = new Stack();
        for (int i = 0; i < opn.length(); i++) {
            if (Character.isDigit(opn.charAt(i))) {
                newstack.push(opn.charAt(i));
            }
 
            double result = 1;
            if (opn.charAt(i) == '+' || opn.charAt(i) == '-'
                    || opn.charAt(i) == '*' || opn.charAt(i) == '/'
                    || opn.charAt(i) == '^') {
                String fir = "";
                String sec = "";
                fir += newstack.pop();
                sec += newstack.pop();
                first = Double.parseDouble(fir);
                second = Double.parseDouble(sec);
 
                switch (opn.charAt(i)) {
                case '^':
                    result = Math.pow(second, first);
                    newstack.push(result);
                    break;
                case '/':
                    newstack.push(second / first);
                    break;
                case '*':
                    newstack.push(second * first);
                    break;
                case '+':
                    newstack.push(second + first);
                    break;
                case '-':
                    newstack.push(second - first);
                    break;
 
                }
            }
 
        }
        System.out.println("Result: " + newstack.peek());
    }
}

PM MAIL   Вверх
Qu1nt
Дата 15.8.2013, 22:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 602
Регистрация: 13.1.2007

Репутация: нет
Всего: 50



Проблема в отсутствии тестов.
PM MAIL   Вверх
Владислав95
Дата 16.8.2013, 00:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 3
Регистрация: 15.8.2013

Репутация: нет
Всего: нет



не могу понять в чём проблема, напутал скорее всего с условиями в цикле перехода в опн. писал код по этому уроку http://trubetskoy1.narod.ru/ppn.html
PM MAIL   Вверх
Mirkes
Дата 16.8.2013, 15:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 586
Регистрация: 18.8.2011
Где: Красноярск

Репутация: 7
Всего: 17



Вам же сказали - проблема в отсутствии тестов. Покажите какие выражения транслируются в ОПН правильно, а какие - неправильно.

А вообще, зачем Вам ОПН? Если Вы все равно производите синтаксический разбор нормально записанного выражения, то и вычисляйте результат сразу без промежуточной записи в ОПН.


--------------------
Mirkes
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   tux
javastic
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux, javastic.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0742 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.