8

I have to write a read method for a quadratic class where a quadratic is entered in the form ax^2 + bx + c. The description for the class is this:

Add a read method that asks the user for an equation in standard format and set the three instance variables correctly. (So if the user types 3x^2 - x, you set the instance variables to 3, -1, and 0). This will require string processing you have done before. Display the actual equation entered as is and properly labeled as expected output.

I was able to do the ax^2 part by using string manipulation and if else statements. But I am not sure how to do the bx and c parts of the equation because of the sign that could be in front of bx and c. Here is how I did the ax^2 part of the method.

public void read()
{
    Scanner keyboard = new Scanner(System.in);
    System.out.println("Please enter a quadratic equation in standard format.");
    String formula = keyboard.next();
    String a = formula.substring(0, formula.indexOf("x^2"));
    int a2 = Integer.parseInt(a);
    if (a2 == 0)
    {
        System.out.println("a = 0");
    }
    else if (a2 == 1)
    {
        System.out.println("a = 1");
    }
    else
    {
        System.out.println("a = " + a2);
    }
 }

Feel free to write any code as an example. Any help would be greatly appreciated.

araknoid
  • 2,805
  • 4
  • 30
  • 32
user007
  • 91
  • 1
  • 5
  • 4
    What if you had a quadratic that was -2x^2+3x-1, or -2x^2, or -x^2+3? How would you consider handling those cases? – Makoto Feb 28 '13 at 06:18
  • thats the point of the if else statements, my program would work for the first 2 equations but I just did some further testing and it didn't work for the last -x^2+3 equation so I have some more coding to do for that part to I guess. – user007 Feb 28 '13 at 06:36
  • 4
    My point was more towards the edge cases. You have to be very cautious of those, and account for them. Ultimately, you're doing the same consumption operations on each part of the string separated by an operator. That's a hint. Another hint is, if you visit [this Debuggex link](http://www.debuggex.com/?re=%28%28%28-%7C%2B%29%3F%29%28%5Cd%2Bx%3F%7C%28x%7B1%7D%5C%5E%5Cd%2B%29%29%29%2B&str=x%5E4-3x%5E2%2B17), you'll see a general flow of what you want to do (in regex). – Makoto Feb 28 '13 at 06:57
  • Maybe using [Regular Expression](http://docs.oracle.com/javase/tutorial/essential/regex/) to extract the 3 components of the equation and then treat them separately would be better but not that much expert about RegExp to provide an example... – araknoid Feb 28 '13 at 17:29
  • @Makoto: you're missing two '\' in the first group before the minus and plus signs. The [correct regex](http://www.debuggex.com/?re=%28%28%28%5C-%7C%5C%2B%29%3F%29%28%5Cd%2Bx%3F%7C%28x%7B1%7D%5C%5E%5Cd%2B%29%29%29%2B&str=x%5E4-3x%5E2%2B17). – harpun Feb 28 '13 at 18:06
  • @harpun: I never *did* say that the regex was correct...merely that it outlined a general flow of what you want to accomplish. – Makoto Feb 28 '13 at 18:14
  • Would that class work if say 13x^2? And how would the sub terms then work? – user007 Feb 28 '13 at 19:11

3 Answers3

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


public class Mini {

    public static void main(String[] args) {
        int a = 0;
        int b = 0;
        int c = 0;

    String formula = " -x^2 + 6x - 5";
    formula = formula.replaceAll(" ", "");

    if (!formula.startsWith("+") && !formula.startsWith("-"))
        formula = "+" + formula;

        String exp = "^((.*)x\\^2)?((.*)x)?([\\+\\s\\-\\d]*)?$";
        Pattern p = Pattern.compile(exp);
        Matcher m = p.matcher(formula);

        System.out.println("Formula is " + formula);
        System.out.println("Pattern is " + m.pattern());

        while (m.find()) {
            a = getDigit(m.group(2));
            b = getDigit(m.group(4));
            c = getDigit(m.group(5));
        }

        System.out.println("a: " + a + " b: " + b + " c: " + c);

    }

    private static int getDigit(String data) {
        if (data == null) {
            return 0;
        } 
        else 
        {

            if (data.equals("+"))
            {
                return 1;
            }
            else if (data.equals("-"))
            {
                return -1;
            }
            else
            {
                try
                {
                    int num = (int) Float.parseFloat(data);
                    return num;
                }
                catch (NumberFormatException ex)
                {
                    return 0;
                }
            }
        }
    }
}
orak
  • 2,159
  • 5
  • 27
  • 51
  • Hey Orak thanks for your help. I tested your program and it does not seem to work when a quadratic such as x^2 + x - 3 is input. The class has to set a and b equal to 1 when that type of quadratic occurs. – user007 Feb 28 '13 at 21:42
  • @user2118379 add an explicit + at the beginning if not found...thanks for correction :) – orak Mar 01 '13 at 02:16
1

Here's an example of how you could do it using a regular expression. So far this only works properly if the equation is given in the format ax^2 + bx + c. It could be tweaked further to allow for changing the order of the sub-terms, missing terms, etc. To do this I would probably try to come up with regular expressions for each sub-term. Anyway, this should serve to give you the general idea:

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

class ParseEquation {
    static Pattern match = Pattern.compile("([\\+\\-]?[0-9]*)x\\^2([\\+\\-]?[0-9]*)x([\\+\\-]?[0-9]*)");

    static String parseEquation(String formula) {
        // remove all whitespace
        formula = formula.replaceAll(" ", "");
        String a = "1";
        String b = "1";
        String c = "0";
        Matcher m = match.matcher(formula);
        if (!m.matches()) return "syntax error";
        a = m.group(1);
        if (a.length() == 0) a = "1";
        if (a.length() == 1 && (a.charAt(0) == '+' || a.charAt(0) == '-')) a += "1";
        b = m.group(2);
        if (b.length() == 0) b = "1";
        if (b.length() == 1 && (b.charAt(0) == '+' || b.charAt(0) == '-')) b += "1";
        c = m.group(3);
        return a + "x^2" + b + "x" + c;
    }

    public static void main(String[] args) {
        System.out.println(parseEquation("2x^2 + 3x - 25"));
        System.out.println(parseEquation("-2x^2 + 3x + 25"));
        System.out.println(parseEquation("+2x^2 + 3x + 25"));
        System.out.println(parseEquation("x^2 + 3x + 25"));
        System.out.println(parseEquation("2x^2 + x + 25"));
    }
}
ahans
  • 1,602
  • 12
  • 18
1

Via regular expressions:

sub quadParse {
    my ($inputStr) = @_;
    my $str = "+".$inputStr;        # as the first needn't have a sign
    $str =~ s/\s+//g;               # normalise
    my $squared = $1 if ($str =~ m/([+-][0-9])*x\^2/);
    my $ex = $1 if ($str =~ m/([+-][0-9]*)x(?!\^)/);
    my $const = $1 if ($str =~ m/([+-][0-9]+)(?!x)/);
    return "${squared}, ${ex}, ${const}";
}

For string parsing, Perl.

Oh, go on then:

public static String coeff(String str, String regex) {
    Pattern patt = Pattern.compile(regex);
    Matcher match = patt.matcher(str);
    // missing coefficient default
    String coeff = "+0"; 
    if(match.find()) 
        coeff = match.group(1);
    // always have sign, handle implicit 1
    return (coeff.length() == 1) ? coeff + "1" 
        : coeff;
}
public static String[] quadParse(String arg) {
    String str = ("+" + arg).replaceAll("\\s", "");
    String quad = coeff(str, "([+-][0-9]*)x\\^2" );
    String ex = coeff(str, "([+-][0-9]*)x(?!\\^)");
    String cnst = coeff(str, "([+-][0-9]+)(?!x)" );
    return new String[] {quad, ex, cnst};
}

Java test in ideone.

These handle the formula in any order, with or without initial sign on the first term, and handle missing terms correctly. The Perl version doesn't fix '+' to '+1' etc, or supply an explicit '0' for missing terms, because I've run out of time.

Phil H
  • 18,593
  • 6
  • 62
  • 99