0

ローマ数字モードの電卓を作っています。モデルビューとビューコントローラーで操作を実行しました。私の問題は、ローマ数字を NSNumber に変換する必要があることです。UILabel があり、View Controller はラベルにあるものを取得し、それをモデル ビューのオペランドとして設定します。ラベルからローマ数字を取得して NSNumber にする方法を知っている人はいますか? ここにいくつかのコードがあります:

- (IBAction)digitPressed:(UIButton *)sender {


    NSString *digit = [[sender titleLabel] text];
    if (self.userIsTypingNumber) {
      [self.display setText:[self.display.text stringByAppendingString:digit]];
    } else {
        [self.display setText:digit];
        self.userIsTypingNumber = YES;
    }
}

- (IBAction)operationPressed:(UIButton *)sender {

    if (self.userIsTypingNumber) {
        if ([self isValidForRoman:self.display.text] == YES) {
            //find out what roman numeral is in the display
        } else {
        NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc]init];
        [numberFormatter setNumberStyle: NSNumberFormatterDecimalStyle];
        NSNumber *n = [numberFormatter numberFromString:self.display.text];
        [[Model singleton] setOperand:n];
        self.userIsTypingNumber = NO;
        }
    }
    NSString *operation = [[sender titleLabel] text];
    NSNumber *result = [[Model singleton] performOperation:operation];
    [self.display setText:[NSString stringWithFormat:@"%@", result]];
}

- (IBAction)clearDigitPressed:(UIButton *)sender {

    [self.display setText:@""];
}

- (IBAction)clearOperationPressed:(UIButton *)sender {

    [[Model singleton] performOperation:nil];
    [self.display setText:@""];
}

- (IBAction)changeNumeralType:(id)sender {

    switch ([sender selectedSegmentIndex]) {
        case 0:
        {            
            [self.button1 setTitle:@"1" forState:UIControlStateNormal];
            [self.button2 setTitle:@"2" forState:UIControlStateNormal];
            [self.button3 setTitle:@"3" forState:UIControlStateNormal];
            [self.button4 setTitle:@"4" forState:UIControlStateNormal];
            [self.button5 setTitle:@"5" forState:UIControlStateNormal];
            [self.button6 setTitle:@"6" forState:UIControlStateNormal];
            [self.button7 setTitle:@"7" forState:UIControlStateNormal];
            [self.button8 setTitle:@"8" forState:UIControlStateNormal];
            [self.button9 setTitle:@"9" forState:UIControlStateNormal];
            [self.button0 setTitle:@"0" forState:UIControlStateNormal];
        } break;

        case 1:
        {
            [self.button1 setTitle:@"L" forState:UIControlStateNormal];
            [self.button2 setTitle:@"C" forState:UIControlStateNormal];
            [self.button3 setTitle:@"D" forState:UIControlStateNormal];
            [self.button4 setTitle:@"I" forState:UIControlStateNormal];
            [self.button5 setTitle:@"V" forState:UIControlStateNormal];
            [self.button6 setTitle:@"X" forState:UIControlStateNormal];
            [self.button7 setTitle:@"" forState:UIControlStateNormal];
            [self.button8 setTitle:@"" forState:UIControlStateNormal];
            [self.button9 setTitle:@"" forState:UIControlStateNormal];
            [self.button0 setTitle:@"M" forState:UIControlStateNormal];

        } break;

    }
}

- (BOOL)isValidForRoman:(NSString *)text
{
    NSString *romanRegex = @"^(?=.)(?i)M*(D?C{0,3}|C[DM])(L?X{0,3}|X[LC])(V?I{0,3}|I[VX])$";
    NSPredicate *romanTest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", romanRegex];
    return ([romanTest evaluateWithObject:text]);
}
4

3 に答える 3

2

以下に、役立つリソースをいくつか示します。

ローマ数字の変換 - これは前方/後方変換があるため、おそらく 2 つのうちのほうが優れています。

pzearfoss / NSNumber-RomanNumerals - これは単純なカテゴリです。ただし、NSNumber をローマ数字に変換するだけです。それを微調整して、逆の方向に進むことができる場合があります。

于 2013-02-07T22:36:07.870 に答える
1

私が以前に見たものはすべて少し奇妙だったので、1つだけ書いたので、試してみてください: https://github.com/shoumikhin/RomanNumeral

//==============================================================================
@implementation NSNumber (RomanNumeral)
//------------------------------------------------------------------------------
- (NSString *)encodeRomanDigit:(NSInteger)value one:(NSString *)one five:(NSString *)five ten:(NSString *)ten
{
    switch (value)
    {
        case 1 :

            return [NSString stringWithFormat:@"%@", one];

        case 2 :

            return [NSString stringWithFormat:@"%@%@", one, one];

        case 3 :

            return [NSString stringWithFormat:@"%@%@%@", one, one, one];

        case 4 :

            return [NSString stringWithFormat:@"%@%@", one, five];

        case 5 :

            return [NSString stringWithFormat:@"%@", five];

        case 6 :

            return [NSString stringWithFormat:@"%@%@", five, one];

        case 7 :

            return [NSString stringWithFormat:@"%@%@%@", five, one, one];

        case 8 :

            return [NSString stringWithFormat:@"%@%@%@%@", five, one, one, one];

        case 9 :

            return [NSString stringWithFormat:@"%@%@", one, ten];
    }

    return @"";
}
//------------------------------------------------------------------------------
- (NSString *)encodeRomanDigit:(NSInteger)value withDigitNumber:(NSUInteger)digitPosition
{
    switch (digitPosition)
    {
        case 0 :

            return [self encodeRomanDigit:value one:@"I" five:@"V" ten:@"X"];

        case 1 :

            return [self encodeRomanDigit:value one:@"X" five:@"L" ten:@"C"];

        case 2 :

            return [self encodeRomanDigit:value one:@"C" five:@"D" ten:@"M"];

        case 3 :

            return [self encodeRomanDigit:value one:@"M" five:@"" ten:@""];
    }

    return @"";
}
//------------------------------------------------------------------------------
- (NSString *)romanNumeralStringValue
{
    NSMutableString *ret = @"".mutableCopy;
    NSUInteger value = self.unsignedIntegerValue;
    NSUInteger base = 10;
    NSUInteger digitPosition = 0;
    NSUInteger const ROMAN_NUMBER_MAX = 4000;

    if (value < ROMAN_NUMBER_MAX)
      do
      {
          [ret insertString:[self encodeRomanDigit:value % base withBase:digitPosition] atIndex:0];
          digitPosition++;
      }
      while (value /= base);

    return ret;
}
//------------------------------------------------------------------------------
@end
//==============================================================================
@implementation NSString (RomanNumeral)
//------------------------------------------------------------------------------
- (NSInteger)decodeRomanDigit:(char)romanDigit
{
    switch (romanDigit)
    {
        case 'I' :
        case 'i' :

            return 1;

        case 'V' :
        case 'v' :
        case 'U' :
        case 'u' :

            return 5;

        case 'X' :
        case 'x' :

            return 10;

        case 'L' :
        case 'l' :

            return 50;

        case 'C' :
        case 'c' :

            return 100;

        case 'D' :
        case 'd' :

            return 500;

        case 'M' :
        case 'm' :

            return 1000;
    }

    return 0;
}
//------------------------------------------------------------------------------
- (NSInteger)romanNumeralValue
{
    NSInteger ret = 0;
    NSUInteger length = self.length;
    unichar buffer[length];

    [self getCharacters:buffer range:NSMakeRange(0, length)];

    for (int i = 0; i < length; ++i)
    {
        NSInteger current = [self decodeRomanDigit:buffer[i]];
        NSInteger next = i + 1 < length ? [self decodeRomanDigit:buffer[i + 1]] : 0;

        if (next > current)
        {
            ret += next - current;
            i++;
        }
        else
            ret += current;
    }

    return ret;
}
//------------------------------------------------------------------------------
@end
//==============================================================================
于 2014-01-24T23:33:33.437 に答える