使用栈实现整型四则运算
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