数据结构和算法四(栈的经典应用逆波兰表达式的运用)

思路

数字输出,运算符进栈,括号匹配出栈,栈顶优先级出栈
a、首先使用两个栈 一个是s1 一个是s2 s1 是用来临时存储运算符的, s2 是用来存放输入的逆波兰表达式的,
b、从中缀表达式的最左端开始,逐个读取每一个字符,如果操作数,则压入s2,如果是左括号,则压入s1,如果为右括号,则将s1中的运算符依次取出并且压入s2,直到遇到左括号,但是该左括号出栈 但不压入s2,如果为操作符, 判断s1是否为空,如果为空 则将它压入s2,如果扫描到的比栈顶的元素的优先级大 将它入栈,如果扫描到的比小于栈顶或者等于栈顶的优先级小,直到扫描到的元素大于栈顶的元素(注意这里是一个循环),然后判断s1里面如果还有运算符 则一一出栈压入到s2中
c、然后这个时候所有的数据全部在s2中,这个时候从的将s2逆置,从栈底开始取元素,开始扫描,如果扫描到的是一个运算符,则将他之前扫描到的两个元素做运算,得到存储到该位置,一直扫描,直到栈里还剩一个元素,就得到结果。

代码实现

自己写的 就是为了实现可能还有问题 大家可以提出来

  public class ReversePolishUtil {
  /**
    *是一个中缀表达式
    * @param express
    */
  public static void Reverse(String[] express) {
    if (express == null || express.length == 0) {
        抛出异常;
   }
    运来存放运算符
    StackDemo</a> s1 = new StackDemo ();
    用来存放输入逆波兰表达式
    StackDemo s2 = new StackDemo ();
    依次遍历这个数组
    for (int i = 0; i < express.length; i++) {
          String nowChar = express[i];
          Pattern pattern = Pattern.compile("[0-9]*");
          boolean isMacth = pattern.matcher(nowChar).matches();
          if (isMacth) {
          如果是数字 直接压入s2
          s2.push(nowChar);
          } else {
          否则就是操作符 就得判断s1 栈顶的元素
          if (s1.empty()) {
          如果为空 直接push
          s1.push(nowChar);
          } else if (nowChar.equals("(")) {
          如果是左括号 直接push s1
            s1.push(nowChar);
          } else if (nowChar.equals(")")) {
          如果是右括号, s1中的运算符依次出栈 压入到s2中, 直到遇到左括号, 但是左括号是直接出栈的
              while (!s1.empty() && !s1.peek().equals("(")) {
                        s2.push(s1.pop());
                      }
              然后将左括号也给出栈
              s1.pop();
          } else if (nowChar.equals("+") || nowChar.equals("-")) {
          1、如果扫描到的比栈顶的元素的优先级大 将它入栈
          2、如果扫描到的比小于栈顶或者等于栈顶的优先级小,知道扫描到的元素大于栈顶的元素扫描到的运算符
               while (!s1.empty() && !s1.peek().equals("(")) {
            在这里只要不遇到左括号 就一直出栈,因为优先级都比它大
                        s2.push(s1.pop());
                       }
          在这里是要么遇到括号 要么s1出栈为null了
                s1.push(nowChar);
          } else if (nowChar.equals("*") || nowChar.equals("/")) {
          在这里一直出栈的情况是只有当遇到 * 和/
                while (!s1.empty() && s1.peek().equals("*") || s1.peek().equals("?")) {
                         s2.push(s1.pop());//出栈
                      }
                s1.push(nowChar);
          }
      }
    如果s1里面还有操作符 则push到s2里面
    while (!s1.empty()) {
          s2.push(s1.pop());
    }
  while (!s2.empty()) {
    Log.e("Reverse", s2.pop() + "");
    }  
  }
}

然后使用数组手写一个栈,上面的逆波兰就用的这个demo

    public class StackDemo {
    //初始数组的大小
    private int capacity = 3;
    //数组中元素的个数
    private int size = 0;
    //由于是数组设计到扩容 ,这里直接是扩容1.5倍
    private int increment = 2;
    private Object[] elementData = new Object[capacity];
    public StackDemo() {
    }

    public StackDemo(int capacity) {
    this.capacity = capacity;
    }
    //实现一个push的方法
    public void push(Object obj) {
    //在这里要判断是否超出了 如果超过了就得扩容 注意相等也要判断 坑了
      if (size >= elementData.length) {      
        grow(); //扩容
        }
    elementData[size] = obj;
    size++;
    }

    //移除栈顶的元素
    public Object pop() {
        if (elementData == null || elementData.length == 0 || size == 0) {
            return "";
        }
        size--;
        return elementData[size];
    }
    public boolean empty() {
        if (elementData == null || elementData.length == 0 || size == 0) {
            return true;
        }
        return false;
    }
    /**
     * 查看栈顶元素但是不删除
     * @return
     */
    public Object peek() {
        if (elementData == null || elementData.length == 0 || size == 0) {
            return "";
        }
        return elementData[size - 1];
    }
    //数组大小的扩容
    private void grow() {
        int newcapacity = (increment * elementData.length);
        elementData = Arrays.copyOf(elementData, newcapacity);
    }

}

最后调用:
String[] string = {"12", "+", "4", "+", "5","*","(","3","-","2",")"};
ReversePolishUtil.Reverse(string); 吧上一篇文章的结果打印出来是没问题的

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,717评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,501评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,311评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,417评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,500评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,538评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,557评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,310评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,759评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,065评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,233评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,909评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,548评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,172评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,420评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,103评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,098评论 2 352

推荐阅读更多精彩内容