在不使用正则表达式和API的情况下评估多项式字符串

时间:2013-08-22 16:45:25

标签: java polynomial-math

给定具有单个变量x的多项式,并将x的值作为输入,计算其值。例子:

eval("-2x^3+10x-4x^2","3")=-60

eval("x^3+x^2+x","6")=258

问题描述:在这段代码中,无论何时遇到+/-,我都会将字符串分解为子字符串,并将子字符串传递给评估单个术语的函数,如“-2x ^ 3”。所以我输入的代码=“ - 2x ^ 3 + 10x-4x ^ 2”只计算到“-2x ^ 3 + 10x”并跳过“-4x ^ 2”部分。

有人可以告诉我这里有什么不对吗?

public class EvalPolyX2 {

    static String testcase1 = "-2x^3+10x-4x^2";
    static String testcase2 = "3";

    public static void main(String args[]){
        EvalPolyX2 testInstance = new EvalPolyX2();
        int result = testInstance.eval(testcase1,testcase2);
        System.out.println("Result : "+result);
    }

    public int eval(String str,String valx){

        int sum = 0;        
        String subStr = "";
        if(str.charAt(0) == '-')
        {
            int len = str.length();
            for (int i = 0; i < len; i++)
            {
                if(str.charAt(i) == '-' || str.charAt(i) == '+')
                {                   
                    subStr = str.substring(0, i);
                    System.out.println("subStr="+subStr);
                    sum += evalSubPoly(subStr, valx);
                    str = str.substring(i);
                    len = str.length();
                    i = 0;
                }               
            }
        }
        else if(str.charAt(0) != '-')
        {
            str = '+' + str;
            int len = str.length();
            for (int i = 0; i < len; i++)
            {
                if(str.charAt(i) == '-' || str.charAt(i) == '+')
                {
                    subStr = str.substring(0, i);
                    System.out.println("subStr="+subStr);
                    sum += evalSubPoly(subStr, valx);
                    str = str.substring(i);
                    len = str.length();
                    i=0;
                }
            }
        }
        return sum;
    }

    public int evalSubPoly(String poly,String valx){
        int len = poly.length();
        String num = "";
        String power = "";
        int exp = 0, coeff = 0;

        for(int i = 0; i < len; i++)
        {
            if(poly.charAt(i) == 'x')
            {
                num = poly.substring(0, i);
                coeff = Integer.parseInt(num);                              
            }
            if(poly.charAt(i) == '^')
            {
                power = poly.substring(i+1, len);
                exp = Integer.parseInt(power);
            }                       
        }

        if(power.equals(""))
            exp = 1;
        System.out.println("coeff="+coeff);

        int sum = 1;
        int x = Integer.parseInt(valx);

        for (int i = 0; i < exp; i++)
        {
            sum = sum*x;
        }
        System.out.println("sum="+sum);
        sum = sum*coeff;

        return sum;
    }
}

6 个答案:

答案 0 :(得分:2)

使用正则表达式有什么问题?您可以将多项式拆分为单项式,评估每项,并添加所有结果。

private static final Pattern monomial = Pattern
        .compile("([+-])?(\\d+)?x(?:\\^(\\d+))?");

public static int eval(String str, String valx) {
    Matcher m = monomial.matcher(str);
    int x = Integer.parseInt(valx);

    int total = 0;
    while (m.find()) {
        String mul = m.group(2);
        int value = (mul == null) ? 1 : Integer.parseInt(m.group(2));

        String pow = m.group(3);
        value *= (pow == null) ? x : (int) Math.pow(x,
                Integer.parseInt(pow));

        if ("-".equals(m.group(1)))
            value = -value;

        total += value;
    }

    return total;
}

System.out.println(eval("-2x^3+10x-4x^2", "3"));
System.out.println(eval("x^3+x^2+x", "6"));
-60
258

答案 1 :(得分:1)

此代码替换应该有帮助

  if(str.charAt(i) == '-' || str.charAt(i) == '+' || i == (len - 1))
  {   
    if(i == len - 1)
    {
     i++;
    }
    ...

虽然可能有更好的方法,但我只是想在这里展示一条出路。 原因是你正在寻找+或 - 作为分隔符。 但是表达式的最后一部分不会以这两种方式结束,而只是EOL

答案 2 :(得分:1)

  1. 您需要考虑最后一个字词(if语句只会在找到-+时触发,而最后一个字段不存在。

    一种简单的方法是替换:

    for (int i = 0; i < len; i++)
    {
        if (str.charAt(i) == '-' || str.charAt(i) == '+')
    

    使用:

    //                 v one more iteration
    for (int i = 0; i <= len; i++)
    {
        if (i == len || str.charAt(i) == '-' || str.charAt(i) == '+')
    //      \------/
    //   extra condition
    

    上面简单地继续进行一次迭代,在那次迭代中,总是进入if语句,导致最后一个术语被处理。

  2. 您还可以简化

    if (str.charAt(0) == '-')
    {
      // common code
    }
    else if (str.charAt(0) != '-')
    {
      str = '+' + str;
      // common code
    }
    

    要:

    if (str.charAt(0) != '-')
    {
      str = '+' + str;
    }
    // common code
    
  3. 还有处理+的错误。我得到了NumberFormatException。处理它的一种方法是忽略术语之间的+(而不是在开头添加+):

    if (i != len && str.charAt(i) == '+')
      str = str.substring(i+1);
    else
      str = str.substring(i);
    
  4. 您也可以使用static函数直接调用它们,而不是声明您的类的新实例。

  5. Test

答案 3 :(得分:0)

简单的答案就是当你这样做时:

           if(str.charAt(i) == '-' || str.charAt(i) == '+')
            {
                subStr = str.substring(0, i);

效果是你在 - 或+之前将subStr设置为文本并进行评估。但是由于字符串末尾没有 - 或+,这个逻辑不会评估多项式的​​最后一项,因为它只评估在 - 或+之前的子字符串。

P.S。这只是我注意到的一个问题。我不知道其余逻辑是否正确。

答案 4 :(得分:0)

解析字符串时,您会查找+/-并且只有在找到它们时才会停止。这适用于前两个术语,但是当你达到“-4x ^ 2”时,循环将不会停止,因为没有+/-。因此,除了条件之外,还需要添加代码,以便在到达字符串末尾时,剩下的就是最后一个术语。所以你想拥有的是这个

if(str.charAt(0) == '-')
    {
        int len = str.length();
        for (int i = 0; i < len; i++)
        {
            if(str.charAt(i) == '-' || str.charAt(i) == '+')
            {                   
                subStr = str.substring(0, i);
                System.out.println("subStr="+subStr);
                sum += evalSubPoly(subStr, valx);
                str = str.substring(i+1);
                len = str.length();
                i = 0;
            }               
        }
        System.out.println("subStr="+str);
        sum += evalSubPoly(str, valx);
    }


    else if(str.charAt(0) != '-')
    {
        str = '+' + str;
        int len = str.length();
        for (int i = 0; i < len; i++)
        {
            if(str.charAt(i) == '-' || str.charAt(i) == '+')
            {
                subStr = str.substring(0, i);
                System.out.println("subStr="+subStr);
                sum += evalSubPoly(subStr, valx);
                str = str.substring(i+1);
                len = str.length();
                i=0;
            }
        }
        System.out.println("subStr="+str);
        sum += evalSubPoly(str, valx);
    }

我还会抛弃可能存在更多错误的免责声明,但这是导致您出现问题的主要错误。

编辑:将更改添加到else if语句并添加了上述评论中提到的更改

答案 5 :(得分:0)

使用正则表达式,您可以获得更简单的解决方案。而且,你想要支持简单的常量吗?尝试下一个:

public class EvalPolyX2 {
    public static void main(String args[]) {
        System.out.println("Result: " + eval("x^3+x^2+x", 6));
    }
    public static int eval(String eq, int val) {
        int result = 0;
        String mons[] = eq.split("(?=[+-])(?!\\B)");
        for (String str : mons) {
            str = str.replace("+", "");
            if (str.contains("x")) {
                double a = 1, b = 1;
                String[] comps = str.split("x\\^?");
                if (comps.length > 0) {
                    a = comps[0].isEmpty() ? 1 : Integer.parseInt(comps[0]);
                }
                if (comps.length > 1) {
                    b = Integer.parseInt(comps[1]);
                }
                result += a * Math.pow(val, b);
            } else {
                result += Integer.parseInt(str);
            }
        }
        return result;
    }
}