使用栈实现整型四则运算
This commit is contained in:
parent
619caada3f
commit
90c0e319a9
21
object-c/08_stack/stack_practice/ArrayStack.h
Normal file
21
object-c/08_stack/stack_practice/ArrayStack.h
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
|
||||||
|
/**
|
||||||
|
栈实现
|
||||||
|
|
||||||
|
Author: Smallfly
|
||||||
|
*/
|
||||||
|
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
|
||||||
|
@interface Stack : NSObject
|
||||||
|
|
||||||
|
- (id)initWithCapacity:(NSUInteger)count;
|
||||||
|
|
||||||
|
- (BOOL)isEmpty;
|
||||||
|
- (id)top;
|
||||||
|
- (NSUInteger)size;
|
||||||
|
|
||||||
|
- (BOOL)push:(id)obj;
|
||||||
|
- (id)pop;
|
||||||
|
|
||||||
|
@end
|
49
object-c/08_stack/stack_practice/ArrayStack.m
Normal file
49
object-c/08_stack/stack_practice/ArrayStack.m
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
#import "ArrayStack.h"
|
||||||
|
|
||||||
|
@implementation Stack {
|
||||||
|
NSMutableArray *_arr;
|
||||||
|
NSUInteger _capacity;
|
||||||
|
NSUInteger _count;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (id)initWithCapacity:(NSUInteger)capacity {
|
||||||
|
self = [super init];
|
||||||
|
_capacity = capacity;
|
||||||
|
_arr = [[NSMutableArray alloc] initWithCapacity:capacity];
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL)isEmpty {
|
||||||
|
return _arr.count == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL)isFull {
|
||||||
|
return _arr.count == _capacity;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (id)top {
|
||||||
|
if ([self isEmpty]) return nil;
|
||||||
|
NSUInteger index = _arr.count - 1;
|
||||||
|
return _arr[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSUInteger)size {
|
||||||
|
return _arr.count;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL)push:(id)obj {
|
||||||
|
if (!obj) return NO;
|
||||||
|
if (_arr.count == _capacity) return NO;
|
||||||
|
[_arr addObject:obj];
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (id)pop {
|
||||||
|
if ([self isEmpty]) return nil;
|
||||||
|
NSUInteger index = _arr.count - 1;
|
||||||
|
id obj = _arr[index];
|
||||||
|
[_arr removeLastObject];
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
22
object-c/08_stack/stack_practice/FourOperation.h
Normal file
22
object-c/08_stack/stack_practice/FourOperation.h
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
|
||||||
|
/**
|
||||||
|
整型四则运算
|
||||||
|
|
||||||
|
Author: Smallfly
|
||||||
|
*/
|
||||||
|
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
|
||||||
|
@interface FourOperation : NSObject
|
||||||
|
|
||||||
|
+ (FourOperation *)shared;
|
||||||
|
|
||||||
|
/**
|
||||||
|
整型四则运算
|
||||||
|
|
||||||
|
@param expression 运算表达式,注意操作数和运算符之间要有空格
|
||||||
|
@return 计算结果
|
||||||
|
*/
|
||||||
|
- (NSNumber *)caculateExpression:(NSString *)expression;
|
||||||
|
|
||||||
|
@end
|
102
object-c/08_stack/stack_practice/FourOperation.m
Normal file
102
object-c/08_stack/stack_practice/FourOperation.m
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
#import "FourOperation.h"
|
||||||
|
#import "ArrayStack.h"
|
||||||
|
|
||||||
|
NSDictionary *OptPriority() {
|
||||||
|
return @{@"*": @1, @"/": @1, @"+": @0, @"-": @0};
|
||||||
|
}
|
||||||
|
|
||||||
|
@implementation FourOperation {
|
||||||
|
@private
|
||||||
|
Stack *_optStack;
|
||||||
|
Stack *_numStack;
|
||||||
|
NSNumberFormatter *_numFormatter;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ (FourOperation *)shared {
|
||||||
|
static FourOperation* single = nil;
|
||||||
|
static dispatch_once_t onceToken;
|
||||||
|
dispatch_once(&onceToken, ^{
|
||||||
|
single = [FourOperation new];
|
||||||
|
});
|
||||||
|
return single;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (instancetype)init {
|
||||||
|
self = [super init];
|
||||||
|
_optStack = [[Stack alloc] initWithCapacity:100];
|
||||||
|
_numStack = [[Stack alloc] initWithCapacity:100];
|
||||||
|
_numFormatter = [NSNumberFormatter new];
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (id)caculateExpression:(NSString *)expression {
|
||||||
|
NSArray *elements = [expression componentsSeparatedByString:@" "];
|
||||||
|
|
||||||
|
for (NSString *obj in elements) {
|
||||||
|
NSNumber *numb = [_numFormatter numberFromString:obj];
|
||||||
|
if (numb) { // 运算数
|
||||||
|
[_numStack push:numb];
|
||||||
|
} else { // 操作符
|
||||||
|
|
||||||
|
// 如果栈顶操作符优先级大于等于当前操作符
|
||||||
|
while ([self _topOperationPriorityIsHigherOrEqualToOperation:obj]) {
|
||||||
|
|
||||||
|
// 取出栈顶的操作符和两个操作数做一次运算
|
||||||
|
NSNumber *res = [self _excuteOnceCaculate];
|
||||||
|
|
||||||
|
// 计算结果存入栈
|
||||||
|
[_numStack push:res];
|
||||||
|
}
|
||||||
|
|
||||||
|
[_optStack push:obj];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果操作符存在栈中,依次取出做运算
|
||||||
|
NSNumber *res = nil;
|
||||||
|
while ([_optStack top]) {
|
||||||
|
res = [self _excuteOnceCaculate];
|
||||||
|
[_numStack push:res];
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSInteger)_getPriority:(NSString *)opt {
|
||||||
|
return [[OptPriority() objectForKey:opt] integerValue];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL)_topOperationPriorityIsHigherOrEqualToOperation:(NSString *)opt {
|
||||||
|
NSString *topOpt = [_optStack top];
|
||||||
|
if (!topOpt) return NO;
|
||||||
|
NSInteger curPriority = [self _getPriority:opt];
|
||||||
|
NSInteger topPriority = [self _getPriority:topOpt];
|
||||||
|
return curPriority <= topPriority;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSNumber *)_excuteOnceCaculate {
|
||||||
|
NSNumber *numRight = [_numStack pop];
|
||||||
|
NSNumber *numLeft = [_numStack pop];
|
||||||
|
NSString *topOpt = [_optStack pop];
|
||||||
|
NSInteger result = [self _caculeteWithNumberLeft:numLeft numberRight:numRight operation:topOpt];
|
||||||
|
NSNumber *res = [NSNumber numberWithInteger:result];
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSInteger)_caculeteWithNumberLeft:(NSNumber *)numLeft numberRight:(NSNumber *)numRight operation:(NSString *)opt {
|
||||||
|
if (!numLeft || !numRight || !opt) return 0;
|
||||||
|
NSInteger left = [numLeft integerValue];
|
||||||
|
NSInteger right = [numRight integerValue];
|
||||||
|
if ([opt isEqualToString:@"+"]) {
|
||||||
|
return left + right;
|
||||||
|
} else if ([opt isEqualToString:@"-"]) {
|
||||||
|
return left - right;
|
||||||
|
} else if ([opt isEqualToString:@"*"]) {
|
||||||
|
return left * right;
|
||||||
|
} else if ([opt isEqualToString:@"/"]) {
|
||||||
|
return left / right;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
Loading…
Reference in New Issue
Block a user