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

@"(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 = ; i<StringToCompute.length; i++) {
if([StringToCompute characterAtIndex:i]=='('){
NSString * str = [StringToCompute substringWithRange:NSMakeRange(, i)]; [myStack push:str]; NSString *strtemp = [StringToCompute substringWithRange:NSMakeRange(i+, StringToCompute.length-i-)]; StringToCompute = [[NSMutableString alloc]initWithString:strtemp]; break;
} if([StringToCompute characterAtIndex:i]==')'){
NSString *strTemp = [StringToCompute substringToIndex:i];
StringToCompute =[StringToCompute substringWithRange:NSMakeRange(i+,StringToCompute.length-i-)];
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-){

//已没有括号


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 = ; i<strTmp.length; i++) {
char c= [strTmp characterAtIndex:i];
if(c=='+'||c=='-'||c=='*'||c=='/'){
          //拆开式子
NSString * temp = [strTmp substringWithRange:NSMakeRange(, i)];
[array addObject:temp];
temp = [strTmp substringWithRange:NSMakeRange(i, i)];
[array addObject:temp];
strTmp = [strTmp substringWithRange:NSMakeRange(i+, strTmp.length - i-)];
if(strTmp.length<=){
needContinue = false;
[array addObject:strTmp];
}
break;
}
} if(!needContinue){
break;
} }
// NSLog(@"%@",array); while (true) {
     //做 * 和 /
Boolean needFinish = false;
for (int i = ; i< array.count ; i++) {
if([array[i] isEqual:@"/"]||[array[i] isEqual:@"*"]){
NSNumber *left = array[i-];
NSNumber *right = array[i+];
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-];
NSLog(@"%@",array);
[array removeObjectAtIndex:i];
NSLog(@"%@",array);
break;
}
if (i==array.count -){
needFinish = true;
}
} if(needFinish){
NSLog(@"%@",array);
break;
}
} while (true) {
Boolean needFinish = false;
     //做 + 和 - 运算
for (int i = ; i< array.count ; i++) {
if([array[i] isEqual:@"+"]||[array[i] isEqual:@"-"]){
NSNumber *left = array[i-];
NSNumber *right = array[i+];
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-];
NSLog(@"%@",array);
[array removeObjectAtIndex:i];
NSLog(@"%@",array);
break;
}
if (i==array.count -){
needFinish = true;
}
} if(needFinish){
NSLog(@"%@",array);
break;
}
} return (NSNumber*)array[]; } @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 = - ;
for (int i =; i< [self length]; i++) {
if('c'== [self characterAtIndex:i]){
index = i ;
break;
}
}
return index ;
} -(int) lastIndexOf:(char)c {
int index = - ;
for (int i =; 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 ;
}

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

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

oc 计算 带括号 式子的更多相关文章

  1. 使用python开发一个能够计算带括号的复杂表达式的计算器(只支持加减乘除)

    使用到了模块re,正则,字典等 # 实现简单的加减乘除括号等运算 # Calculator def calculator(expression): print(expression) import r ...

  2. 算法进阶面试题06——实现LFU缓存算法、计算带括号的公式、介绍和实现跳表结构

    接着第四课的内容,主要讲LFU.表达式计算和跳表 第一题 上一题实现了LRU缓存算法,LFU也是一个著名的缓存算法 自行了解之后实现LFU中的set 和 get 要求:两个方法的时间复杂度都为O(1) ...

  3. Python带括号的计算器

    带括号的计算器也是第一个自我感觉完成最好的 毕竟真的弄了一个多星期 虽然前期这路真的很难走  我会努力加油  将Python学好学踏实 参考了两位博主的文章 http://www.cnblogs.co ...

  4. 修改phpcms会员登录后头部登陆条的会员名称不带括号

    phpcms会员登录后显示会员名称是带括号的,现在把他修改成不带括号. 找到函数库libs/functions/global.func.php,修改如下即可: function get_nicknam ...

  5. c++ new带括号和不带括号

    在new对象的时候有加上(),有不加(),不知道这个到底是什么区别?比如:CBase *base = new CDerived();CBase *base = new CDeviced; 很多人都说, ...

  6. [转]c++ new带括号和不带括号

    ref:http://m.blog.csdn.net/blog/u012745772/42420443 在new对象的时候有加上(),有不加(),不知道这个到底是什么区别?比如:CBase *base ...

  7. js中new函数后带括号和不带括号的区别

    用new创建构造函数的实例时,通常情况下new 的构造函数后面需要带括号(譬如:new Parent()). 有些情况下new的构造函数后带括号和不带括号的情况一致,譬如: function Pare ...

  8. 解决VS Code开发Python3语言自动补全功能不带括号的问题

    Visual Studio Code(以下简称VS Code)用来开发Python3,还是很便利的,本身这个IDE就是轻量级的,才几十兆大小,通过安装插件的方式支持各种语言的开发.界面也美美哒,可以在 ...

  9. Eclipse中Server视图加载项目之后项目名后边有带括号的名字

    用习惯了eclipse工具,因为某种原因需要修改项目名称.结果选择项目,按“F2”成功修改后,使用tomcat进行web发布时,选择“Add and Remove”,发现名字还是以前那个项目名称.即使 ...

随机推荐

  1. md加密 16位 32位

    16位大写 //生成MD5 public static String getMD5(String message) { String md5 = ""; try { Message ...

  2. python入坑级

    pycharm设置 pycharm设置自动换行的方法 只对当前文件有效的操作:菜单栏->View -> Active Editor -> Use Soft Wraps: 如果想对所有 ...

  3. Delphi ActiveX编程

    樊伟胜

  4. Delphi 图形组件(Shape)

    樊伟胜

  5. deep_learning_Softmax()

    该节课中提到了一种叫作softmax的函数,因为之前对这个概念不了解,所以本篇就这个函数进行整理,如下: 维基给出的解释:softmax函数,也称指数归一化函数,它是一种logistic函数的归一化形 ...

  6. redis整合Spring入门

    首先 衷心感谢这篇博客给我入门时的启发  三颗心脏 你需要知道,spring的官方文档中已经注明,与redis整合时,spring的jar包版本不能低于4.2.6,否则不支持,会报错的哟 测试的时候请 ...

  7. 2.Nginx基本配置

    1. Nginx相关概念 代理服务器一般分为正向代理(通常直接称为代理服务器)和反向代理. 通常的代理服务器,只用于代理内部网络对Internet的连接请求,客户机必须指定代理服务器,并将本来要直接发 ...

  8. TCP的ACK原理和延迟确认机制

    某天晚上睡觉前突然想到 tcp的ACK确认是单独发的还是和报文一起发的,下面看一下别人的解答 一.ACK定义TCP协议中,接收方成功接收到数据后,会回复一个ACK数据包,表示已经确认接收到ACK确认号 ...

  9. mybatic MapperScannerConfigurer的原理

    原文地址:http://www.cnblogs.com/fangjian0423/p/spring-mybatis-MapperScannerConfigurer-analysis.html 前言 本 ...

  10. java面试题(目录版)

    在https://www.cnblogs.com/marsitman/p/9539369.html  根据自己以往的面试经验,在该基础上做了补充和删减,均链接到相应的地址(链接失效请留言评论). 一. ...