связанный список удалить ошибку - PullRequest
2 голосов
/ 27 апреля 2011

У меня есть домашнее задание, чтобы сделать калькулятор с использованием стека и преобразовать инфикс в постфикс.Мой метод инфикса в постфикс работает нормально.Но другой метод оценки этого работает для всех случаев, кроме случаев, когда кратные или делители приводят к двузначным числам.Мой калькулятор не поддерживает двузначные записи, но поддерживает оценку двузначных.Попробуйте ввести: 2 + 2 * 5/2, 2 + 5 * 4/2 и некоторые другие в аналогичном формате.Ошибка находится в строке 151 на втором прогоне, когда он идет, чтобы вычислить деление.Вот что происходит в связанном списке: [2, 2, 5, *, 2, /, +] [2, 10, 2, /, +] [10, 2, +] - ошибка Следует удалить /,2 и 10, следовательно, 3 удаляет утверждение.Но когда он делает eval.remove (eval.get (i-1)), 2 перед ним исчезает, а 10 становится передним узлом.

    import java.util.Stack;
import java.util.LinkedList;

public class Calculator
{
    Stack<Character> infix = new Stack<Character>();

    StringBuilder postfix = new StringBuilder();
    Stack<String> postfix_str = new Stack<String>();

    String operators = "+-*/^";

    String infix2postfix(String infix_str)
    {
        int i = 0;
        boolean flag = true;

        while (!infix_str.isEmpty())
        {
            if (infix_str.charAt(i) == '(')
            {
                infix.push(infix_str.charAt(i));
                infix_str = infix_str.substring(i+1, infix_str.length());
            }
            else
            {
                if (Character.getNumericValue(infix_str.charAt(i)) >= 0 && 
                    Character.getNumericValue(infix_str.charAt(i)) <= 9)
                {
                    postfix.append(infix_str.charAt(i));
                    postfix_str.push(String.valueOf(infix_str.charAt(i)));//added
                    infix_str = infix_str.substring(i+1, infix_str.length());
                }
                else //operator
                {
                    if (!(infix_str.charAt(i) == ')'))
                    {
                        if (infix.empty() || infix.peek() == '(' || !(preced(infix_str.charAt(i), infix.peek())))
                        {
                            infix.push(infix_str.charAt(i));
                            infix_str = infix_str.substring(i+1, infix_str.length());
                        }
                        else
                        {
                            postfix_str.push(String.valueOf(infix.peek()));//added
                            postfix.append(infix.pop());
                        }
                    }
                    else
                    {
                        try
                        {
                            while (infix.peek() != '(')
                            {
                                postfix_str.push(String.valueOf(infix.peek()));//added
                                postfix.append(infix.pop());
                            }
                            infix.pop();
                            infix_str = infix_str.substring(i+1, infix_str.length());
                         }
                         catch(Exception EmptyStackException)
                         {
                            System.out.println("Unbalanced Parathesis");
                            break;
                         }
                    }
                }
            }
        }
        while (!infix.empty())
        {
            postfix_str.push(String.valueOf(infix.peek()));//added
            postfix.append(infix.pop());
        }
        System.out.println(postfix);
        System.out.println(postfix_str.toString());
        return postfix.toString();
    }

    /**
     * 
     * @param statement operator, top of stack
     * @return true to pop
     */
    boolean preced(char arg1, char arg2)//when to pop (true - pop)
    { 
        String firstPreced = "^";
        String secondPreced = "*/";
        String thirdPreced = "+-";

        //EQUALS TO
        if ((thirdPreced.charAt(0) == arg1 || thirdPreced.charAt(1) == arg1)
                                          &&
            (thirdPreced.charAt(0) == arg2 || thirdPreced.charAt(1) == arg2))
        {return true;}
        if ((secondPreced.charAt(0) == arg1 || secondPreced.charAt(1) == arg1)
                                          &&
            (secondPreced.charAt(0) == arg2 || secondPreced.charAt(1) == arg2))
        {return true;}
        if (firstPreced.charAt(0) == arg1
                        &&
            firstPreced.charAt(0) == arg2) 
        {return true;}


        if ((thirdPreced.charAt(0) == arg1 || thirdPreced.charAt(1) == arg1)
                                          &&
            (secondPreced.charAt(0) == arg2 || secondPreced.charAt(1) == arg2))
        {return true;}

        if ((thirdPreced.charAt(0) == arg1 || thirdPreced.charAt(1) == arg1)
                                          &&
            (firstPreced.charAt(0) == arg2))
        {return true;}

        return false;
    }

    void evalPostfix(String postfix)//2+2*5/2
    {
        LinkedList<String> eval = new LinkedList<String>();
        //[2, 2, 5, *, 2, /, +]
        //[2, 10, 2, /, +]
        //[2, 5, +] -- should be
        //[10, 2, +] -- result
        while (!postfix_str.empty())
        {
            eval.addFirst(postfix_str.pop());
        }

        int i = 0;

        while (!(eval.size() == 1))
        {                      
            if (eval.get(i).equals("+") || eval.get(i).equals("-") || eval.get(i).equals("*") || eval.get(i).equals("/")
                    || eval.get(i).equals("^"))
            {
                double total = 0;
                if (eval.get(i).equals("+"))
                {total = Double.valueOf(eval.get(i - 1)) + Double.valueOf(eval.get(i - 2));}
                if (eval.get(i).equals("-"))
                {total = Double.valueOf(eval.get(i - 1)) - Double.valueOf(eval.get(i - 2));}
                if (eval.get(i).equals("*"))
                {total = Double.valueOf(eval.get(i - 1)) * Double.valueOf(eval.get(i - 2));}
                if (eval.get(i).equals("/"))
                {total = Double.valueOf(eval.get(i - 2)) / Double.valueOf(eval.get(i - 1));}
                if (eval.get(i).equals("^"))
                {total = Double.valueOf(eval.get(i - 1)) ^ Double.valueOf(eval.get(i - 2));}

                eval.remove(eval.get(i));
                eval.remove(eval.get(i-1));//BUG!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
                eval.remove(eval.get(i-2));

                i-=2;

                String sum_str = Double.toString(total);

                eval.add(i, sum_str);

                total = 0;
            }
            else
            {
                i++;
            }
        }
        System.out.println(eval.get(0));
    }
}



   import java.util.Scanner;

public class CalculatorTest
{
    public static void main(String[] args)
    {
        while(true)
        {
        Calculator calc = new Calculator();
        Scanner in = new Scanner(System.in);
        System.out.println("Enter Calc");
        String input = in.nextLine();
        calc.infix2postfix(input);
        calc.evalPostfix("");
        }
    }
}

1 Ответ

3 голосов
/ 27 апреля 2011

Похоже, вы используете LinkedList#remove(Object) для удаления элемента из связанного списка.Этот метод удаляет элементы по ссылке , поэтому он ищет элемент для удаления.Поскольку элемент может появляться в связанном списке более одного раза, звучит так, будто он находит первый экземпляр элемента ("2") и удаляет его. [*]

Возможно, вы можете попробовать использовать LinkedList#remove(int), который удаляет элемент по позиции .Итак:

eval.remove(i);
eval.remove(i-1);
eval.remove(i-2);

[*] Я здесь приукрашиваю некоторые детали, например, как две ссылки на две строки могут фактически быть одним и тем же элементом.Вероятно, это связано с интернированием строк , но я не могу быть уверен без более детального изучения вашего кода.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...