加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

如何使用标准C拒绝无效数字时将罗马数字转换为int?

发布时间:2020-12-16 10:06:26 所属栏目:百科 来源:网络整理
导读:为了这个问题,为了简单起见(没有Unicode,没有乘法原理,没有双减法,没有上拉,没有大数等等),有效的罗马数字由 the regex定义: ^(M{0,3})(D?C{0,3}|CM|CD)(L?X{0,3}|XC|XL)(V?I{0,3}|IX|IV)$ Code example with POSIX regexec() .正则表达式匹配使用“严格”
为了这个问题,为了简单起见(没有Unicode,没有乘法原理,没有双减法,没有上拉,没有大数等等),有效的罗马数字由 the regex定义:

^(M{0,3})(D?C{0,3}|CM|CD)(L?X{0,3}|XC|XL)(V?I{0,3}|IX|IV)$

Code example with POSIX regexec().正则表达式匹配使用“严格”规则表示的1..3999范围内的罗马数字.

如果我们不需要拒绝无效数字,有许多解决方案可以转换罗马数字,例如:

int roman_numeral_value(unsigned char c)
{
  switch(toupper(c)) {
  case 'I': return 1;
  case 'V': return 5;
  case 'X': return 10;
  case 'L': return 50;
  case 'C': return 100;
  case 'D': return 500;
  case 'M': return 1000;
  default: return 0; // error
  }
}

int roman_numeral_to_int(const char *s,int size)
{
  int total = 0,prev = 0;
  for (int i = size-1; i >= 0; --i) { // in reverse order
    int value = roman_numeral_value(s[i]);
    total += value < prev ? -value : value; // subtract if necessary
    prev = value;
  }
  return total;
}

It works for valid Roman numerals.但是roman_numeral_to_int()接受正则表达式拒绝的数字,例如IIIII.是否有一个类似的简单跨平台解决方案,不需要pcre_exec()或其他外部依赖项,适用于有效的罗马数字,仅适用于它们?

解决方法

使用strcmp()或换句话说,往返字符串.

首先考虑反向问题,数字 – >串.

有许多方法可以有效地将整数转换为罗马数字串.我们称之为:

// return false on error due to `value` range error or scant `size`
bool roman_int_to_string(char *dest,size_t size,int value);

除了字母案例问题之外,规范罗马数字字符串和int之间存在一对一的关系.只需将源字符串转换为int,然后将int转换为另一个测试字符串.如果这些字符串匹配,我们就有赢家.

#define ROMAN_STRING_N 20
int roman_numeral_to_int_with_validate(const char *s,int size,bool *is_canonical) {
  int value = roman_numeral_to_int(s,size);

  char test[ROMAN_STRING_N];
  *is_canonical = roman_int_to_string(test,sizeof test,value);
  if (*is_canonical) {
    if (strcmp(s,test)) {  // Or use a case insensitive compare as desired
      *is_canonical = false;
    }
  }

  return value;
}

经验教训:我编写了一个直接验证函数.为了测试它我需要反向roman_int_to_string().随机字符串生成器迅速显示出许多令人惊讶的错误,如“CMC”和“CMCD”以及OP的“IIII”.最后,使用简单的string-to-int和int-to-string函数对然后进行字符串比较是最有弹性的.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读