Обработка символа ^ для получения степеней многочленов с использованием регулярных выражений - PullRequest
1 голос
/ 14 октября 2019

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

Pattern pattern = Pattern.compile("([+-]?(?:(?:\\d+x\\^\\d+)|(?:\\d+x)|(?:\\d+)|(?:x)))");
Matcher matcher = pattern.matcher(expr);
while (matcher.find()) {
    if(matcher.group(1).matches("[0-9]+")) {
        a = Integer.parseInt(matcher.group(1));
        b = 0;
    } else if(matcher.group(1).matches("\\^")) {
        a = Integer.parseInt(expr.substring(0, expr.indexOf("x")));
        b = Integer.parseInt(expr.substring(0, expr.indexOf("^"))+1);
    } else {
        a = Integer.parseInt(expr.substring(0, expr.indexOf("x")));
        b = 1;
    }
}

Это должно быть в состоянии обнаружить и выдать мне допустимые выходные данные, если в качестве входных данных указано что-то вроде

5x ^ 3 + 2x + 1

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

Ответы [ 2 ]

1 голос
/ 14 октября 2019

Я думаю, что выражение, похожее на,

\^(-?\d+(?:\.\d+)?)|(-?\d+(?:\.\d+)?)|(x)

Демо (для десятичных дробей)

или,

\^(-?\d+)|(-?\d+)|(x)

Демонстрация (для целых чисел)

может быть полезна для решения проблемы.


Здесь первая группа находит значения экспонентывторая группа возвращает коэффициенты, а третья группа возвращает x (чтобы можно было выяснить, есть ли в уравнении константа).

Тест

import java.util.regex.Matcher;
import java.util.regex.Pattern;


public class RegularExpression{

    public static void main(String[] args){

        final String regex = "\\^(-?\\d+(?:\\.\\d+)?)|(-?\\d+(?:\\.\\d+)?)|(x)";
        final String string = "5x^3 +2x +1\n"
             + "5x^-3.1 +2x -1\n"
             + "5x^3.23 -2012.12x +10.12\n"
             + "-5x^3.54 +2x -1.512";

        final Pattern pattern = Pattern.compile(regex, Pattern.DOTALL | Pattern.CASE_INSENSITIVE);
        final Matcher matcher = pattern.matcher(string);

        while (matcher.find()) {
            System.out.println("Full match: " + matcher.group(0));
            for (int i = 1; i <= matcher.groupCount(); i++) {
                System.out.println("Group " + i + ": " + matcher.group(i));
            }
        }

    }
}

Вывод

Full match: 5
Group 1: null
Group 2: 5
Group 3: null
Full match: x
Group 1: null
Group 2: null
Group 3: x
Full match: ^3
Group 1: 3
Group 2: null
Group 3: null
Full match: 2
Group 1: null
Group 2: 2
Group 3: null
Full match: x
Group 1: null
Group 2: null
Group 3: x
Full match: 1
Group 1: null
Group 2: 1
Group 3: null
Full match: 5
Group 1: null
Group 2: 5
Group 3: null
Full match: x
Group 1: null
Group 2: null
Group 3: x
Full match: ^-3.1
Group 1: -3.1
Group 2: null
Group 3: null
Full match: 2
Group 1: null
Group 2: 2
Group 3: null
Full match: x
Group 1: null
Group 2: null
Group 3: x
Full match: -1
Group 1: null
Group 2: -1
Group 3: null
Full match: 5
Group 1: null
Group 2: 5
Group 3: null
Full match: x
Group 1: null
Group 2: null
Group 3: x
Full match: ^3.23
Group 1: 3.23
Group 2: null
Group 3: null
Full match: -2012.12
Group 1: null
Group 2: -2012.12
Group 3: null
Full match: x
Group 1: null
Group 2: null
Group 3: x
Full match: 10.12
Group 1: null
Group 2: 10.12
Group 3: null
Full match: -5
Group 1: null
Group 2: -5
Group 3: null
Full match: x
Group 1: null
Group 2: null
Group 3: x
Full match: ^3.54
Group 1: 3.54
Group 2: null
Group 3: null
Full match: 2
Group 1: null
Group 2: 2
Group 3: null
Full match: x
Group 1: null
Group 2: null
Group 3: x
Full match: -1.512
Group 1: null
Group 2: -1.512
Group 3: null

Если вы хотите упростить / изменить / изучить выражение, это было объяснено на верхней правой панели regex101.com . При желании вы также можете посмотреть в эту ссылку , как она будет сопоставляться с некоторыми примерами входных данных.


RegEx Circuit

jex.im визуализирует регулярные выражения:

enter image description here

Пример 2

import java.util.regex.Matcher;
import java.util.regex.Pattern;


public class RegularExpression{

    public static void main(String[] args){

        final String regex = "\\^(-?\\d+(?:\\.\\d+)?)|(-?\\d+(?:\\.\\d+)?)|(x)";
        final String string = "12x^11 +10x^9 -8x^7 +9x^6 -5x^3 +2x -1";
        final Pattern pattern = Pattern.compile(regex);
        final Matcher matcher = pattern.matcher(string);

        while (matcher.find()) {
            System.out.println("Full match: " + matcher.group(0));
            for (int i = 1; i <= matcher.groupCount(); i++) {
                System.out.println("Group " + i + ": " + matcher.group(i));
            }
        }

    }
}

Вывод

Full match: 12
Group 1: null
Group 2: 12
Group 3: null
Full match: x
Group 1: null
Group 2: null
Group 3: x
Full match: ^11
Group 1: 11
Group 2: null
Group 3: null
Full match: 10
Group 1: null
Group 2: 10
Group 3: null
Full match: x
Group 1: null
Group 2: null
Group 3: x
Full match: ^9
Group 1: 9
Group 2: null
Group 3: null
Full match: -8
Group 1: null
Group 2: -8
Group 3: null
Full match: x
Group 1: null
Group 2: null
Group 3: x
Full match: ^7
Group 1: 7
Group 2: null
Group 3: null
Full match: 9
Group 1: null
Group 2: 9
Group 3: null
Full match: x
Group 1: null
Group 2: null
Group 3: x
Full match: ^6
Group 1: 6
Group 2: null
Group 3: null
Full match: -5
Group 1: null
Group 2: -5
Group 3: null
Full match: x
Group 1: null
Group 2: null
Group 3: x
Full match: ^3
Group 1: 3
Group 2: null
Group 3: null
Full match: 2
Group 1: null
Group 2: 2
Group 3: null
Full match: x
Group 1: null
Group 2: null
Group 3: x
Full match: -1
Group 1: null
Group 2: -1
Group 3: null
0 голосов
/ 14 октября 2019

Вот возможное решение, которое создает массив коэффициентов для каждого значения показателя (0 - константа). Он ищет либо постоянное значение, либо что-то в форме a x ^ y , где часть ^ y является необязательной. Переменная a должна иметь размер в соответствии с максимальным показателем, который вы ожидаете в уравнении.

int[] a = new int[4];
int exp, coeff;
String expr = "-5x^3 + 2x - 1";
Pattern pattern = Pattern.compile("((?:((?:^|\\s*[+-]\\s*)\\d*)x(?:\\^(\\d+))?)|(?:[+-]\\s*\\d+))");
Matcher matcher = pattern.matcher(expr);
while (matcher.find()) {
    if(matcher.group(1).matches("[+-]\\s*\\d+")) {
        // the constant part
        a[0] = Integer.parseInt(matcher.group(1).replace(" ", ""));
    }
    else {
        // a variable part
        coeff = (matcher.group(2) != "") ? Integer.parseInt(matcher.group(2).replace(" ", "")) : 1;
        exp = (matcher.group(3) != "" && matcher.group(3) != null) ? Integer.parseInt(matcher.group(3)) : 1;
        a[exp] = coeff;
    }
}
System.out.println(Arrays.toString(a));

Выход (для этого примера)

[-1, 2, 0, -5]

Демонстрация на rextester

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