[12] Integer to Roman
© Jarvus Chen / www.jarvus.net
Description
Given an integer, convert it to a roman numeral.
Input is guaranteed to be within the range from 1 to 3999.
Required knowledge
Roman numerals conversion table
- I = 1
- V = 5
- X = 10
- L = 50
- C = 100
- D = 500
- M = 1000
Number | Roman | Number | Roman | Number | Roman | Number | Roman |
---|---|---|---|---|---|---|---|
1 | I | 10 | X | 100 | C | 1000 | M |
2 | II | 20 | XX | 200 | CC | 2000 | MM |
3 | III | 30 | XXX | 300 | CCC | 3000 | MMM |
4 | IV | 40 | XL | 400 | CD | ||
5 | V | 50 | L | 500 | D | ||
6 | VI | 60 | LX | 600 | DC | ||
7 | VII | 70 | LXX | 700 | DCC | ||
8 | VIII | 80 | LXXX | 800 | DCCC | ||
9 | IX | 90 | XC | 900 | CM |
String array
https://stackoverflow.com/questions/1088622/how-do-i-create-an-array-of-strings-in-c
There are three way you can declare a string array. The second one is the most recommended.
char a1[][14] = { "blah", "hmm" };
char* a2[] = { "blah", "hmm" };
char (*a3[])[] = { &"blah", &"hmm" };
// prints blah
printf(a1[0]);
printf(a2[0]);
printf(*a3[0]);
// change its content
strcpy(a1[0], "hmm");
strcpy(a1[1], "blah");
a2[0] = "hmm";
a2[1] = "blah";
a3[0] = &"hmm";
a3[1] = &"blah";
String connect
https://openhome.cc/Gossip/CGossip/StringLengthCopyCat.html
You can select how many char you want to combine with another one.
char str1[80] = "xyz";
char str2[] = "abc";
strcat(str1, str2);
// str1 is xyzabc
strncat(str1, str2, 2);
// str1 is xyzabcab
My solution
Part 1 identify how many digit in the input number and reverse it. Because of strcat
method, I have to process roman transformation from the last digit.
Part 2 according to remain values, choose which data can it retrieve.
char* intToRoman(int num) {
char* data1[] = {"I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"};
char* data2[] = {"X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC"};
char* data3[] = {"C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM"};
char* data4[] = {"M", "MM", "MMM"};
char* ans = malloc(sizeof(char)*15);
// Part 1
// inverse int
int temp = 0;
int count = 0;
while( num > 0){
temp = temp * 10 + num % 10;
num /= 10;
count++;
};
// Part 2
// process from the last digit
while ( temp > 0){
int digit = temp%10;
if ( count == 4 && digit > 0){
strcat(ans, data4[digit-1]);
}else if( count == 3 && digit > 0){
strcat(ans, data3[digit-1]);
}else if( count == 2 && digit > 0){
strcat(ans, data2[digit-1]);
}else if( count == 1 && digit > 0){
strcat(ans, data1[digit-1]);
}
temp = temp/10;
count--;
}
return ans;
}
Others solution
https://discuss.leetcode.com/topic/11001/my-c-solution-in-19ms
Not really good but this is kind of another thinking logic to finish the problem.
char *link(char *s1,char *s2)
{
int len1=strlen(s1);
int len2=strlen(s2);
for(int i=len1;i<len1+len2;i++)
s1[i] = s2[i-len1];
return s1;
}
char *integerToRoman(int x)
{
char *arr[13]={"M","CM","D","CD","C","XC","L","XL","X","IX","V","IV","I"};
int value[13]= {1000,900,500,400,100,90,50,40,10,9,5,4,1};
char roman=(char)malloc(sizeof(char)*100);
memset(roman,0,100);
for(int i=0;x!=0;i++){
while(x>=value[i]){
x-=value[i];
roman = link(roman,arr[i]);
}
}
return roman;
}