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;
}
复制代码

 

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

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

 

posted on   wp7ers  阅读(171)  评论(0编辑  收藏  举报
编辑推荐:
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

点击右上角即可分享
微信分享提示