object-c 用栈实现数学表达式

#import <Foundation/Foundation.h>

@interface Stack : NSObject

//参数
extern NSUInteger const size;         //栈最大容量(常量)
@property(nonatomic, retain) NSMutableArray *stackArray;    //栈内元素
@property(nonatomic, retain) NSString *top;                    //栈顶元素


-(instancetype)initWithSize:(NSUInteger) size;

-(NSString*)getTop;

-(BOOL)push:(NSString*) element;

-(NSString*)pop;

@end

Stack.h的代码

#import "Stack.h"

@implementation Stack
//常量实现
NSUInteger const size = 500;

//带参数的构造方法
-(instancetype)initWithSize:(NSUInteger)size{
    self = [super init];
    if(self){
        self.stackArray = [[NSMutableArray alloc]initWithCapacity:size];
        for(NSUInteger i = 0;i<size;i++){
            [self.stackArray addObject:@"#"];
        }
    }
    return self;
}
//获取栈顶元素
-(NSString*)getTop{
    if(self.stackArray.count == 0){
        NSLog(@"Stack is Empty.");
        return nil;
    }
    else
        return self.top;
}
//入栈
-(BOOL)push:(NSString*) element{
    if(self.stackArray.count == size){
        NSLog(@"Stack is full, fail to push.");
        return NO;
    }
    else{
        [self.stackArray addObject:element];
        self.top = [self.stackArray lastObject];
        return YES;
    }
}
//出栈
-(NSString*)pop{
    if(self.stackArray.count == 0){
        NSLog(@"Stack is empty, fail to pop.");
        return nil;
    }
    else{
        NSString* popElement = [self.stackArray lastObject];
        [self.stackArray removeLastObject];
        self.top = [self.stackArray lastObject];
        return popElement;
    }
}
@end

Stack.m



#import <Foundation/Foundation.h>

@interface Math : NSObject

@property(nonatomic,retain) NSMutableArray *str;


-(NSArray *)validOperator;
-(NSDictionary *)inStackPriority;
-(NSDictionary *)outStackPriority;


-(BOOL)isLegical:(NSString*) str;

-(BOOL)isOperator:(NSString*) str;

-(BOOL)isNumberic:(NSString *)str;


-(NSString *)comparePriority:(NSString *)inOptr outOptr:(NSString *)outOptr;

-(double)calculate:(double)opnd1 opnd2:(double)opnd2 optr:(NSString *)optr;

-(NSString *)ExpressionCalculate:(NSString *)inputString;

@end

Math.h



#import "Math.h"
#import "Stack.h"

@interface Math()
//类扩展,私有参数和方法
//分离运算符和数值
@property (nonatomic, strong) NSMutableArray *operArray;
@property (nonatomic, strong)NSMutableArray *valueArray;

//初始化两个栈:操作数栈和运算符栈
@property(nonatomic,strong) Stack *valueStack;
@property (nonatomic) NSUInteger vsSize;
@property(nonatomic,strong) Stack *operStack;
@property (nonatomic) NSUInteger osSize;

@end

@implementation Math

//合法操作符
-(NSArray *)validOperator
{
    NSArray * opers = @[@"+", @"-", @"*", @"/", @"%", @"(", @")", @"="];
    return opers;
}

//入栈优先级
-(NSDictionary *)inStackPriority
{
    return @{@"(":@1, @"*":@5, @"/":@5, @"%":@5, @"+":@3, @"-":@3, @")":@8, @"=":@0 };
}

//出栈优先级
-(NSDictionary *)outStackPriority
{
    return @{@"(":@8, @"*":@4, @"/":@4, @"%":@4, @"+":@2, @"-":@2, @")":@1, @"=":@0 };
}

//判断当前字符是操作符还是数字
-(BOOL)isOperator:(NSString*) str{
    if ([[self validOperator] containsObject:str]) {
        return YES;
    }
    else
        return NO;
}

//判断表达式是否合法
-(BOOL)isLegical:(NSString*) str{
    NSUInteger len = [str length];
    //左右括号游标,用来判断左右括号是否匹配
    NSUInteger l = 0, r= 0;
    
    for(NSUInteger i = 0;i<len;i++){
        char ch = [str characterAtIndex:i];
        NSString* chstr = [NSString stringWithFormat:@"%c",ch];
        
        //是数字,略过
        if(![self isOperator:chstr]){
            continue;
        }
        //左括号
        else if([chstr isEqualToString:@"("]){
            l++;
        }
        //右括号
        else if([chstr isEqualToString:@")"]){
            r++;
        }
        //既不是数字也不是括号,判断下一个字符
        else{
            NSUInteger j = i+1;
            if(j<len){
                char nextch = [str characterAtIndex:j];
                NSString *jStr = [NSString stringWithFormat:@"%c",nextch];
                if([self isOperator:jStr]){
                    if(![jStr isEqualToString:@"("]&&![jStr isEqualToString:@")"]){
                        return NO;
                    }
                }
            }
        }
    }
    //左右括号不匹配
    if(l != r){
        return NO;
    }
    return YES;
}

//清楚空格
-(NSMutableArray *)clearWhitespace:(NSMutableArray *)inputArray
{
    NSMutableArray * tempArray = [NSMutableArray array];
    for (int i = 0; i < inputArray.count; i++) {
        if (![inputArray[i] isEqualToString:@""]) {
            [tempArray addObject:inputArray[i]];
        }
    }
    return tempArray;
}

//检查是不是数字(包含小数和负数)
-(BOOL)isNumberic:(NSString *)str
{
    NSCharacterSet* Digits = [NSCharacterSet decimalDigitCharacterSet];
    NSString *value = [str stringByTrimmingCharactersInSet:Digits];
    
    //检测字符串中除数字之外的字符
    if ([value length]!= 0) {
        //包含.或者-可能为小数或者负数
        if (!([value isEqualToString:@"."] ^ [value isEqualToString:@"-"])) {
            NSLog(@"不是数字");
            return NO;
        }
    }
    return YES;
}

//比较运算符优先级大小
-(NSString *)comparePriority:(NSString *)inOptr outOptr:(NSString *)outOptr
{
    NSDictionary *inStackPriority = [self inStackPriority];
    NSDictionary *outStackPriority = [self outStackPriority];
    
    NSString *inPriority = inStackPriority[inOptr];
    NSString *outPriority = outStackPriority[outOptr];
    
    NSInteger isp = [inPriority integerValue];
    NSInteger icp = [outPriority integerValue];
    
    if (isp > icp)
        return @">";
    else if (isp < icp)
        return @"<";
    else
        return @"=";
}

//纯计算(两个操作数根据制定运算符进行运算)
-(double)calculate:(double)opnd1 opnd2:(double)opnd2 optr:(NSString *)optr
{
    NSArray *items = @[@"+", @"-", @"*", @"/"];
    int item = (int)[items indexOfObject:optr];
    
    switch (item) {
        case 0:
            return (opnd1 + opnd2);
            break;
        case 1:
            return (opnd1 - opnd2);
            break;
        case 2:
            return (opnd1 * opnd2);
            break;
        case 3:
            if (opnd2 == 0) {
                NSLog(@"除法,除数为0");
                return 0;
                break;
            }
            return (opnd1 / opnd2);
            break;
        default:
            return 0;
            break;
    }
}



//计算
-(NSString *)ExpressionCalculate:(NSString *)inputString{
    inputString = [inputString stringByAppendingString:@"="];
    //先判断表达式是否合法
    if(![self isLegical:inputString]){
        //NSLog(@"字符串不是数学表达式无法计算");
        return @"字符串不是数学表达式无法计算";
    }
    
    //从输入的字符串中提取运算符和数值
    //初始化两个数组
    self.operArray = [NSMutableArray array];
    self.valueArray = [NSMutableArray array];
    
    for (NSUInteger i = 0;i<inputString.length;i++){
        char ch = [inputString characterAtIndex:i];
        NSString *temp = [NSString stringWithFormat:@"%c",ch];
        if([self isOperator:temp]&&![temp isEqualToString: @"="]){
            [self.operArray addObject:temp];
        }
    }
    NSArray *tempArray = [inputString componentsSeparatedByCharactersInSet: [NSCharacterSet characterSetWithCharactersInString:@"(+-*/%=)"]];
    self.valueArray = [NSMutableArray arrayWithArray:tempArray];
    
    //清楚空格
    self.valueArray = [self clearWhitespace:self.valueArray];
    //检查数值数组中是否含有非数字字符
    for (NSString *ch in self.valueArray) {
        if (![self isNumberic:ch]) {
            //NSLog(@"含有非法字符");
            return @"含有非法字符";
        }
    }
    
    //初始化两个栈
    self.osSize = self.operArray.count;
    self.operStack = [[Stack alloc]initWithSize:self.osSize];
    self.vsSize = self.valueArray.count;
    self.valueStack = [[Stack alloc]initWithSize:self.vsSize];
    
    //等号入栈
    [self.operStack push:@"="];
    
    //暂存括号
    NSString *bracket;
    //暂存运算符
    NSString *oper;
    //暂存操作数
    NSString *value1, *value2;
    
    for(NSUInteger i = 0;i<[inputString length];i++){
        char ch = [inputString characterAtIndex:i];
        NSString *str = [NSString stringWithFormat:@"%c", ch];
        
       
        if (([str isEqualToString:@"="]) && ([[self.operStack getTop] isEqualToString:@"="]) ) {
            break;
        }
      
        else if([self isOperator:str]){
          
            NSString *pr = [self comparePriority:[self.operStack getTop] outOptr:str];
            NSArray *items = @[@"<", @"=", @">"];
            int item = (int)[items indexOfObject:pr];
            
            switch (item) {
                case 0:
                  
                    [self.operStack push:str];
                    break;
                case 1:
                   
                    bracket = [self.operStack pop];
                    break;
                case 2:
                {
                    
                    i--;
                    oper = [self.operStack pop];
                    value2 = [self.valueStack pop];
                    value1 = [self.valueStack pop];

                    double a = [value1 doubleValue];
                    double b = [value2 doubleValue];
                    
                    double c = [self calculate:a opnd2:b optr:oper];
                    NSNumber *num = [[NSNumber alloc] initWithDouble:c];
                    NSString *result = [num stringValue];
                    [self.valueStack push:result];
                    break;
                }
                default:
                    break;
            }
        }
        
        else{
         
            NSUInteger j = i+1;
            if (j<[inputString length]) {
                char nextch = [inputString characterAtIndex:j];
                NSString *nextstr = [NSString stringWithFormat:@"%c", nextch];
               
                if(![self isOperator:nextstr])
                    continue;
                else{
                    [self.valueStack push:[self.valueArray firstObject]];
                    [self.valueArray removeObjectAtIndex:0];
                }
            }
            else{
                [self.valueStack push:[self.valueArray firstObject]];
                [self.valueArray removeObjectAtIndex:0];
            }
        }
    }
    
    NSString *expResult = [self.valueStack getTop];
    return expResult;
}
@end

math.m

//
//  main.m
//  Lab1
//
//  Created by 苏泽萱 on 2019/12/12.
//  Copyright © 2019 苏泽萱. All rights reserved.
//
#import <Foundation/Foundation.h>
#include "Math.h"

int main(int argc, const char * argv[]) {
   

   NSString *str = @"4a";
    NSLog(@"%@",str);
    
    
    Math *calculator = [[Math alloc]init];
    NSString *result = [calculator ExpressionCalculate:str];
    NSLog(@"%@",result);
    
        return 0;
}

main.m函数

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值