Использование Java split для оценки математического выражения

1

По прошествии некоторого времени работы с этой проблемой мне трудно понять синтаксис Regex именно для того, что мне нужно.

В курсе Java, который я беру, нам поручено построить калькулятор, способный принимать строку выражения (написанную с круглыми скобками или без нее) и правильно ее оценивая.

Концепция синтаксического анализа выражения состоит в том, что у вас есть строка...

5+16/20-56+7-20*16/9

И вы хотите получить два ArrayLists через "split":

{5,16,20,56,7,20,16,9} {+,/,-,+,-,*,/}

Затем вы выполняете операции по частям в порядке приоритета операции, освобождая операции из вашего массива ArrayList, пока ваш массив чисел не будет иметь один элемент: конечный результат.

К сожалению, у меня нет опыта работы с Regex и я не могу понять смысл учебников и примеров, которые я читаю.

Я не могу понять, как разбить на основе "[*-/+]", и я не могу понять, как выбрать целые числа для разделения, а не просто цифры. Из-за этих ошибок я не могу скомпилировать свой код. Один рабочий фрагмент кода, который я получил:

import java.util.*;
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;

public class Tester
{
    public static void main(String[] args)
    {
        String expression = "3+5+6-10*20/150-14+76%2";

//      String[] operands = expression.split("");
        String[] operators = expression.split("[0-9]");

//      System.out.println(operands);
        System.out.println(operators);
    }
}

приводит к

[Ljava.lang.String;@308ab721

И я понятия не имею, откуда это взялось.

Может ли кто-нибудь помочь мне выяснить, что я делаю неправильно? Или указать на очень хороший уроки для начинающих в Regex?

Я ценю вашу помощь, все.

Теги:
split
expression

4 ответа

2
Лучший ответ

operands и operators - это array

для печати array вы можете сделать

System.out.println(Arrays.toString(operands));
System.out.println(Arrays.toString(operators));

И вы должны разбить его так:

String[] operands = expression.split("[\\+\\-\\*\\%\\/]");
String[] operators = expression.split("[0-9]+");
  • 1
    Ни одна из обратных косых черт в первом шаблоне не нужна, хотя они безвредны.
  • 0
    хорошо, изменил это. но хорошей практикой является включение escape-символа в регулярное выражение (для начинающих). Поскольку в некоторых случаях это необходимо. replaceAll() например
Показать ещё 8 комментариев
1

Вы печатаете адрес памяти ваших переменных. Если вам требуется строковое представление, вы можете сделать

System.out.println(Arrays.toString(operators));

То, что происходит за кулисами, - это метод println() вызывающий toString() для любого объекта, который передается ему. По умолчанию реализация toString() для массива в Java - это возврат адреса памяти, поэтому вы получаете эту уродливую вещь.

1

Я не эксперт, но это должно сработать для вас:

public static void main(String[] args)
{      
  String expression = "3+5+6-10*20/150-14+76%2";

  String[] operands = expression.split("[-+*%/]");
  String[] operators = expression.split("[0-9]+");

  System.out.println(Arrays.toString(operands));
  System.out.println(Arrays.toString(operators));
}

Вам нужно избежать метасимволов Regex (или в этом случае просто изменить порядок) и правильно напечатать ваши массивы.

Небольшая разработка:

В Regex некоторые символы имеют особое значение. Вы уже использовали их, указав диапазон 0-9, при этом тире является метасимволом. То же самое относится к -. Вы можете увидеть полный список здесь.

Я фактически использовал метасимвол + (который "соответствует предыдущему подвыражению один или несколько раз") в шаблоне с измененным номером, чтобы уменьшить количество пустых строк, которые были разделены. Он делает это путем сопоставления одного или нескольких вхождений цифры.

  • 1
    (1) Вам не нужно экранировать большинство метасимволов, когда они находятся внутри [] . В частности, + и * имеют специального значения в квадратных скобках. (2) Если бы вы избежали их, вы сделали бы это с обратной косой чертой, а не с прямой. Все, что вы здесь сделали, - это пять раз добавили косую черту в свой класс персонажа, что безвредно, но выглядит глупо.
  • 0
    @ajb 1 косая черта - оператор деления. И я думал, что вам нужно удвоить метасимволы, но я ошибся. Спасибо, отредактировал.
Показать ещё 3 комментария
0

Если это просто цифры или не номера, регулярное выражение просто:

String[] operands = expression.split("\\D+");
String[] operators = expression.replaceAll("^\\d+", "").split("\\d+");

Значения регулярных выражений:

Вызов replaceAll() обрезает ведущие цифры из выражения, поэтому вы не получите пустым, как первый оператор.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню