[LeetCode]Integer to Roman
Posted 乘风有时
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[LeetCode]Integer to Roman相关的知识,希望对你有一定的参考价值。
int型数字转化为罗马数字的形式
思路:
由于只是1到3999,一共只有四位,分别求这四位的情况。
可以将每一位从1到9,int和罗马数字的一一对应的关系给出来,然后直接转换。
/***************************************************************** Given an integer, convert it to a roman numeral. Input is guaranteed to be within the range from 1 to 3999. *****************************************************************/ #include <stdio.h> char* intToRoman(int num) { int sd = num %10; int nm = num/10; int td = nm%10; nm /= 10; int hd = nm%10; nm /= 10; int thd = nm%10; int i,index = 0; char *rstr = (char *)malloc(16*sizeof(char)); memset(rstr,0,16*sizeof(char)); for(i = 0;i < thd;i++){ rstr[index++] = ‘M‘; } switch (hd)//百位 { case 3://注意没有break rstr[index++] = ‘C‘; case 2://注意没有break rstr[index++] = ‘C‘; case 1://注意没有break rstr[index++] = ‘C‘; break; case 4://注意没有break rstr[index++] = ‘C‘; case 5: rstr[index++] = ‘D‘; break; case 6: rstr[index++] = ‘D‘; rstr[index++] = ‘C‘; break; case 7: rstr[index++] = ‘D‘; rstr[index++] = ‘C‘; rstr[index++] = ‘C‘; break; case 8: rstr[index++] = ‘D‘; rstr[index++] = ‘C‘; rstr[index++] = ‘C‘; rstr[index++] = ‘C‘; break; case 9: rstr[index++] = ‘C‘; rstr[index++] = ‘M‘; break; default: break; } switch (td)//十位 { case 3: rstr[index++] = ‘X‘; case 2: rstr[index++] = ‘X‘; case 1: rstr[index++] = ‘X‘; break; case 4: rstr[index++] = ‘X‘; case 5: rstr[index++] = ‘L‘; break; case 6: rstr[index++] = ‘L‘; rstr[index++] = ‘X‘; break; case 7: rstr[index++] = ‘L‘; rstr[index++] = ‘X‘; rstr[index++] = ‘X‘; break; case 8: rstr[index++] = ‘L‘; rstr[index++] = ‘X‘; rstr[index++] = ‘X‘; rstr[index++] = ‘X‘; break; case 9: rstr[index++] = ‘X‘; rstr[index++] = ‘C‘; break; default: break; } switch (sd)//个位 { case 3: rstr[index++] = ‘I‘; case 2: rstr[index++] = ‘I‘; case 1: rstr[index++] = ‘I‘; break; case 4: rstr[index++] = ‘I‘; case 5: rstr[index++] = ‘V‘; break; case 6: rstr[index++] = ‘V‘; rstr[index++] = ‘I‘; break; case 7: rstr[index++] = ‘V‘; rstr[index++] = ‘I‘; rstr[index++] = ‘I‘; break; case 8: rstr[index++] = ‘V‘; rstr[index++] = ‘I‘; rstr[index++] = ‘I‘; rstr[index++] = ‘I‘; break; case 9: rstr[index++] = ‘I‘; rstr[index++] = ‘X‘; break; default: break; } return rstr; } int main(){ int n = 1684; char *s = intToRoman(n); printf("%s\n",s); free(s); return 0; }
上面思路代码冗余,不好。
思路2:
考虑每位对应数字是多少就先填多少个对应的罗马数字;
例如:46->XXXXIIIIII
然后多余的罗马数字在合。
合并的可能情况如下:
注意,每位都是一样的,用个位举例。
1.4个I合并为IV;IIII->IV
2.5个I合并为V;IIIII->V
3.2个V合并为X;IIIIIIIII->VIIII->VIV->IX
1 /***************************************************************** 2 Given an integer, convert it to a roman numeral. 3 Input is guaranteed to be within the range from 1 to 3999. 4 *****************************************************************/ 5 #include <stdio.h> 6 7 char* intToRoman(int num) { 8 char *rstr = (char *)malloc(32*sizeof(char)); 9 memset(rstr,0,32*sizeof(char)); 10 char lromans[] = {‘M‘,‘C‘,‘X‘,‘I‘}; 11 char uromans[] = {‘ ‘,‘D‘,‘L‘,‘V‘}; 12 int count = 0,lcount = 0,up = 0; 13 int i,k = 1000,index = 0,sum = 0; 14 while(num > 0){//在rstr数组中填充num的每位的数值对应数量的单位量字母(如num=9,则rstr="IIIIIIIII") 15 up = num/k; 16 num = num%k; 17 for(i = 0;i < up;i++){ 18 rstr[sum++] = lromans[count];//填充 19 } 20 count++; 21 k = k/10; 22 } 23 24 count = 0; 25 for(i = 0;i < sum;i++){//将每位的数值对应数量的单位量字母转换成正确的表示法 26 rstr[index] = rstr[i]; 27 if(rstr[i] == lromans[count]){ 28 lcount++; 29 }else{ 30 do{ 31 count++; 32 }while(rstr[i] != lromans[count]); 33 lcount = 1; 34 } 35 if(lcount == 4){//4个的情况:IIII->IV 36 index -= 2; 37 rstr[index] = uromans[count]; 38 }else if(lcount == 5){//5个的情况:IIIII->V 39 index -= 2; 40 rstr[index] = uromans[count]; 41 }else if(lcount == 9){//9个的情况:IIIIIIIII->VIIII->VIV->IX 42 index -= 4; 43 rstr[index++] = lromans[count]; 44 rstr[index] = lromans[count - 1]; 45 } 46 index++; 47 } 48 rstr[index] = ‘\0‘; 49 50 return rstr; 51 } 52 53 int main(){ 54 int n = 3999; 55 char *s = intToRoman(n); 56 printf("%s\n",s); 57 free(s); 58 return 0; 59 }
思路3:
贪心算法:尽量从大单位开始匹配,但是4和9要特殊考虑。
/***************************************************************** Given an integer, convert it to a roman numeral. Input is guaranteed to be within the range from 1 to 3999. *****************************************************************/ #include <stdio.h> //找钱的思想,对4和9特殊处理,贪心算法 char* intToRoman(int num) { int weights[] = {1000,500,100,50,10,5,1}; char romans[] = {‘M‘,‘D‘,‘C‘,‘L‘,‘X‘,‘V‘,‘I‘}; int nums[7] = {0}; char *rstr = (char *)malloc(16*sizeof(char)); memset(rstr,0,16*sizeof(char)); int i = 0,j = 0,index = 0; while(num > 0){ nums[i] = num/weights[i];//记录罗马数字每个单位对应的字母的个数 num = num%weights[i]; i++; } for(i = 0;i < 7;i++){ if(nums[i] == 4){//低位的单位有4个的时候可以转化的高位单位:IIII->IV nums[i] = 1; nums[i - 1]++; if(nums[i - 1] > 1){//两个以上的高位单位可以进位:VIV->IX rstr[index - 1] = romans[i]; rstr[index++] = romans[i - 2]; }else{ rstr[index++] = romans[i]; rstr[index++] = romans[i - 1]; } }else{ for(j = 0;j < nums[i];j++){ rstr[index++] = romans[i]; } } } return rstr; } int main(){ int n = 3999; char *s = intToRoman(n); printf("%s\n",s); free(s); return 0; }
以上是关于[LeetCode]Integer to Roman的主要内容,如果未能解决你的问题,请参考以下文章
leetcode 136:roman-to-integer&&leetcode 137:integer-to-roman
[Leetcode] String to Integer (atoi)