Java计算器核心算法代码实现

在进行一个表达式的计算时,先将表达式分割成数字和字符串然后利用出入栈将分割后的表达式进行中缀转后缀,再将后缀表达式进行计算得到结果(思想在上一篇写过)现在贴下Java语言的代码实现。(学习Java时间不长所以可能会有很多不足的地方,我会改进也欢迎大神可以给我一些意见和建议~谢谢啦)

我将这部分分成三个方法完成功能,并在getResult方法调用(getResult方法被主方法调用)

private String getResult(String str) {
    //分割
    String[] Str = segment(str);
    //中缀转后缀
    String newStr = infToSuf(Str);
    //后缀计算
    String result = sufToRes(newStr);
    return sufToRes(result);
  }

1.字符串分割,为避免在TextView上显示带空格删除时不方便而且显示屏就那么大占地方,录入时的字符串中没有空格然后就手动分割了

private static String[] segment(String str) {
    String[] exp = new String[str.length()+1];
    //找最近的索引并截取字符串
    int l = str.length();
    for(int i = 0;i < l+1;i++) {
      int index;
      int[] ind = new int[6];
      ind[0] = str.indexOf('+');
      ind[1] = str.indexOf('-');
      ind[2] = str.indexOf('*');
      ind[3] = str.indexOf('/');
      ind[4] = str.indexOf('(');
      ind[5] = str.indexOf(')');
      if(ind[1] == 0) {
        Arrays.sort(ind);
        int t;
        for(t = 0;t <6;t++) {
          if(ind[t] >= 0)
            break;
        }
        int r = ind[t+1];
        exp[i] = str.substring(0,r);
        i++;
        exp[i] = str.substring(r,r+1);
        str = str.substring(r+1);
      }else if(((ind[1]-ind[4]) == 1) && (ind[4]==0)) {
        Arrays.sort(ind);
        int t ;
        for(t = 0;t <6;t++) {
          if(ind[t] >= 0)
            break;
        }
        int r = ind[t+1];
        exp[i] = str.substring(0,1);
        i++;
        exp[i] = str.substring(1,r+2);
        i++;
        exp[i] = str.substring(r+2,r+3);
        str = str.substring(r+3);
      }else {
        Arrays.sort(ind);
        int t;
        for(t = 0;t <6;t++) {
          if(ind[t] >= 0)
            break;
        }
        if(t==6)
          break;
        index = ind[t];
        if(index!=0) {
          exp[i] = str.substring(0,index);
          i++;
        }
        exp[i] = str.substring(index,index+1);
        str = str.substring(index+1);
      }
    }
    int j = 0;
    int k = 0;
    for(; exp[j]!=null ;j++){}
    if(!exp[j-1].equals(")")) {
      exp[j]=str;
      str = "";
      k = j;
    }else {
      k = j-1;
    }
    String[] expp = new String[k+1];
    for(int t = 0; t < k+1;t++) {
      expp[t] = exp[t];
    }
    return expp;
    //System.out.println("分割的字符串:");
  }

2.中缀转后缀

private static String infToSuf(String[] exp) {
    String newStrs = "";
    //初始化栈
    Stack<String> stack = new Stack<>();
     /*
           判断并放入后缀表达式中:
       for循环遍历整个str进行判断
           循环结束若栈不为空全部出栈
     */
    int l = exp.length;
    for(int i = 0; i < l; i++) {
      if ((stack.empty()) && (exp[i].equals("+") || exp[i].equals("-") || exp[i].equals("*") || exp[i].equals("/"))) {
        stack.push(exp[i]);
      } else if (exp[i].equals("(")) {
        stack.push(exp[i]);
      } else if (exp[i].equals("*") || exp[i].equals("/")) {
        while (stack.peek().equals("*") || stack.peek().equals("/")) {
          newStrs = newStrs.concat(stack.pop()+" ");
          if(stack.isEmpty()) {
            break;
          }
        }
        stack.push(exp[i]);
      } else if (exp[i].equals("+") || exp[i].equals("-")) {
        while (!(stack.isEmpty())&&((stack.peek()).equals("*") || (stack.peek()).equals("/") || (stack.peek()).equals("+") || (stack.peek()).equals("-"))) {
          newStrs = newStrs.concat(stack.pop()+" ");
          if(stack.isEmpty()) {
            break;
          }
        }
        stack.push(exp[i]);
      } else if (exp[i].equals(")")) {
        int t = stack.search("(");
        for (int k = 1; k < t; k++) {
          newStrs = newStrs.concat(stack.pop()+" ");
        }
        String tstr = stack.pop();
      } else {
        newStrs = newStrs.concat(exp[i]+ " ");
      }
    }
    while (!stack.empty()) {
      if (!stack.peek().equals("(") || !stack.peek().equals(")")) {
        newStrs = newStrs.concat(stack.pop()+" ");
      } else if (stack.peek().equals("(") || stack.peek().equals(")")) {
        String tstr = stack.pop();
      }
    }
//   System.out.println("后缀:"+newStrs);
    return newStrs;
  }

3.后缀的计算

  private static String sufToRes(String sufStr) {
    String[] exp = sufStr.split(" ");
    Stack<String> stack = new Stack<>();
    String Res = "";
    for(int i = 0;i < exp.length; i++) {
      if(!exp[i].equals("+") && !exp[i].equals("-") && !exp[i].equals("*") && !exp[i].equals("/")){
        stack.push(exp[i]);
      }else if(exp[i].equals("+")) {
        BigDecimal b2 = new BigDecimal(stack.pop());
        BigDecimal b1 = new BigDecimal(stack.pop());
        BigDecimal b3 = b1.add(b2);
        stack.push(b3.toString());
      }else if(exp[i].equals("-")) {
        BigDecimal b2 = new BigDecimal(stack.pop());
        BigDecimal b1 = new BigDecimal(stack.pop());
        BigDecimal b3 = b1.subtract(b2);
        stack.push(b3.toString());
      }else if(exp[i].equals("*")) {
        BigDecimal b2 = new BigDecimal(stack.pop());
        BigDecimal b1 = new BigDecimal(stack.pop());
        BigDecimal b3 = new BigDecimal(0);
        if(b1.compareTo(BigDecimal.ZERO)== 0|| b2.compareTo(BigDecimal.ZERO) == 0) {
          b3 = BigDecimal.ZERO;
        }else {
          b3 = b1.multiply(b2);
        }
        stack.push(b3.toString());
      }else if(exp[i].equals("/")){
        BigDecimal b2 = new BigDecimal(stack.pop());
        BigDecimal b1 = new BigDecimal(stack.pop());
        BigDecimal b3 = new BigDecimal(0);
        double d1 = b1.doubleValue();
        double d2 = b2.doubleValue();
        if(d1%d2 == 0){
          b3 = (b1.divide(b2));
          stack.push(b3.toString());
        }else {
          b3 = b1.divide(b2,10, RoundingMode.HALF_UP);
          stack.push(b3.toString());
        }
      }
    }
    Res = stack.pop();
    boolean flag = false;
    for (int m = 0; m < Res.length() - 1;m++) {
      if(Res.charAt(m) == '.'){
        flag = true;
      }
    }
    if(flag) {
      for(int m = Res.length()-1;m >= 0;m--) {
        if(Res.charAt(m) == '0'){
        }else {
          Res = Res.substring(0,m+1);
          break;
        }
      }
      if(Res.charAt(Res.length()-1) == '.') {
        Res = Res.substring(0,Res.length()-1);
      }
    }
    return Res;
  }

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对我们的支持。如果你想了解更多相关内容请查看下面相关链接

(0)

相关推荐

  • Java通过卖票理解多线程

    以卖票的例子来介绍多线程和资源共享,下面我们来看看为什么要用卖票作为例子. 卖票是包含一系列动作的过程,有各种操作,例如查询票.收钱.数钱.出票等,其中有一个操作是每次卖掉一张,就将总的票数减去1.有10张票,如果一个人卖票,先做查票.收钱.数钱等各种操作,再将总的票数减去1,效率很低.如果多个人卖票,每个人都是做同样的操作,数钱.检查钱,最后将总的票数减1,这样效率高.但是有一个问题,如果出现两个人同时将总的票数减掉了1,例如,A.B两个人同时读取到票的总数是10,A从中减去1,同时B也从中减

  • java计算图两点之间的所有路径

    本文实例为大家分享了java计算图两点之间的所有路径的具体代码,供大家参考,具体内容如下 1.给定图如下: 2.求0到3之间可达的所有路径 这里问题就是关于搜索遍历的问题,但其中需要注意到不能产生回路或环. 算法描述如下: top_node:当前栈顶元素 adjvex_node;当前top_node已经访问的邻接点 next_node:即将访问的元素(top_node的第adjvex_node个邻接点所对应的元素) 找出所有路径采用的是遍历的方法,以"深度优先"算法为基础.从源点出发,

  • java实现多线程卖票功能

    java多线程卖票直接先看个例子: public class SelTicketsMainTest { public static void main(String[] args) { SaleTickets1 saleTickets = new SaleTickets1(); for(int t=1;t<=3;t++) { new Thread(saleTickets).start(); } } } class SaleTickets1 implements Runnable{ private

  • java外卖订餐系统小项目

    本文实例为大家分享了java外卖订餐系统的具体代码,供大家参考,具体内容如下 执行结果: 通过选择功能序号,执行响应的功能: 代码实现: package 外卖订餐系统; /* * 代码优点,使用 循环: * 显示菜单, * 根据用户选择的数字执行相应功能(功能实现:do..while循环.) */ import java.util.Scanner; public class OrderingMsg { public static void main(String[] args) { //数据主题

  • 基于java计算买卖股票的最佳时机

    这篇文章主要介绍了基于java计算买卖股票的最佳时机,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 问题: 可以将问题转化为如下图所示,即求多个累计的收入差 分析: 如果当前位置i的价格比i+1的价格高,则当前不是买入点,则继续判断下一个位置, 如果当前位置i的价格比i+1的价格低,并且i+1仍比i+1+1低,则在当前位置买入,知道i+n比i+n+1大时,卖出. 继续下一轮判断 package com.example.demo; public

  • Java多边形重心计算

    多边形重心计算 三角形重心 顶点为a,b,c的三角形重心为x = (xa + xb + xc) / 3,y = (ya + yb + yc) / 3 多边形重心 x = (x1w1 + x2w2 + - + xnwn)/W y = (y1w1 + y2w2 + - + ynwn)/W import org.locationtech.jts.geom.Coordinate; import org.locationtech.jts.geom.Polygon; import org.locationt

  • 逆波兰计算器(Java实现)

    之前的一篇博客中,讲的是用栈实现了中缀表达式的简易计算器,对于我们人来讲,中缀表达式是一种比较直观,而且非常好计算的一种形式,但对于计算器来讲,非常的难去看懂.所以,下面我讲下逆波兰计算器的Java实现. 逆波兰式(后缀表达式) 逆波兰表达式又叫做后缀表达式.逆波兰表示法是波兰逻辑学家J・卢卡西维兹(J・ Lukasewicz)于1929年首先提出的一种表达式的表示方法 [1]  .后来,人们就把用这种表示法写出的表达式称作"逆波兰表达式".逆波兰表达式把运算量写在前面,把算符写在后面

  • Java计算器核心算法代码实现

    在进行一个表达式的计算时,先将表达式分割成数字和字符串然后利用出入栈将分割后的表达式进行中缀转后缀,再将后缀表达式进行计算得到结果(思想在上一篇写过)现在贴下Java语言的代码实现.(学习Java时间不长所以可能会有很多不足的地方,我会改进也欢迎大神可以给我一些意见和建议~谢谢啦) 我将这部分分成三个方法完成功能,并在getResult方法调用(getResult方法被主方法调用) private String getResult(String str) { //分割 String[] Str

  • Java实现TFIDF算法代码分享

    算法介绍 概念 TF-IDF(term frequency–inverse document frequency)是一种用于资讯检索与资讯探勘的常用加权技术.TF-IDF是一种统计方法,用以评估一字词对于一个文件集或一个语料库中的其中一份文件的重要程度.字词的重要性随着它在文件中出现的次数成正比增加,但同时会随着它在语料库中出现的频率成反比下降.TF-IDF加权的各种形式常被搜寻引擎应用,作为文件与用户查询之间相关程度的度量或评级.除了TF-IDF以外,因特网上的搜寻引擎还会使用基于连结分析的评

  • Java 常见排序算法代码分享

    目录 1. 冒泡排序 2. 选择排序 3. 插入排序 4. 快速排序 5. 归并排序 6. 希尔排序 6.1 希尔-冒泡排序(慢) 6.2 希尔-插入排序(快) 7. 堆排序 8. 计数排序 9. 桶排序 10. 基数排序 11. 使用集合或 API 11.1 优先队列 11.2 Java API 汇总: 1. 冒泡排序 每轮循环确定最值: public void bubbleSort(int[] nums){     int temp;     boolean isSort = false;

  • Java 二分法检索算法代码实现详解

    一,二分法检索算法介绍 二分法检索(binary search)又称折半检索,二分法检索的基本思想是设字典中的元素从小到大有序地存放在数组(array)中.是最常用的搜索算法之一,这主要是由于其搜索时间短. 二,二分法检索算法思路 这种搜索使用分而治之方法,并且需要事先对数据集进行排序. 它将输入集合分为相等的两半,并且每次迭代都将目标元素与中间元素进行比较. 如果找到该元素,则搜索结束.否则,我们根据目标元素是小于还是大于中间元素,通过划分并选择适当的数组分区来继续寻找元素. 这就是为什么对B

  • javascript中实现兼容JAVA的hashCode算法代码分享

    在java中一个hashCode算法,可以用来计算一个字符串的hash值,今天一个朋友突然问俺能不能在js中计算hashCode,要求和java的hashCode计算结果一样. 对于java的hashCode,以前到现在也一直没有了解过其算法,不过猜想应该也不会太难,于是现在java中写了这段代码进行测试: 运行结果:899755 按下Ctrl键点击hashCode方法名跟进去看了下其算法,发现是很简单的几句代码,如下所示: 复制代码 代码如下: public int hashCode() {

  • 基于java实现DFA算法代码实例

    DFA简介 DFA全称为:Deterministic Finite Automaton,即确定有穷自动机.(自己百度吧) 直接代码: 敏感词实体类 package com.nopsmile.dfa; public class Keywords { private String pid; private String Content; public Keywords() { } public Keywords(String content) { super(); Content = content

  • Java语言基于无向有权图实现克鲁斯卡尔算法代码示例

    所谓有权图,就是图中的每一条边上都会有相应的一个或一组值.通常情况下,这个值只是一个数字 如:在交通运输网中,边上的权值可能表示的是路程,也可能表示的是运输费用(显然二者都是数字).不过,边上的权值也有可能是其它东西,比如说是一个字符串,甚至是一个更加复杂的数据包,里面集合了更多的数据 克鲁斯卡尔算法的核心思想是:在带权连通图中,不断地在边集合中找到最小的边,如果该边满足得到最小生成树的条件,就将其构造,直到最后得到一颗最小生成树. 克鲁斯卡尔算法的执行步骤: 第一步:在带权连通图中,将边的权值

  • Java编程实现基于用户的协同过滤推荐算法代码示例

    协同过滤简单来说是利用某兴趣相投.拥有共同经验之群体的喜好来推荐用户感兴趣的信息,个人通过合作的机制给予信息相当程度的回应(如评分)并记录下来以达到过滤的目的进而帮助别人筛选信息,回应不一定局限于特别感兴趣的,特别不感兴趣信息的纪录也相当重要. 协同过滤又可分为评比(rating)或者群体过滤(social filtering)协同过滤以其出色的速度和健壮性,在全球互联网领域炙手可热 UserCF的核心思想即为根据用户数据模拟向量相似度,我们根据这个相似度,来找出指定用户的相似用户,然后将相似用

  • java版数独游戏核心算法(一)

    之前学习javascript时用javascript写过一个数独游戏,最近看了一点java的内容,于是就心血来潮想搞一个java版的数独游戏. 现在将全部代码分享出来和大家学习交流,当然代码中有着各种各样的问题和不足之处,望各位朋友批评指点. 以下是生成数独地图的核心算法,算法不是很好,也是之前参考过网上的一些思想: package hlc.shudu.src; /* * 数独的帮助类,里面提供数据所需的所有算法 */ public class ShuduHelper { //数独地图数组 pr

  • Java实现查找算法的示例代码(二分查找、插值查找、斐波那契查找)

    目录 1.查找概述 2.顺序查找 3.二分查找 3.1 二分查找概述 3.2 二分查找实现 4.插值查找 4.1 插值查找概述 4.2 插值查找实现 5.斐波那契查找 5.1 斐波那契查找概述 5.2 斐波那契查找实现 5.3 总结 1.查找概述 查找表: 所有需要被查的数据所在的集合,我们给它一个统称叫查找表.查找表(Search Table)是由同一类型的数据元素(或记录)构成的集合. 查找(Searching): 根据给定的某个值,在查找表中确定一个其关键字等于给定值的数据元素(或记录).

随机推荐