方法一、贪心算法

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char * intToRoman(int num) {
  struct intToRoman
  {
    int num;
    char *str;
  } list[13] = {
      {1000, "M"},
      {900, "CM"},
      {500, "D"},
      {400, "CD"},
      {100, "C"},
      {90, "XC"},
      {50, "L"},
      {40, "XL"},
      {10, "X"},
      {9, "IX"},
      {5, "V"},
      {4, "IV"},
      {1, "I"},
  };
  int count[13] = {0};
  char *str = (char*)malloc(17 * sizeof(char));
  memset(str, '\0', 17);
  for (int i = 0; i < 13; i++) {
      int count = num / list[i].num;
      while (count-- > 0)
      {
        strcat(str, list[i].str);
      }
      num %= list[i].num;
  }
  strcat(str, '\0');
  return str;
}

int main(void) {
  int num = 3999;
  printf("%s\n", intToRoman(num));
}

或者

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

char * intToRoman(int num) {
  int numArr[] = {1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1};
  char *roman[] = {"M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"};
  int count[13] = {0};
  char *str = (char*)malloc(17 * sizeof(char));
  memset(str, '\0', 17);
  for (int i = 0; i < 13; i++) {
      int count = num / numArr[i];
      while (count-- > 0)
      {
        strcat(str, roman[i]);
      }
      num %= numArr[i];
  }
  return str;
}

int main(void) {
  int num = 3999;
  printf("%s\n", intToRoman(num));
}

image.png

时间复杂度:O(1),因为循环次数都是有常数上限的,因此时间复杂度为常数量级
空间复杂度:O(1),使用的内存量也不会随着输入的整数大小变化而变化,因此也是常量级别的

方法二、将千位,百位,十位与个位可能出现的罗马数字硬编码,然后对整数做整除和求余,取得千位,百位,十位,个位的整数数字,然后去找相应的罗马数字,将其拼接起来即可。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *intToRoman(int num)
{
  char *thousandsRoman[] = {"", "M", "MM", "MMM"};
  char *hundredsRoman[] = {"", "C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM"};
  char *tensRoman[] = {"", "X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC"};
  char *onesRoman[] = {"", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"};
  char *str = (char *)malloc(16 * sizeof(char));
  memset(str, '\0', 16);
  int tods = num / 1000;
  int huds = (num % 1000) / 100;
  int tens = (num % 100) / 10;
  int ones = num % 10;
  strcat(str, thousandsRoman[tods]);
  strcat(str, hundredsRoman[huds]);
  strcat(str, tensRoman[tens]);
  strcat(str, onesRoman[ones]);
  return str;
}

int main(void)
{
  int num = 3999;
  printf("%s\n", intToRoman(num));
}

image.png

时间复杂度为:O(1),以上代码都是常量级别的操作,就算是字符串拼接也是简短的字符串拼接,耗时也在常量级别,因此是O(1)
空间复杂度为:O(1),空间复杂度一目了然,都在常量级别,也没有随着输入数字大小的变化而变化,因此也是O(1)

方法一与方法二比较的话,就是如果你要扩展罗马数字,则随着输入数字规模的增大,方法二需要硬编码的数字量会越来越多,而方法一需要添加的特殊的罗马数字则较少,修改起来比较方便。


阿料
1 声望4 粉丝

一个平凡的coder