我正在制作一个具有罗马数字模式的计算器。我在模型视图中执行了操作,还有一个视图控制器。我的问题是我需要将罗马数字转换为NSNumber。有一个UILabel,视图控制器获取标签中的内容并将其设置为模型视图的操作数。有谁知道如何从标签中取出罗马数字并使其成为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]);
}
答案 0 :(得分:2)
以下是一些可以帮助您的资源:
Roman Numbers Convert - 这个可能是两者中较好的一个,因为这有前向/后向翻译
pzearfoss / NSNumber-RomanNumerals - 这是一个简单的类别;但是,它只将NSNumber转换为Roman Numeral。你可以调整它来反过来。
答案 1 :(得分:1)
你可以尝试这个功能
-(NSString*)numberToRomanNumerals:(int)num{
if (num < 0 || num > 9999) { return @""; } // out of range
NSArray *r_ones = [[NSArray alloc]initWithObjects:@"I", @"II", @"III", @"IV", @"V", @"VI", @"VII", @"VIII",@"IX",nil];
NSArray *r_tens = [[NSArray alloc]initWithObjects:@"X", @"XX", @"XXX", @"XL", @"L", @"LX", @"LXX",@"LXXX", @"XC",nil];
NSArray *r_hund = [[NSArray alloc]initWithObjects:@"C", @"CC", @"CCC", @"CD", @"D", @"DC", @"DCC",@"DCCC", @"CM",nil];
NSArray *r_thou = [[NSArray alloc]initWithObjects:@"M", @"MM", @"MMM", @"MMMM", @"MMMMM", @"MMMMMM",@"MMMMMMM",
@"MMMMMMMM", @"MMMMMMMMM",nil];
int ones = num % 10;
int tens = (num - ones) % 100;
int hundreds = (num - tens - ones) % 1000;
int thou = (num - hundreds - tens - ones) % 10000;
tens = tens / 10;
hundreds = hundreds / 100;
thou = thou / 1000;
NSString *rnum=@"";
if (thou) { rnum = [rnum stringByAppendingString:[r_thou objectAtIndex:thou-1]]; }
if (hundreds) { rnum = [rnum stringByAppendingString:[r_hund objectAtIndex:hundreds-1]]; }
if (tens) { rnum = [rnum stringByAppendingString:[r_tens objectAtIndex:tens-1]]; }
if (ones) { rnum = [rnum stringByAppendingString:[r_ones objectAtIndex:ones-1]]; }
[r_ones release];
[r_tens release];
[r_hund release];
[r_thou release];
return rnum;
}
答案 2 :(得分: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
//==============================================================================