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 = ; 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 计算 带括号 式子的更多相关文章
- 使用python开发一个能够计算带括号的复杂表达式的计算器(只支持加减乘除)
使用到了模块re,正则,字典等 # 实现简单的加减乘除括号等运算 # Calculator def calculator(expression): print(expression) import r ...
- 算法进阶面试题06——实现LFU缓存算法、计算带括号的公式、介绍和实现跳表结构
接着第四课的内容,主要讲LFU.表达式计算和跳表 第一题 上一题实现了LRU缓存算法,LFU也是一个著名的缓存算法 自行了解之后实现LFU中的set 和 get 要求:两个方法的时间复杂度都为O(1) ...
- Python带括号的计算器
带括号的计算器也是第一个自我感觉完成最好的 毕竟真的弄了一个多星期 虽然前期这路真的很难走 我会努力加油 将Python学好学踏实 参考了两位博主的文章 http://www.cnblogs.co ...
- 修改phpcms会员登录后头部登陆条的会员名称不带括号
phpcms会员登录后显示会员名称是带括号的,现在把他修改成不带括号. 找到函数库libs/functions/global.func.php,修改如下即可: function get_nicknam ...
- c++ new带括号和不带括号
在new对象的时候有加上(),有不加(),不知道这个到底是什么区别?比如:CBase *base = new CDerived();CBase *base = new CDeviced; 很多人都说, ...
- [转]c++ new带括号和不带括号
ref:http://m.blog.csdn.net/blog/u012745772/42420443 在new对象的时候有加上(),有不加(),不知道这个到底是什么区别?比如:CBase *base ...
- js中new函数后带括号和不带括号的区别
用new创建构造函数的实例时,通常情况下new 的构造函数后面需要带括号(譬如:new Parent()). 有些情况下new的构造函数后带括号和不带括号的情况一致,譬如: function Pare ...
- 解决VS Code开发Python3语言自动补全功能不带括号的问题
Visual Studio Code(以下简称VS Code)用来开发Python3,还是很便利的,本身这个IDE就是轻量级的,才几十兆大小,通过安装插件的方式支持各种语言的开发.界面也美美哒,可以在 ...
- Eclipse中Server视图加载项目之后项目名后边有带括号的名字
用习惯了eclipse工具,因为某种原因需要修改项目名称.结果选择项目,按“F2”成功修改后,使用tomcat进行web发布时,选择“Add and Remove”,发现名字还是以前那个项目名称.即使 ...
随机推荐
- md加密 16位 32位
16位大写 //生成MD5 public static String getMD5(String message) { String md5 = ""; try { Message ...
- python入坑级
pycharm设置 pycharm设置自动换行的方法 只对当前文件有效的操作:菜单栏->View -> Active Editor -> Use Soft Wraps: 如果想对所有 ...
- Delphi ActiveX编程
樊伟胜
- Delphi 图形组件(Shape)
樊伟胜
- deep_learning_Softmax()
该节课中提到了一种叫作softmax的函数,因为之前对这个概念不了解,所以本篇就这个函数进行整理,如下: 维基给出的解释:softmax函数,也称指数归一化函数,它是一种logistic函数的归一化形 ...
- redis整合Spring入门
首先 衷心感谢这篇博客给我入门时的启发 三颗心脏 你需要知道,spring的官方文档中已经注明,与redis整合时,spring的jar包版本不能低于4.2.6,否则不支持,会报错的哟 测试的时候请 ...
- 2.Nginx基本配置
1. Nginx相关概念 代理服务器一般分为正向代理(通常直接称为代理服务器)和反向代理. 通常的代理服务器,只用于代理内部网络对Internet的连接请求,客户机必须指定代理服务器,并将本来要直接发 ...
- TCP的ACK原理和延迟确认机制
某天晚上睡觉前突然想到 tcp的ACK确认是单独发的还是和报文一起发的,下面看一下别人的解答 一.ACK定义TCP协议中,接收方成功接收到数据后,会回复一个ACK数据包,表示已经确认接收到ACK确认号 ...
- mybatic MapperScannerConfigurer的原理
原文地址:http://www.cnblogs.com/fangjian0423/p/spring-mybatis-MapperScannerConfigurer-analysis.html 前言 本 ...
- java面试题(目录版)
在https://www.cnblogs.com/marsitman/p/9539369.html 根据自己以往的面试经验,在该基础上做了补充和删减,均链接到相应的地址(链接失效请留言评论). 一. ...