Как правильно распарсить строку?

204
08 января 2022, 17:00

Пытаюсь распарсить формулу на составные части. Есть метод:

public static ArrayList <String> partOfFormula(String formulaStr){
    ArrayList<String> listOfParts = new ArrayList<String>(); 
    String[] partsOfFormulaArray;
    if (formulaStr.contains("+")) {
        partsOfFormulaArray = formulaStr.split("\\+");
        for (int i = 0; i < partsOfFormulaArray.length; i++) {
            listOfParts.add(partsOfFormulaArray[i]);
        }
    }
    if (formulaStr.contains("-") && formulaStr.indexOf('-')!=0) {
        partsOfFormulaArray = formulaStr.split("-");
        for (int i = 0; i < partsOfFormulaArray.length; i++) {
            listOfParts.add(partsOfFormulaArray[i]);
        }
    }
    if (formulaStr.contains("*")){
        partsOfFormulaArray = formulaStr.split("\\*");
        for (int i = 0; i< partsOfFormulaArray.length; i++){
            listOfParts.add(partsOfFormulaArray[i]);
        }
    }
    if (formulaStr.contains("/")) {
        partsOfFormulaArray = formulaStr.split("/");
        for (int i = 0; i < partsOfFormulaArray.length; i++) {
            listOfParts.add(partsOfFormulaArray[i]);
        }
    }
    return listOfParts;
}

Если передать туда строку

   "sin(30)*cos(60)/2"

метод возвращает

   "sin(30)"
   "cos(60)/2"
   "sin(30)*cos(60)"
   "2"

Подскажите, что добавить в код чтобы он возвращал

"sin(30)"
"cos(60)"
"2"
Answer 1

Ошибка вот в чем: вы сначала разделили строку по знаку умножения ("sin(30)*cos(60)/2" -> "sin(30)" был знак умножения "cos(60)/2"), а потом по знаку деления("sin(30)*cos(60)/2" -> "sin(30)*cos(60)" был знак деления "2"). Все результаты и добавили.
Как можно решить вашу проблему? Начнем с определения задачи: поделить строку на множество строк, между которыми раньше стояли некие специальные знаки(в нашем случае '/', '*', '+', '-'). Вот алгоритм, решающий эту проблему в лоб:

public static ArrayList <String> partOfFormula(String formulaStr){
    ArrayList<String> listOfParts = new ArrayList<String>(); 
    // id символа, начинающего строку между знаками
    // Например, в строке "23*21*45", beginOfNextPart последовательно принимает значения 0, 3, 6.
    int beginOfNextPart = 0;
    char[] formulaChars = formulaStr.toCharArray();
    for(int i = 0; i < formulaChars.length; i++) {
        if(isSign(formulaChars[i]) && (formulaChars[i] != '-' || beginOfNextPart != i)) {
            listOfParts.add(formulaStr.substring((beginOfNextPart == -1) ? 0 : beginOfNextPart, i));
            beginOfNextPart = i + 1;
        }
    }
    // Добавляем "хвост"
    // Например, у "2*20010" хвостом будет "20010"
    listOfParts.add(formulaStr.substring(beginOfNextPart, formulaStr.length()));
    return listOfParts;
}
private static boolean isSign(char c) {
    return  c == '+' || c == '-' || c == '*' || c == '/';
}
READ ALSO
Поменять местами элементы в CSS

Поменять местами элементы в CSS

Есть список из элементов, первые два занимают по 25% ширины, а каждый третий 50%Размещены по три в строке, сколько будет элементов неизвестно,...

225
Новогодний конкурс 2020 года!

Новогодний конкурс 2020 года!

В прошлом году подобный конкурс неожиданно привлек большой интерес участников RUso

311
Странно работает cin.get() после обработки ctrl+c

Странно работает cin.get() после обработки ctrl+c

Суть программы в том, что пользователь вводит строку, которая посимвольно считывается и выводится на экранРеализована обработка ctrl+c, в результате...

87