算法-表達式求值


今天在網上看到Dijkstra的雙棧算術表達式求值算法,以前很早的時候知道通過算術棧和數值棧搞定的,這次用OC通過數組實現了預期的效果.

(原理參考網上,原作者不詳)

編程語言系統一般都內置了對算術表達式的處理,我們可以簡易的模仿一下算術表達式處理機制,思想不變,主要是實現方式略有不同。算術表達式可能是一個數、或者是由一個左括號、一個算術表達式、一個運算符、另一個算術表達式和一個右括號組成的表達式。為了簡化問題,這里定義的是未省略括號的算術表達式,它明確地說明了所有運算符的操作數,形式如下:(1+((2+3)*(4*5)))

思路:

     表達式由括號、運算符和操作數構成,我們根據以下4中情況從左至右逐個將這些實體送入棧處理:

     1.將操作數壓入操作數棧;

     2.將運算符壓入運算符棧;

     3.忽略左括號;

     4.在遇到右括號時,彈出一個運算符,彈出所需數量的操作數,並將運算后的結果壓入操作數棧;

    在處理完最后一個右括號時,操作數棧上只會剩下一個值,它就是表達式的計算結果。這種方法咋一看難理解,但要證明它能計算得到正確的值很簡單:

    每當算法遇到一個括號包圍,並由一個運算符和兩個操作數組成的子式時,他都將運算符和操作數運算結果壓入操作數棧。這樣的結果就像是在輸入中用這個值代替了該子表達式,因此用這個值代替子表達式得到的結果和原表達式相同。我們可以反復應用這個規律並得到一個最終值。

例如:

(1+((2+3)*(4*5)))

(1+(5*(4*5)))

(1+(5*20))

(1+100)

  101

OC代碼實現如下:

-(NSInteger)operationExpression:(NSString *)expression{

    NSMutableArray  *operationArr=[[NSMutableArray alloc]initWithCapacity:1];
    NSMutableArray  *valArr=[[NSMutableArray alloc]initWithCapacity:1];
    for (NSInteger i=0; i<expression.length; i++) {
        NSString  *currentStr=[NSString stringWithFormat:@"%c",[expression characterAtIndex:i]];
        if([currentStr isEqualToString:@"("]);
        else if([currentStr isEqualToString:@"+"]){
            [operationArr addObject:currentStr];
        }else if([currentStr isEqualToString:@"-"]){
            [operationArr addObject:currentStr];
        }else if([currentStr isEqualToString:@"*"]){
            [operationArr addObject:currentStr];
        }else if([currentStr isEqualToString:@")"]){
            
            NSInteger  lastValue=[[valArr objectAtIndex:valArr.count-1] integerValue];
            NSInteger  secondValue=[[valArr objectAtIndex:valArr.count-2] integerValue];
            
            [valArr removeObjectAtIndex:valArr.count-1];
            [valArr removeObjectAtIndex:valArr.count-1];
            NSString   *lastOperation=[operationArr objectAtIndex:operationArr.count-1];
            [operationArr removeObjectAtIndex:operationArr.count-1];
            
            
            
            NSInteger newValue=0;
            if([lastOperation isEqualToString:@"+"]) newValue=secondValue+lastValue;
            else if([lastOperation isEqualToString:@"-"]) newValue=secondValue-lastValue;
            else if([lastOperation isEqualToString:@"*"]) newValue=secondValue*lastValue;
            else if([lastOperation isEqualToString:@"/"]) newValue=secondValue/lastValue;
            
            [valArr addObject:[NSNumber numberWithLong:newValue]];
            
        }else{
            [valArr addObject:currentStr];
        }
    }
    return [[valArr objectAtIndex:0] integerValue];
}

 還有很多缺憾,比如不能處理浮點數,不能處理,不能處理超過兩位數的整數,如果有想法的可以繼續優化一下~


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM