UDN-企业互联网技术人气社区

板块导航

浏览  : 3025
回复  : 6

[小米] 现有一四则运算表达式,仅包含+-*/()和0~9数字,请设计一个算法,计算该表达式的值。

[复制链接]
很黄很暴力的头像 楼主
发表于 2015-5-29 11:07:18 | 显示全部楼层 |阅读模式
现有一四则运算表达式,仅包含+-*/()和0~9数字,请设计一个算法,计算该表达式的值。
其中+-只作为运算符出现,不作为正负符号出现在表达式中。
发表于 2015-5-29 12:21:59 | 显示全部楼层

  c++递归下降分析器的解法,语法规则:
  expr   = term   [+- term]...
term   = factor [*/ factor]...
  factor = number | (expr)
  

  5块钱的代码,没有语法错误处理,零除检查,大数什么的:)
  

[b][i][u][color=#ff0000][code]float expr(char* s, int& pos);
float term(char* s, int& pos);
float factor(char* s, int& pos);
float number(char* s, int& pos);
float expr(char* s, int& pos) {
        float v = term(s, pos);
        while (s[pos] == '+' || s[pos] == '-') {
                if (s[pos++] == '+')
                        v += term(s, pos);
                else
                        v -= term(s, pos);
        }
        return v;
}
float term(char* s, int& pos) {
        float v = factor(s, pos);
        while (s[pos] == '*' || s[pos] == '/') {
                if (s[pos++] == '*')
                        v *= factor(s, pos);
                else
                        v /= factor(s, pos);
        }
        return v;
}
float factor(char* s, int& pos) {
        if (s[pos] == '(') {
                pos++;
                float v = expr(s, pos);
                pos++;
                return v;
        } else {
                return number(s, pos);
        }
}
float number(char* s, int& pos) {
        int n = 0;
        while (s[pos] >= '0' && s[pos]
使用道具 举报

回复

发表于 2015-5-29 13:12:35 | 显示全部楼层

  import java.io.BufferedReader;
import java.io.IOException;
  import java.io.InputStreamReader;
import java.math.BigDecimal;
  import java.util.ArrayList;
import java.util.Iterator;
import
  java.util.List;
  /**
  * 实现字符串输入之后的四则运算
  * @author Administrator
  *
   */
public class Math {
  
  public static void
  main(String[] args) throws IOException {
   BufferedReader br = new
  BufferedReader(new InputStreamReader(System.in));
    resultShow(br);
//  System.out.println(9-7*8);
  //  System.out.println(getResult("9-7*8"));
  }
  
   public static void resultShow(BufferedReader br) throws
  IOException{
   System.out.print("请输入计算式:");
    //开始接受用户指令
   String str = br.readLine();
   try {
     double result = getResult(str);
    if((double)0 == result -
  (int)result){
      System.out.println("计算后得出的结果为:"+(int)result);
     }else{
      System.out.println("计算后得出的结果为:"+result);
    }
    } catch (Exception e) {
    // TODO Auto-generated catch
  block
    e.printStackTrace();
     System.out.println("您输入的公式不正确!请重新输入");
     resultShow(br);
   }
  }
  
  /**
   *
  首先将计算式转换为Object数组,数字转为int,符号为String
   * @param expr
   *
  @return
   */
  public static double getResult(String expr){
    //转换char数组
   char[] cs = expr.toCharArray();
    //转换后存放公式内容的容器
   ListintData = new
  ArrayList();
   //这个对象用来存放一串连续数字的char字符
    List temp = new ArrayList();
    for (int i = 0; i = 0 && (i==cs.length-1 ||
  ((int)cs[i+1] - 48  temp){
   String
  s = "";
   for (Iterator i = temp.iterator();
  i.hasNext();) {
    Character character = (Character) i.next();
     s += character;
   }
   
   return
  Double.parseDouble(s);
  }
  
  public static double
  getActualResult(Object[] cs){
   return kuohaoMath(cs);
  }
   
  /**
   * 带括号计算,使用递归
   */
  public static  double
  kuohaoMath(Object[] cs){
   //找到扩号符的索引,正反括号
   int[]
  indexe敏感词indKuohaoIndex(cs);
   if(indexes != null){
     Object[] temp = new Object[indexes[1]-indexes[0]-1];
     //截获括号里面的内容数组
    for (int i = 0; i  tempData = new ArrayList();
     for (int i = 0; i =0; j--) {
      if(cs[j].equals("(")){
        indexes[0] = j;
       break;
      }
     }
      break;
    }
   }
   
   return indexes;
  }
   
  /**
   * 不包括括号运算的,普通运算算法
   */
  public static double
  normalMath(Object[] cs){
   int index = -1;
    //先乘法或除法,找到*,/的索引位置
   index = findMultiplication(cs);
    if(index >= 0){
    List tempData = new
  ArrayList();
    //计算符号附近相邻值得结果
    double result
  = 0;
    if(cs[index].equals("*")){
     result =
  (Double)cs[index-1] *  (Double)cs[index+1];
    }else{
      result = (Double)cs[index-1] / (Double)cs[index+1];
    }
     //添加到新容器
    for (int i = 0; i = 0){
    List tempData = new
  ArrayList();
    //计算符号附近相邻值得结果
    double result
  = 0;
    if(cs[index].equals("+")){
     result =
  (Double)cs[index-1] +  (Double)cs[index+1];
    }else{
      result =  (Double)cs[index-1] -  (Double)cs[index+1];
    }
     for (int i = 0; i
                                                        
使用道具 举报

回复

发表于 2015-5-29 15:13:10 | 显示全部楼层

  我用java实现
  //f1处理输入字符串,采用递归的方式处理 括号优先级问题。
String f1(String str){
int
  index=str.indexOf("(");
int
  fIndex=str.lastIndexOf(")");
  if(index>=0&&fIndex>=0){
String
  str1=str.subString(0,index);
String
  str2=str.subString(index,fIndex);
String
  str3=str.subString(fIndex);
str2=f1(str2);
  str=str1+str2+str3;
}
return cal(str);
}
  
//cal将减号变成负号,加减则都是 加号,再split分割。分割后的数组是乘或除,再调用函数下面的处理
String
  cal(String str){
//   * /    + -
float sum=0;
String
  strA[]=str.split("-");
str=null;
for(int
  i=0;i0)
  strA[i]=calChu(strA[i]);//如果除,则计算除
  num*=StringToFloat(strA[i]);
}
return  FloatToString(num);
  }
//处理除
String calChu(String str){
  String strA[]=
  str.split("/");
float num;
for(int
  i=0;i0)
  num/=StringToFloat(strA[i]);
else
  num=StringToFloat(strA[i]);
}
return  FloatToString(num);
}
  
  
public static void main(String args[]) {
           Scanner
  input = new Scanner(System.in);
         String val = null;      
  // 记录输入的字符串
             System.out.print("请输入:");
  
            val = input.nextLine();   
  
   try{  //以上方法皆未捕捉异常,这里进行捕捉一下,更严谨一些
        
  System.out.println("结果是:"+f1(val));
    }catch{
  
   System.out.println("输入有误");
   }
        
  input.close(); // 关闭资源
     }
  }
  

                                                        
使用道具 举报

回复

发表于 2015-5-29 16:16:58 | 显示全部楼层

  我是用C#实现的:
  private void button1_Click(object sender, EventArgs e)
         {
             string text = this.textBox1.Text.Trim();
             char[] charArray = text.ToCharArray();
             List stringArray = charToList(charArray);
             int cacuResult = caculateExpression(stringArray);
             textBox2.Text = cacuResult.ToString();
         }

         //数据预处理
         /*
          因为表达式【(1+2)*3*(23+6)/9+4】中包含数字23,被转化为char数组后,2和3是分开的,所以要合并到一起
          */
         private List charToList(char[] charArray)
         {
             List result = new List();
             string[] opreators = new string[] { "+",
"-", "*", "/", "(",
")" };

             string temp = "";
             for (int i = 0; i  charArray)
         {
             int result = 0;

             //要考虑【乘法】和【除法】的优先级
             //优先计算【乘法】和【除法】
             string[] opreatorArray = new string[] { "*",
"/", "+", "-" };

             for (int i = 0; i  charArray)
         {
             int result = 0;
             //如果表达式不包含括号,则认为是简单表达式,直接返回结果
             if (charArray.IndexOf("(") == -1)
             {
                 result = caculateSimpleExpression(charArray);
                 return result;
             }

             //处理括号问题
             while (charArray.IndexOf("(") != -1)
             {
                 //有多少个左括号,一定就有多少个右括号与之对应

                 //按照左括号的位置从右往左计算
                 int leftIndex = 0;//位置最靠右的左括号
                 int tempIndex = charArray.IndexOf("(");
                 while (tempIndex != -1)
                 {
                     leftIndex = tempIndex;
                     tempIndex = charArray.IndexOf("(",
leftIndex + 1);
                 }

                 int rightIndex = charArray.IndexOf(")",
leftIndex + 1); ;//找出离该左括号最近的右括号

                 List tempStringArray = new List();//暂存数组
                 //左括号和右括号之间的元素,我们放入到暂存数组里面,这里面应该是一个简单表达式。可以直接计算
                 for (int i = leftIndex + 1; i
使用道具 举报

回复

发表于 2015-5-29 18:38:38 | 显示全部楼层

用栈,两个栈,一个存数字,一个存操作符,根据操作符的优先级来进行进栈和出栈的操作
                                                        
使用道具 举报

回复

发表于 2015-5-29 19:43:43 | 显示全部楼层

逆波兰表达式
使用道具 举报

回复

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关于我们
联系我们
  • 电话:010-86393388
  • 邮件:udn@yonyou.com
  • 地址:北京市海淀区北清路68号
移动客户端下载
关注我们
  • 微信公众号:yonyouudn
  • 扫描右侧二维码关注我们
  • 专注企业互联网的技术社区
版权所有:用友网络科技股份有限公司82041 京ICP备05007539号-11 京公网网备安1101080209224 Powered by Discuz!
快速回复 返回列表 返回顶部