Microsoft Interview Question
Software Engineer in Tests#include <stdio.h>
#include <iostream>
const char *Number_AsRomanString( int iNumber )
{
struct RomanDigit_t
{
char *m_psString;
int m_iValue;
};
static const RomanDigit_t RomanDigits[]=
{
{"M", 1000},
{"CM", 900},
{"D", 500},
{"CD", 400},
{"C", 100},
{"XC", 90},
{"L", 50},
{"XL", 40},
{"X", 10},
{"IX", 9},
{"V", 5},
{"IV", 4},
{"I", 1},
};
// Strictly speaking, Roman digits can't display something
// such as 4999 without using overlaid bars and so forth,
// but for now this is a quick-and-dirty piece of code that'll
// just keep using M's...
//
static char sRomanString[20];
sRomanString[0] = '\0';
for (int i=0; iNumber && i<sizeof(RomanDigits)/
sizeof(RomanDigits[0]); i++)
{
while ( RomanDigits[i].m_iValue <= iNumber )
{
strcat( sRomanString, RomanDigits[i].m_psString );
iNumber -= RomanDigits[i].m_iValue;
}
}
return sRomanString;
}
int main(){
int num = 16;
const char *str = Number_AsRomanString(num);
printf("\nThe number is %s",str);
}
int findLen(int n)
{
int count = 0;
while(n)
{
switch(n%10)
{
case 1:
case 5:
count++; break; //I,V
case 2:
case 4:
case 6:
case 9;
count+=2; break; //II, IV, VI, IX
case 3:
count+=3; break; //III, VII
case 4:
count+=4; break; //VIII
}
n/=10;
}
return count;
}
void create(int num, int str)
{
char roman[4][] = {{'I', 'V'}, {'X', 'L'}, {'C', 'D'}, {'M'}};
char *ptr = str;
int rem;
int i = 0;
while(num)
{
switch(num%10)
{
case 3:
*ptr++ = roman[i][0];
case 2:
*ptr++ = roman[i][0];
case 1:
*ptr++ = roman[i][0]; break;
case 4:
*ptr++ = roman[i][0];
case 5:
*ptr++ = roman[i][1]; break;
case 6:
*ptr++ = roman[i][1]; *ptr++ = roman[i][0]; break;
case 7:
*ptr++ = roman[i][1]; *ptr++ = roman[i][0]; *ptr++ = roman[i][0];
break;
case 8:
*ptr++ = roman[i][1]; *ptr++ = roman[i][0]; *ptr++ = roman[i][0]; *ptr++ = roman[i][0]; break;
break;
case 9:
*ptr++ = roman[i][0]; *ptr++ = roman[i+1][0]; break;
}
n/=10;
}
strrev(str);
}
int main()
{
char *str = NULL;
len = findLen(num) + 1;
str = (char*)malloc(sizeof(char) * len);
create(num, str);
return 0;
}
int findLen(int n)
{
int count = 0;
while(n)
{
switch(n%10)
{
case 1:
case 5:
count++; break; //I,V
case 2:
case 4:
case 6:
case 9;
count+=2; break; //II, IV, VI, IX
case 3:
count+=3; break; //III, VII
case 8:////////////////////////////////////mistake corrected
count+=4; break; //VIII
}
n/=10;
}
return count;
}
void create(int num, int str)
{
char roman[4][] = {{'I', 'V'}, {'X', 'L'}, {'C', 'D'}, {'M'}};
char *ptr = str;
int rem;
int i = 0;
while(num)
{
switch(num%10)
{
case 3:
*ptr++ = roman[i][0];
case 2:
*ptr++ = roman[i][0];
case 1:
*ptr++ = roman[i][0]; break;
case 4:
*ptr++ = roman[i][0];
case 5:
*ptr++ = roman[i][1]; break;
case 6:
*ptr++ = roman[i][1]; *ptr++ = roman[i][0]; break;
case 7:
*ptr++ = roman[i][1]; *ptr++ = roman[i][0]; *ptr++ = roman[i][0];
break;
case 8:
*ptr++ = roman[i][1]; *ptr++ = roman[i][0]; *ptr++ = roman[i][0]; *ptr++ = roman[i][0]; break;
break;
case 9:
*ptr++ = roman[i][0]; *ptr++ = roman[i+1][0]; break;
}
n/=10;
}
strrev(str);
}
int main()
{
char *str = NULL;
len = findLen(num) + 1;
str = (char*)malloc(sizeof(char) * len);
create(num, str);
return 0;
}
string convert(int number){
string* numerals = new string[7];
numerals[0] = "I";
numerals[1] = "V";
numerals[2] = "X";
numerals[3] = "L";
numerals[4] = "C";
numerals[5] = "D";
numerals[6] = "M";
int order = 0;
int current = number;
string roman = "";
while( number != 0 ){
current = number % 10;
number = number / 10;
if(current <= 3){
for(int r=0; r<current; r++)
roman = numerals[2*order] + roman;
}
else if(current == 4)
roman = numerals[2*order]+numerals[2*order+1] + roman;
else if(current == 5)
roman = numerals[2*order+1] + roman;
else if(current <= 8){
for(int r=0; r<(current-5); r++)
roman = numerals[2*order] + roman;
roman = numerals[2*order+1] + roman;
}
else if(current == 9)
roman = numerals[2*order]+numerals[2*order+2] + roman;
order++;
if(order > 6)
throw(-1);
}
return roman;
}
//Use Recursion to solve it
char roman[] = "IVXLCDM";
void Int_To_Roman(int number,char *str)
{
int digit = number % 10;
int mod = digit%5;
if(mod<=3)
{
for(int i=0;i<mod;i++)
{
*str++ = roman[index];
}
if(digit/5>=1)
{
*str++ = roman[index+1];
}
}
else
{
if(digit/5>=1)
{
*str++ = roman[index+2];
}
else
{
*str++ = roman[index+1];
}
*str++ = roman[index];
}
*str = '\0';
index += 2;
if(number/10>0)
{
Int_To_Roman(number/10,str);
}
}
string to_roman(int n){
if(n>=4000)
return "TOO LARGE INPUT";
map<int,char> roman_numerals;
roman_numerals[1000]='M';roman_numerals[500]='D';roman_numerals[100]='C';roman_numerals[50]='L';roman_numerals[10]='X';roman_numerals[5]='V';roman_numerals[1]='I';
string result="";
for(int place=1000;place>0;place/=10){
int face=n/place;
if (face<=3)
for(int i=0;i<face;i++)
result.push_back(roman_numerals[place]);
else if(face==4){
result.push_back(roman_numerals[place]);
result.push_back(roman_numerals[place*5]);
}
else if (face==5)
result.push_back(roman_numerals[place*5]);
else if (face<=8){
result.push_back(roman_numerals[place*5]);
for(int i=6;i<=face;i++)
result.push_back(roman_numerals[place]);
}
else if(face==9){
result.push_back(roman_numerals[place]);
result.push_back(roman_numerals[place*10]);
}
n%=place;
}
return result;
}
int map(char inp)
{
switch (inp)
{
case 'i':
case 'I':
return 1;
case 'v':
case 'V':
return 5;
case 'x':
case 'X':
return 10;
case 'l':
case 'L':
return 50;
case 'c':
case 'C':
return 100;
case 'd':
case 'D':
return 500;
default:
return 0;
}
}
int main()
{
char str[16];
int res = 0,prev = 501,curr = 0;
cout <<"Enter the input ROMAN string = ";
cin >> str;
int len = strlen(str);
for(int i=0;i<len;i++)
{
curr = map(str[i]);
if(curr<=prev)
res += curr;
else
{
res += curr;
res -= 2*prev;
}
prev = curr; //Re-initialize the previous
}
cout <<"The decimal equivalent of input Roman "<<str<<" = "<<res;
return 0;
}
Here is my solution, although I don't like it very much...
- September 25, 2008