2018/12/15

a013: 羅馬數字

a013: 羅馬數字


#include
#include
#include
#include

// 阿拉伯數字 --> 羅馬數字
int a2r(unsigned int val, char* res, size_t sz) {
  char *twas[] = {"", "c", "cc", "ccc", "cd", "d", "dc", "dcc", "dccc", "cm"};
  char *wans[] = {"", "x", "xx", "xxx", "xl", "l", "lx", "lxx", "lxxx", "xc"};
  char *thos[] = {"", "M", "MM", "MMM", "Mv", "v", "vM", "vMM", "vMMM", "Mx"};
  char *huns[] = {"", "C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM"};
  char *tens[] = {"", "X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC"};
  char *ones[] = {"", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"};
  int   size[] = { 0,  1,    2,     3,    2,   1,    2,     3,      4,    2};

  if (val < 0) { strcpy(res, "UNKNOWN"); return 1; }
  if (val == 0) { strcpy(res, "ZERO"); return 1; }

  while (val >= 1000000) {
    if (sz-- < 1) return 0;
    *res++ = 'm';
    val -= 1000000;
  }

  // Add each of the correct elements, adjusting as we go.

  if (sz < size[val/100000]) return 0;
  sz -= size[val/100000];
  strcpy (res, twas[val/100000]); res += size[val/100000]; val = val % 100000;

  if (sz < size[val/10000]) return 0;
  sz -= size[val/10000];
  strcpy (res, wans[val/10000]); res += size[val/10000]; val = val % 10000;

  if (sz < size[val/1000]) return 0;
  sz -= size[val/1000];
  strcpy (res, thos[val/1000]); res += size[val/1000]; val = val % 1000;

  if (sz < size[val/100]) return 0;
  sz -= size[val/100];
  strcpy (res, huns[val/100]);  res += size[val/100];  val = val % 100;

  if (sz < size[val/10]) return 0;
  sz -= size[val/10];
  strcpy (res, tens[val/10]);   res += size[val/10];   val = val % 10;

  if (sz < size[val]) return 0;
  sz -= size[val];
  strcpy (res, ones[val]);      res += size[val];

  // Finish string off.
  if (sz < 1) return 0;
  *res = '\0';
  return 1;
}

int r2a_in_char(char r) {
  switch (r) {
    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;
    case 'v': return 5000;
    case 'x': return 10000;
    case 'l': return 50000;
    case 'c': return 100000;
    case 'd': return 500000;
    case 'm': return 1000000;
    default: return 0;
  }
}

int r2a(char *str) {
  int res = 0;
  int max = strlen(str);
  for (int i=0; i    // 從羅馬數字轉成阿拉伯數字
    int s1 = r2a_in_char(str[i]);
 
    if (i+1 < max) {
      // 往後看,將下一個字元從羅馬數字轉成阿拉伯數字
      int s2 = r2a_in_char(str[i+1]);
 
      // 比對前後文....
      if (s1 >= s2) {  // 前面大於等於後面,表示加法,直接加起來
        res = res + s1;
      } else {  // 前面小於後面,表示減法: 加後面減前面
        res = res + s2 - s1;
        i++; // i++ 之後,跳過下一符號
      }
    } else { // 結束.....
      res = res + s1;
      i++;
    }
  }
  return res;
}

int main ()
{
  int n, a, b;
  char r1[100], r2[100];
  char res[100];

  while (scanf ("%s %s", r1, r2) == 2) {
    a = r2a(r1);
    b = r2a(r2);
    a2r(a>b?a-b:b-a, res, 100);
    printf ("%s\n", res);
  }
  return 0;
}

0 意見: