iOS:Case.计算器Calculator Modal写法对比

来源:互联网 发布:产品群发软件 编辑:程序博客网 时间:2024/05/05 23:01

============自己的============

定义:

 double result;    NSString *operator;      NSMutableString *operand1;    double operand0;
主要方法:
// 获取结果-(NSString *)getCalculateOutput{        return [NSString stringWithFormat:@"%f",result];}//处理输入-(void)dealWithInput:(NSString *)input{        // num    if ([self inputIsOperand:input]) {        [operand1 appendString:input];        result  = [operand1 doubleValue];    }else{        // operator                int whichOperator = [self getOperator:operator];        switch (whichOperator) {            case 0:                result = [operand1 doubleValue];                                break;            case 1:                result = [operand1 doubleValue] + operand0;                                break;            case 2:                result = [operand1 doubleValue] - operand0;                                break;            case 3:                result = [operand1 doubleValue] * operand0;                                break;            case 4:                result = [operand1 doubleValue] / operand0;                break;                            default:                break;        }         operand0 = result;        operator = [NSString stringWithString:input];        [operand1 setString:@""];            }}-(BOOL)inputIsOperand:(NSString *)input{        if ([@"0123456789" rangeOfString:input].length > 0) {        return YES;    }    return NO;}-(int)getOperator:(NSString *)aOperator{        if ([aOperator isEqualToString:@"+"]) {        return Add;    }else if([aOperator isEqualToString:@"-"]){        return Sub;    }else if([aOperator isEqualToString:@"*"]){        return Mul;    }else if([aOperator isEqualToString:@"*"]){        return Div;    }    return non;}

============官网============

定义:

@private   NSMutableString *_display;    // The calculator display (the value a harwdare-based calculator shows on its LCD screen).   double           _operand;   NSString        *_operator;
// These string constants contain the characters that the input: method accepts.const NSString *Operators = @"+-*/";const NSString *Equals    = @"=";const NSString *Digits    = @"0123456789.";const NSString *Period    = @".";const NSString *Delete    = @"D";const NSString *Clear     = @"C";
主要方法:
/* * The input: method accepts the characters in the string constants * Operators, Equals, Digits, Period Delete, and Clear. * * The results of this method's computations are stored in _display. * This method uses _operand, and _operator in its calculations. */- (void) input:(NSString *) input_character {   static BOOL last_character_is_operator = NO;   BOOL bad_character;      // Does input_character contain exactly one character?   if (!(bad_character = !(input_character && [input_character length] == 1))) {            // Is input_character in Digits?      if ([Digits rangeOfString: input_character].length) {         if (last_character_is_operator) {            // Set the display to input_character.            [_display setString: input_character];                        last_character_is_operator = NO;         }         // Is input_character a digit, or is a period while a period has not been added to _display?         else if (![input_character isEqualToString: (NSString *)Period] || [_display rangeOfString: (NSString *)Period].location == NSNotFound) {            // Add input_character to _display.            [_display appendString:input_character];         }      }            // Is input_character in Operators or is it Equals?      else if ([Operators rangeOfString:input_character].length || [input_character isEqualToString:(NSString *)Equals]) {         if (!_operator && ![input_character isEqualToString:(NSString *)Equals]) {            // input_character is this calculation's operator.            //            // Save the operand and the operator.            _operand  = [[self displayValue] doubleValue];            _operator = input_character;         }         else {            // input_character is in Operators or Equals.            //            // Perform the computation indicated by the saved operator between the saved operand and _display.            // Place the result in _display.            if (_operator) {               double operand2 = [[self displayValue] doubleValue];               switch ([Operators rangeOfString: _operator].location) {                  case 0:                     _operand = _operand + operand2;                     break;                  case 1:                     _operand = _operand - operand2;                     break;                  case 2:                     _operand = _operand * operand2;                     break;                  case 3:                     _operand = _operand / operand2;                     break;               }               [_display setString: [[NSNumber numberWithDouble: _operand] stringValue]];            }            // Save the operation (if this is a chained computation).            _operator = ([input_character isEqualToString:(NSString *)Equals])? nil : input_character;         }         last_character_is_operator = YES;      }      // Is input_character Delete?      else if ([input_character isEqualToString:(NSString *)Delete]) {         // Remove the rightmost character from _display.         NSInteger index_of_char_to_remove = [_display length] - 1;         if (index_of_char_to_remove >= 0) {            [_display deleteCharactersInRange:NSMakeRange(index_of_char_to_remove, 1)];            last_character_is_operator = NO;         }      }      // Is input_character Clear?      else if ([input_character isEqualToString:(NSString *)Clear]) {         // If there's something in _display, clear it.         if ([_display length]) {            [_display setString:[NSString string]];         }         // Otherwise, clear the saved operator.         else {            _operator = nil;         }      }      else {         // input_character is an unexpected (invalid) character.         bad_character = TRUE;      }   }   if (bad_character) {      // Raise exception for unexpected character.      NSException *exception = [NSException exceptionWithName:NSInvalidArgumentException                                                       reason:@"The input_character parameter contains an unexpected value."                                                     userInfo:[NSDictionary dictionaryWithObjectsAndKeys: input_character, @"arg0", nil]];      [exception raise];   }}#pragma mark Outlets/* * The displayValue method rerutns a copy of _display. */- (NSString *) displayValue {   if ([_display length]) {      return [_display copy];   }   return @"0";}

###############对比###############

---------算法-----------
--变量:
result:存储当前要显示的结果
operand0:存储上一个操作数
operator:存储上一个操作符
operand1:存储当前操作数
--输入处理:
输入如果是数字,保存为operand1,更新result的值;如果是操作符,则将之前保存的operand0、operator和operand1计算,并将结果保存为新的operand0,当前操作符保存为operator;更新result的值;
--输出:
显示result的值
---------------
--变量:
_display:显示的结果(当前操作数)
_operand:存储上一个操作数
_operator:存储上一个操作数
--输入处理:
输入如果是数字,_display接收输入,更新_display; 输入如果是运算符,判断是不是第一个运算符号,{如果是,保持操作数_operand和当前操作符_operator} {如果不是,将当前操作数_display、之前操作数_operand、操作符_operator运算,结果保存为新的operand,当前操作符保存为operator} 更新_display
--输出思路:
显示_display的值
-------比较
-大体一样,不过例2更精简(直接用显示的_display代替operand1,虽然_display显示的时候不总代表当前操作数operand1,但只要是开始运算,_display完全就是当前operand1),更全面(首个运算符号的判断);而且这更符合计算器model的思路,随意的输入值然后从display中get结果。

-算法,不仅仅要考虑变量选择,逻辑思路,对于变量初值的选择也很重要,_display为空字符串,operator为nil,lastCharacterIsOperator为no,这些值跟算法思路和逻辑分支判断完全对起来了;这些初值完全适用代码的逻辑判断,

-一个算法最基本要满足‘正常情况/循环结构’的处理,好的算法,变量初值完全契合‘正常情况/循环结构’,就像该例,循环结构为:碰到数字,更新显示;碰到运算符,如果运算符为nil怎么处理,或者用operator运算当前显示和operand,或者更新运算符(本例子不是做更新处理,另外一种思路);这些情况初值完全适用,开始时候,输入数字,更新display,如果输入计算符,默认operand为0,同时operator为当前输入的运算符。算法思路详见‘算法’分类中‘概念’文章。
----------命名问题----------

--result既然是存储着要显示的结果,叫display更合理;它不是运算结果(当输入操作数的时候,它的值为操作数)

--成员变量名字没有前缀下划线;
----------质量问题----------
--没有异常判断:对输入的字符串长度是不是1,有没有值,没判断,直接当作正确的去用了;
--没有合法值判断:输入的字符串应该限定在自己接受的范围内;
--考虑条件不够全面,算法逻辑不清晰:当运算完,当前操作符为‘=’号和其它符号的区别处理

----------其他技巧----------

- 第一个操作数为double类型,操作符和第二个操作数位字符串类型;

- 输入一个字符串判断是哪个字符:switch方法([const字符串常量 rangOfString ].location),其中case直接是数字,而不用写很多if,else if判断;

0 0