每日算法20210316:字符串表达式求解

朴素法求解字符串表达式

package AlogPub.first;
public class StringExpression {
    // 字符串表达式的计算
    //a+b*(c-d)+e
    //朴素算法
    private int anwser;
    private int[] num;
    private char[] exp;
    private char[] expression;
    public StringExpression(char[] car){
        this.expression=car;
        this.num=new int[car.length/2+1];
        this.exp=new char[car.length/2];
    }
    private void add_sub(){
        this.anwser=num[0];
        for (int i = 0; i < exp.length; i++) {
            if(exp[i]=='+'){
                this.anwser+=num[i+1];
            }
            if(exp[i]=='-'){
                this.anwser-=num[i+1];
            }
        }
    }
    private void multiply(){
        int j=0;
        for (int i = 0; i < exp.length; i++) {
            if(exp[i]!='*' && exp[i]!='/'){
                j=0;
                continue;
            }
            if(exp[i]=='*'){
                num[i-j]*=num[i+1];
            }
            j++;
        }
    }
    private void separate(){
        int j=0;
        int k=0;
        for (int i = 0; i < expression.length; i++) {
            if(i%2==0){
                num[j++]=expression[i]-'0';
            }
            if(i%2==1){
                exp[k++]=expression[i];
            }
        }       
    }
    private int calc(){
        separate();
        multiply();
        add_sub();
        return this.anwser;
    }
    public static void main(String[] args) {
        String s="9+8*6-7+6";
        StringExpression se=new StringExpression(s.toCharArray());
        System.out.println(se.calc());
    //  String[]   strings=s.split("[0-9]{1,}");
    // String[]   strings=s.split("\\PL+");
    //  for (int i = 0; i < strings.length; i++) {
    //     System.out.println(strings[i]);
    //  }
    }
}

逆波兰式求解字符串表达式

package AlogPub.first;
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;

public class NiBoLan {
    //逆波兰表达式
    /**
     * 1 遍历字符串  如果是数字直接输出
     * 2 如果是操作符   若stack为空 和 (和大于栈顶操作符权限 pull  小于等于操作符权限  输出
     * 3 如果是( pull  如果是右 )  若栈顶是( 输出  否则输出栈元素 知道输出 (
     */
    public List<String> ChangeToNiBoLan(String str){
        Stack<String> stack=new Stack<>();
       String[] cs=stringToCharArray(str);
       List<String> resList=new ArrayList<>();  //存放表达式
       //区分数字和操作符
     
       for (int i = 0; i < cs.length; i++) {
        if(cs[i].matches("[0-9]")){
            //遇到操作数
            //组装操作数
            StringBuilder sb=new StringBuilder();
            
            while((i)<str.length()&&cs[i].matches("[0-9]")){
                sb.append(cs[i]);
                i++;
            }
           i--;
            //直接输出
            resList.add(sb.toString());
        
        }else{
            //不是操作数  是操作符时
            //遇到 (  直接入栈
            //否则 遇到 ) 查看栈顶是否时(  是 ( 出栈  否则:不是 栈顶元素出栈   直到遇到( 出栈
            //否则 其他情况  即 是 + - * / 栈是空  进栈  否则:栈顶元素是 ( 直接进栈  否则:比较该操作符 与栈顶操作符的优先级 大于 进栈  小于等于 栈顶元素出栈 知道大于栈顶元素
            if("(".equals(cs[i])){
                stack.push(cs[i]);
            }else if(")".equals(cs[i])){
                while(true){
                    if("(".equals(stack.peek())){
                        stack.pop();
                        break;
                    }else{
                        resList.add(stack.pop());
                    }
                }
            }else{
                while(true){
                    if(stack.isEmpty()){
                        stack.push(cs[i]);
                        break;
                    }else if("(".equals(stack.peek())){
                        stack.push(cs[i]);
                        break;
                    }else {
                        if(numPri(cs[i])>numPri(stack.peek())){
                            stack.push(cs[i]);
                            break;
                        }else{
                            if(numPri(cs[i])<=numPri(stack.peek())){
                                resList.add(stack.pop());
                            }else{
                                resList.add(cs[i]);
                                break;
                            } 
                        }
                    }
                }
            }
        }
       }
       while(!stack.isEmpty()){
           resList.add(stack.pop());
       }
       return resList;
    }
    public Double cala(List<String> list){
        Stack<Double> opr=new Stack<>();
        list.forEach(v->{
            //if 是数  进栈  else  取出两个数运算  结果进栈  
            if(v.matches("[0-9]{1,}")){
                opr.push(Double.valueOf(v));
            }else{
                opr.push(jisuan(opr.pop(),opr.pop(), v));
            }
        });
        return opr.pop();
    }
    public Double jisuan(Double a,Double b,String exp){
        if("*".equals(exp)){
            return b*a;
        }else if("/".equals(exp)){
            return b/a;
        }else if("+".equals(exp)){
            return a+b;
        }else{
            return b-a;
        }
    }
    public String[] stringToCharArray(String str){
        char[] cs=str.toCharArray();
        String[] res=new String[str.length()];
       for (int i = 0; i < res.length; i++) {
           res[i]=cs[i]+"";
       }

     return res;
    }
    private int numPri(String num){
        if("+".equals(num)||"-".equals(num)){
            return 0;
        }else{
            return 1;
        }
    }
   public static void main(String[] args) {
    //  String str="2-3*(15+6)";
    String str="288-3*(15+6)";
     NiBoLan niBoLan=  new NiBoLan();
    String[] strings= niBoLan.stringToCharArray(str);
    for (int i = 0; i < strings.length; i++) {
        System.out.println(strings[i]);
    }
    System.out.println("========");
   List<String> list= niBoLan.ChangeToNiBoLan(str); 
   for (int i = 0; i < list.size(); i++) {
    System.out.println(list.get(i));
}
Double d= niBoLan.cala(list);
   System.out.println(d);
   } 
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值