字符串表達(dá)式求值

給你一個(gè)字符串漾月,這個(gè)字符串表示一個(gè)表達(dá)式病梢,這個(gè)表達(dá)式可能有整數(shù),加減乘除符號和小括號,求這個(gè)表達(dá)式的值蜓陌。

算法步驟&原理

  1. 首先假如只有加減符號觅彰,并且都是整數(shù),那么很容易求解钮热,遍歷一遍即可getNum實(shí)現(xiàn)填抬。
  2. 現(xiàn)在再加入乘除。在遍歷表達(dá)式的時(shí)候隧期,開始的數(shù)字加到隊(duì)列中飒责,然后符號加到隊(duì)列中,然后后邊遇到數(shù)字的時(shí)候仆潮,首先看隊(duì)列中的那個(gè)符號是不是加減宏蛉,加減的話直接把這個(gè)數(shù)加進(jìn)去,否則需要與隊(duì)列里面的數(shù)和那個(gè)符號計(jì)算之后再加進(jìn)去性置。
  3. 上面的描述可以解決有加減乘除的情況檐晕,如果在假如括號的話,就是首先計(jì)算各個(gè)括號里面的值蚌讼,計(jì)算結(jié)果加到隊(duì)列當(dāng)中,然后再計(jì)算所有的个榕。
public static int getValue(String str) {
        return value(str.toCharArray(), 0)[0];//返回表達(dá)式的值
    }

    public static int[] value(char[] str, int i) {
        LinkedList<String> que = new LinkedList<String>();
        int pre = 0;
        int[] bra = null;
        while (i < str.length && str[i] != ')') {//以一個(gè)括號包含的數(shù)為單位進(jìn)行計(jì)算
            if (str[i] >= '0' && str[i] <= '9') {//遇到了數(shù)字
                pre = pre * 10 + str[i++] - '0';
            } else if (str[i] != '(') {//遇到了+ - * /
                addNum(que, pre);//處理之前的數(shù)篡石,直接加到隊(duì)列中或者與隊(duì)列中原有的操作符和數(shù)字結(jié)合之后再加進(jìn)去
                que.addLast(String.valueOf(str[i++]));//隊(duì)列中加入運(yùn)算符號
                pre = 0;
            } else {//遇到了左括號
                bra = value(str, i + 1);//計(jì)算這個(gè)括號內(nèi)的值
                pre = bra[0];//括號能的值
                i = bra[1] + 1;//右括號的下一個(gè)位置,也就是下一次計(jì)算的開始位置
            }
        }
        addNum(que, pre);//最后一個(gè)數(shù)加到隊(duì)列當(dāng)中
        return new int[] { getNum(que), i };//返回一個(gè)“部分”的值和計(jì)算到的位置
    }

    public static void addNum(LinkedList<String> que, int num) {
        if (!que.isEmpty()) {//隊(duì)列為null,證明此時(shí)還沒有數(shù)加進(jìn)來西采,進(jìn)來的num是第一個(gè)數(shù)凰萨,直接加到隊(duì)列中即可
            int cur = 0;
            String top = que.pollLast();
            if (top.equals("+") || top.equals("-")) {//隊(duì)列首部為加或者減,不做操作械馆,彈出的繼續(xù)加回去
                que.addLast(top);
            } else {//隊(duì)列首部為/或者*胖眷,需要與進(jìn)來的數(shù)結(jié)合后再重新加入隊(duì)列中
                cur = Integer.valueOf(que.pollLast());
                num = top.equals("*") ? (cur * num) : (cur / num);
            }
        }
        que.addLast(String.valueOf(num));
    }

    public static int getNum(LinkedList<String> que) {//只有加減時(shí)的運(yùn)算3+4-5+6
        int res = 0;
        boolean add = true;
        String cur = null;
        int num = 0;
        while (!que.isEmpty()) {
            cur = que.pollFirst();
            if (cur.equals("+")) {
                add = true;
            } else if (cur.equals("-")) {
                add = false;
            } else {
                num = Integer.valueOf(cur);
                res += add ? num : (-num);
            }
        }
        return res;
    }

[沒有括號leetcode227]https://leetcode.com/problems/basic-calculator-ii/

public class Solution {
    public int calculate(String s) {
        return value(s.toCharArray());   
    }
    public int value(char[] str){
        LinkedList<String> list=new LinkedList<String>();
        int i=0;
        int pre=0;
        while(i<str.length){
            if(str[i]==' '){
                i++;
                continue;
            }
            else if(str[i]>='0'&&str[i]<='9'){
                pre=pre*10+str[i++]-'0';
            }
            else{
                addNum(list,pre);
                list.addLast(String.valueOf(str[i++]));
                pre=0;
            }
        }
        addNum(list,pre);
        return getNum(list);
    }
    public void addNum(LinkedList<String> list,int num){
        if(!list.isEmpty()){
            String flag=list.pollLast();
            if(flag.equals("+")||flag.equals("-"))
                list.addLast(flag);
            else{
                int pre=Integer.valueOf(list.pollLast());
                num=flag.equals("*")?pre*num:pre/num;
            }
        }
        list.addLast(String.valueOf(num));
    }
    public int getNum(LinkedList<String> list){
        int res=0;
        boolean add=true;
        String cur=null;
        int num=0;
        while(!list.isEmpty()){
            cur=list.pollFirst();
            if(cur.equals("+"))
                add=true;
            else if(cur.equals("-")){
                add=false;
            }
            else{
                num=Integer.valueOf(cur);
                res=(add?res+num:res-num);
            }
        }
        return res;
    }
}

[有括號沒乘除leetcode224]https://leetcode.com/problems/basic-calculator/

public class Solution {
   public int calculate(String s) {
       return value(s.toCharArray(),0)[0];
   }
   public int[] value(char[] str,int i){
       int[] bra=new int[2];
       boolean add=true;
       int res=0;
       int pre=0;
       while(i<str.length&&str[i]!=')'){
           if(str[i]==' '){
               i++;
           }
           else if(str[i]>='0'&&str[i]<='9'){
               pre=pre*10+str[i++]-'0';
           }
           else if(str[i]!='('){
               if(add)
                   res+=pre;
               else
                   res-=pre;
               pre=0;
               add=str[i++]=='+'?true:false;
           }else{
               bra=value(str,i+1);
               pre=bra[0];
               i=bra[1]+1;
           }
       }
       if(add)
           res+=pre;
       else
           res-=pre;
       bra[0]=res;
       bra[1]=i;
       return bra;
   }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市霹崎,隨后出現(xiàn)的幾起案子珊搀,更是在濱河造成了極大的恐慌,老刑警劉巖尾菇,帶你破解...
    沈念sama閱讀 221,888評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件境析,死亡現(xiàn)場離奇詭異,居然都是意外死亡派诬,警方通過查閱死者的電腦和手機(jī)劳淆,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,677評論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來默赂,“玉大人沛鸵,你說我怎么就攤上這事±掳耍” “怎么了曲掰?”我有些...
    開封第一講書人閱讀 168,386評論 0 360
  • 文/不壞的土叔 我叫張陵疾捍,是天一觀的道長。 經(jīng)常有香客問我蜈缤,道長拾氓,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,726評論 1 297
  • 正文 為了忘掉前任底哥,我火速辦了婚禮咙鞍,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘趾徽。我一直安慰自己续滋,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,729評論 6 397
  • 文/花漫 我一把揭開白布孵奶。 她就那樣靜靜地躺著疲酌,像睡著了一般。 火紅的嫁衣襯著肌膚如雪了袁。 梳的紋絲不亂的頭發(fā)上朗恳,一...
    開封第一講書人閱讀 52,337評論 1 310
  • 那天,我揣著相機(jī)與錄音载绿,去河邊找鬼粥诫。 笑死,一個(gè)胖子當(dāng)著我的面吹牛崭庸,可吹牛的內(nèi)容都是我干的怀浆。 我是一名探鬼主播,決...
    沈念sama閱讀 40,902評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼怕享,長吁一口氣:“原來是場噩夢啊……” “哼执赡!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起函筋,我...
    開封第一講書人閱讀 39,807評論 0 276
  • 序言:老撾萬榮一對情侶失蹤沙合,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后跌帐,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體灌诅,經(jīng)...
    沈念sama閱讀 46,349評論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,439評論 3 340
  • 正文 我和宋清朗相戀三年含末,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了猜拾。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,567評論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡佣盒,死狀恐怖挎袜,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤盯仪,帶...
    沈念sama閱讀 36,242評論 5 350
  • 正文 年R本政府宣布紊搪,位于F島的核電站,受9級特大地震影響全景,放射性物質(zhì)發(fā)生泄漏耀石。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,933評論 3 334
  • 文/蒙蒙 一爸黄、第九天 我趴在偏房一處隱蔽的房頂上張望滞伟。 院中可真熱鬧,春花似錦炕贵、人聲如沸梆奈。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,420評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽亩钟。三九已至,卻和暖如春鳖轰,著一層夾襖步出監(jiān)牢的瞬間清酥,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,531評論 1 272
  • 我被黑心中介騙來泰國打工蕴侣, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留总处,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,995評論 3 377
  • 正文 我出身青樓睛蛛,卻偏偏與公主長得像,于是被迫代替她去往敵國和親胧谈。 傳聞我的和親對象是個(gè)殘疾皇子忆肾,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,585評論 2 359

推薦閱讀更多精彩內(nèi)容