• oc 计算 带括号 式子


    下面代码实现可以计算 类似以下的字符窜。

    @"(1+2*(3+4)+3)/2"

    自写一个简单 stack 。不知道 OC为什么不提供Stack类。

    #import <Foundation/Foundation.h>
    
    @interface MyStack : NSObject
    {
        
    }
    @property NSMutableArray* mArray ;
    
    @property int size ;
    
    -(id) pop ;
    
    -(void) push:(id)obj ;
    
    -(MyStack* )init ;
    @end
    #import "MyStack.h"
    
    @implementation MyStack
    
    @synthesize   mArray ;
    
    @synthesize size ;
    
    -(id) pop {
        id temp =mArray.lastObject ;
        [mArray removeLastObject] ;
        return temp  ;
    }
    
    -(void) push:(id)obj {
        if(mArray!=nil && obj !=nil){
            [mArray addObject:obj ];
        }
    }
    
    -(MyStack* )init {
        
        self = [super init];
        if(self!=nil&&self.mArray ==nil){
            self.mArray = [[NSMutableArray alloc]init];
        }
        return  self ;
    }
    @end

    编写计算类

    #import "NSString+index.h"
    #import <Foundation/Foundation.h>
    
    @interface MyCalculater : NSObject
    //计算子窜,没有括号的式子
    +(NSNumber*)calculate:(NSString*) str;
    //计算总窜
    +(NSNumber*)compute:(NSString*)StringToCompute ; @end//
    //  MyCalculater.m
    //  hellowWorld
    //
    //  Created by hongtao on 2018/4/4.
    //  Copyright © 2018年 hongtao. All rights reserved.
    //
    
    #import "MyCalculater.h"
    #import "MyStack.h"
    
    @implementation MyCalculater
    
    +(NSNumber*)compute:(NSString*)StringToCompute {
        
        MyStack *myStack  = [[MyStack alloc]init];
        NSNumber * result =nil;
        while (true) {
            Boolean needFinish = false;
            
            for (int i = 0;  i<StringToCompute.length; i++) {
                if([StringToCompute characterAtIndex:i]=='('){
                    NSString * str = [StringToCompute substringWithRange:NSMakeRange(0, i)];
                    
                    [myStack push:str];
                    
                    NSString *strtemp = [StringToCompute substringWithRange:NSMakeRange(i+1, StringToCompute.length-i-1)];
                    
                    StringToCompute = [[NSMutableString alloc]initWithString:strtemp];
                    
                    break;
                }
                
                if([StringToCompute characterAtIndex:i]==')'){
                    NSString *strTemp = [StringToCompute substringToIndex:i];
                    StringToCompute =[StringToCompute substringWithRange:NSMakeRange(i+1,StringToCompute.length-i-1)];
                    NSMutableString * mstr = [[NSMutableString alloc]init];
                    [mstr appendString:[myStack pop] ];
                    [mstr appendString:[[MyCalculater calculate:strTemp] stringValue]] ;
                    [mstr appendString:StringToCompute];
                    StringToCompute = [mstr copy];
                    mstr = nil;
                    break;
                }
                
                if(i==StringToCompute.length-1){

    //已没有括号

    
    

                    if([StringToCompute containsString:@"+"]||[StringToCompute containsString:@"-"]||[StringToCompute containsString:@"*"]            ||[StringToCompute containsString:@"/"])

              {

                      result= [MyCalculater calculate:StringToCompute];
                        NSLog(@"result:%@",result );
                    }else{
                        result =StringToCompute ;
                        NSLog(@"result:%@", StringToCompute);
                    }
                    needFinish = true;
                }
            }
            if(needFinish){
                break;
            }
            
        }
        
        return nil ;
    }
    
    +(NSNumber*)calculate:(NSString*)  strTmp {
        //计算没有括号的式子。1.分离式子,分个因子放到数组。2.找到符号位,做左右两边计算,结果用来替换原来符号位,删除左右两个计算数。
    NSMutableArray
    * array = [[NSMutableArray alloc]init]; while (true) { //先计算 * / Boolean needContinue = true; for (int i = 1; i<strTmp.length; i++) { char c= [strTmp characterAtIndex:i]; if(c=='+'||c=='-'||c=='*'||c=='/'){
              //拆开式子 NSString
    * temp = [strTmp substringWithRange:NSMakeRange(0, i)]; [array addObject:temp]; temp = [strTmp substringWithRange:NSMakeRange(i, i)]; [array addObject:temp]; strTmp = [strTmp substringWithRange:NSMakeRange(i+1, strTmp.length - i-1)]; if(strTmp.length<=1){ needContinue = false; [array addObject:strTmp]; } break; } } if(!needContinue){ break; } } // NSLog(@"%@",array); while (true) {
         //做 * 和 / Boolean needFinish
    = false; for (int i =0 ; i< array.count ; i++) { if([array[i] isEqual:@"/"]||[array[i] isEqual:@"*"]){ NSNumber *left = array[i-1]; NSNumber *right = array[i+1]; double result = 0.0 ; if([array[i] isEqual:@"/"]){ result = [left doubleValue]/[right doubleValue] ; } if([array[i] isEqual:@"*"]){ result = [left doubleValue]*[right doubleValue] ; } //替换符号位,删除左右元素。 array[i]=@(result); NSLog(@"%@",array); [array removeObjectAtIndex:i-1]; NSLog(@"%@",array); [array removeObjectAtIndex:i]; NSLog(@"%@",array); break; } if (i==array.count -1){ needFinish = true; } } if(needFinish){ NSLog(@"%@",array); break; } } while (true) { Boolean needFinish = false;
         //做 + 和 - 运算
    for (int i =0 ; i< array.count ; i++) { if([array[i] isEqual:@"+"]||[array[i] isEqual:@"-"]){ NSNumber *left = array[i-1]; NSNumber *right = array[i+1]; double result = 0.0 ; if([array[i] isEqual:@"+"]){ result = [left doubleValue]+[right doubleValue] ; } if([array[i] isEqual:@"-"]){ result = [left doubleValue]-[right doubleValue] ; } //基本与上面同理。 array[i]=@(result); NSLog(@"%@",array); [array removeObjectAtIndex:i-1]; NSLog(@"%@",array); [array removeObjectAtIndex:i]; NSLog(@"%@",array); break; } if (i==array.count -1){ needFinish = true; } } if(needFinish){ NSLog(@"%@",array); break; } } return (NSNumber*)array[0]; } @end

    扩展NSString 方法,竟然没有 indexof lastIndexOf 方法。自写。

    #import <Foundation/Foundation.h>
    
    @interface NSString (index)
    -(int) indexOf:(char)c ;
    -(int) lastIndexOf:(char)c ;
    @end
    #import "NSString+index.h"
    
    @implementation NSString (index)
    -(int) indexOf:(char)c {
        int index = -1 ;
        for (int i =0; i< [self length]; i++) {
            if('c'== [self characterAtIndex:i]){
                index = i ;
                break;
            }
        }
        return index ;
    }
    
    -(int) lastIndexOf:(char)c {
        int index = -1 ;
        for (int i =0; i< [self length]; i++) {
            if('c'== [self characterAtIndex:i]){
                index = i ;
            }
        }
        return index ;
    }
    
    @end

    可以是类方法,这里就不改了。

    main 方法中调用。

    #import "MyCalculater.h"
    
    int main(int argc, const char * argv[]) {
        @autoreleasepool {
            
            NSLog(@"%@",[MyCalculater compute:@"(1+2*(3+4)+3)/2"]);
            
        }
        return 0;
    }

    匹配括号的思想是栈的使用。遇左括号截取对应部分压栈,遇右括号出栈并计算替换。

    没有检查合法性。没有做代码优化。

  • 相关阅读:
    POJ3345 Bribing FIPA(树形DP)
    POJ3294 Life Forms(二分+后缀数组)
    ZOJ1027 Travelling Fee(DP+SPFA)
    POJ2955 Brackets(区间DP)
    POJ1655 Balancing Act(树的重心)
    POJ2774 Long Long Message(后缀数组)
    URAL1297 Palindrome(后缀数组)
    SPOJ705 SUBST1
    POJ3261 Milk Patterns(二分+后缀数组)
    POJ1743 Musical Theme(二分+后缀数组)
  • 原文地址:https://www.cnblogs.com/mamamia/p/8718547.html
Copyright © 2020-2023  润新知