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

@"(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. maven入门-- part4 坐标和依赖

    Maven的坐标为各种构件引入了秩序,任何一个构件都必须明确的定义自己的坐标,maven的坐标包括如下的元素: groupId: 定义当前Maven项目隶属的实际项目 artifactId: 该元素定 ...

  2. SpringBoot面试题

    详见:https://www.cnblogs.com/3xmq/p/springboot.html https://blog.csdn.net/yuzongtao/article/details/84 ...

  3. beego中获取url以及参数的方式

    以下都全默认在controller下执行 获取当前请求的referer fmt.Println(this.Ctx.Request.Referer()) 输出:http://localhost:8080 ...

  4. layDate面板出现红色花纹图案

    要使用layDate,有两种方法: 1. 要么在引用layui.js和layui.css,然后通过layui.use('laydate', callback) 加载模块后,调用方法使用. 2. 去la ...

  5. js数组的所有方法

    修改器方法 下面的这些方法会改变调用它们的对象自身的值: Array.prototype.copyWithin()  在数组内部,将一段元素序列拷贝到另一段元素序列上,覆盖原有的值. Array.pr ...

  6. Samba passwd smbpasswd and tdbsam

    ome commands to convert samba backend password-databases. If you use "passdb backend = smbpassw ...

  7. CAN总线简介:如何以编程方式控制汽车

    最近,我正与Voyage公司的朋友合作研究,以实现福特Fusion空调系统(A/C)的编程控制.目前,Voyage公司正努力打造自动驾驶的终极目标:能够以低廉的价格成本和广泛的投放范围,把世界任何地方 ...

  8. MySQL单表查询实例

    数据表准备 ​```mysql create table emp( id int not null unique auto_increment, name varchar(20) not null, ...

  9. 使用js拆分带参数的URL,将参数分离出来

    url中的内容www.XXXX.com?content=123; 一下为js内容,包装在一个init方法中. init(); function init(){ var theRequest = new ...

  10. MQTT 入门介绍——菜鸟教程

    一.简述 MQTT(Message Queuing Telemetry Transport,消息队列遥测传输协议),是一种基于发布/订阅(publish/subscribe)模式的"轻量级& ...