5

给定一个具有单个变量 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;
    }
}
4

6 回答 6

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
于 2013-08-22T17:16:41.273 回答
1

此代码替换应该会有所帮助

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

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

于 2013-08-22T17:02:51.797 回答
1
  1. 您需要考虑最后一项(if 语句仅在找到-or时触发+,最后没有)。

    一种简单的方法是替换:

    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为此得到一个。处理它的一种方法是忽略+术语之间的(而不是+在开头添加 a ):

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

测试

于 2013-08-22T17:04:29.330 回答
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;
    }
}
于 2013-08-22T17:32:29.657 回答
0

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

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

效果是您将 subStr 设置为- 或 +之前的文本,并对其进行评估。但由于字符串末尾没有 - 或 +,因此该逻辑无法评估多项式的​​最后一项,因为它只评估在 - 或 + 之前的子字符串。

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

于 2013-08-22T17:01:41.103 回答
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语句的更改并添加了我上面评论中提到的更改

于 2013-08-22T17:02:30.853 回答