javaregexpolynomials

Decode polynomial from String with Pattern and Matcher


I am tryng to decode each individual monomials in a String representing a polynomial.

public static void main(String[] args) {
    String polynomial = "3x^3-x^2+5.9x-3.8";
    String monomialFormat = "([+-]?[\\d\\.]*[a-zA-Z]?\\^?\\d*)", monomialPartsFormat = "([+-]?[\\d\\.]*)([a-zA-Z]?)\\^?(\\d*)";

    Pattern p1 = Pattern.compile(monomialFormat);
    Matcher m1 = p1.matcher(polynomial);

    while (!m1.hitEnd()) {
        m1.find();
        Pattern p2 = Pattern.compile(monomialPartsFormat);
        System.out.print(m1.group() + "   ->   ");
        Matcher m2 = p2.matcher(m1.group());

        float coefficient;
        try {
            coefficient = Float.valueOf(m2.group(1));
        } catch (IllegalStateException e) {
            coefficient = 0.0F;
        }
        int exponent;
        try {
            exponent = Integer.valueOf(m2.group(3));
        } catch (IllegalStateException e) {
            exponent = 0;
        }
        char variable;
        try {
            variable = m2.group(2).charAt(0);
        } catch (IllegalStateException e) {
            variable = '_';
        }

        System.out.println("" + coefficient + variable + "^" + exponent);
    }
}

The first pattern works correctly and cut the polynomial into several monomials, but not the second one. No matches are found for the differents parts of each monomial (coefficient, variable, exponent). There must be something wrong in the second regex but I can't find it.

Results of the prints :

3x^3   ->   0.0_^0
-x^2   ->   0.0_^0
+5.9x   ->   0.0_^0
-3.8   ->   0.0_^0

Solution

  • Your regex was correct. The major problem was the missing m2.find() before grabbing the groups. You were also missing some additional checks when casting the monomial elements, so I just included a small function to help.

    public static void main(String[] args) {
    
        String polynomial = "3x^3-x^2+5.9x-3.8";
        String monomialFormat = "([+-]?[\\d\\.]*[a-zA-Z]?\\^?\\d*)", monomialPartsFormat = "([+-]?[\\d\\.]*)([a-zA-Z]?)\\^?(\\d*)";
    
        Pattern p1 = Pattern.compile(monomialFormat);
        Matcher m1 = p1.matcher(polynomial);
    
        while (!m1.hitEnd()) {
            m1.find();
            Pattern p2 = Pattern.compile(monomialPartsFormat);
            System.out.print(m1.group() + "   ->   ");
            Matcher m2 = p2.matcher(m1.group());
    
            if (m2.find()) {     
    
                float coefficient;
                try {
                    String coef = m2.group(1);
                    if (isNumeric(coef)) {
                        coefficient = Float.valueOf(coef);
                    } else {
                        coefficient = Float.valueOf(coef + "1");
                    }
                } catch (IllegalStateException e) {
                    coefficient = 0.0F;
                }
    
                int exponent;
                try {
                    String exp = m2.group(3);
                    if (isNumeric(exp)) {
                        exponent = Integer.valueOf(exp);
                    } else {
                        exponent = 1;
                    }
                } catch (IllegalStateException e) {
                    exponent = 0;
                }
    
                String variable = m2.group(2);
    
                System.out.println("" + coefficient + variable + "^" + exponent);
            }
        }
    }
    
    public static boolean isNumeric(String str) {
    
        return str.matches("[+-]*\\d*\\.?\\d+");
    }
    

    Output:

    3x^3   ->   3.0x^3
    -x^2   ->   -1.0x^2
    +5.9x   ->   5.9x^1
    -3.8   ->   -3.8^1