这个仍旧使用查表法,比较简单,直接上代码:
#include <stdio.h>
#include <stdlib.h>
#include "string.h"
#include "math.h"
char lut_1[10][8] = {"I","II","III","IV","V","VI","VII","VIII","IX"};
char lut_10[10][8] = {"X","XX","XXX","XL","L","LX","LXX","LXXX","XC"};
char lut_100[10][8] = {"C","CC","CCC","CD","D","DC","DCC","DCCC","CM"};
char lut_1000[10][8] = {"M","MM","MMM"};
//M D C L X V I
//7 6 5 4 3 2 1
#define LOG_FLAG 0
char str_lut[7] = {'I','V','X','L','C','D','M'};
//01 10 02 23 32 24 45 54 46
int wait_signal_lut[10][2]=
{
{1,2},
{2,1},
{1,3},
{3,4},
{4,3},
{3,5},
{5,6},
{6,5},
{5,7},
};
int lut_num_real_num[31][2]=
{
{1 ,1},
{11,2},
{111,3},
{12,4},
{2 ,5},
{21,6},
{211,7},
{2111,8},
{13,9},
{3,10},
{33,20},
{333,30},
{34,40},
{4,50},
{43,60},
{433,70},
{4333,80},
{35,90},
{5,100},
{55,200},
{555,300},
{56,400},
{6,500},
{65,600},
{655,700},
{6555,800},
{57,900},
{7,1000},
{77,2000},
{777,3000},
};
int look_up_every_char(char c)
{
int i=0;
for(i=0;i<7;i++)
{
if(str_lut[i] == c)
{
return i+1;
}
}
return 0;
}
int roma_separate(char *roma_buf,int *int_buf)
{
int lens = 0 , i = 0 , temp = 0;
lens = strlen(roma_buf);
for (i = 0; i < lens; i++)
{
temp = look_up_every_char(roma_buf[i]);
if(!temp)
{
printf("ERROR!\n");
return -1;
}
int_buf[i] = temp;
}
return lens;
}
int wait_for_dec_signal(int prev , int val)
{
int i = 0, j=0;
#if LOG_FLAG
printf("wait_for_dec_signal %d %d\n", prev,val);
#endif
for(i=0;i<9;i++)
{
if((prev == val)||((wait_signal_lut[i][0]==prev)&&(wait_signal_lut[i][1]==val)))
{
return 0; //no signal
}
}
return 1; //signal come
}
int combine_2_one(int *temp,int lens)
{
int i = 0,j = 0,sum = 0;
for(j = lens-1;j>=0;j--)
{
sum += temp[i] * pow(10,j) ;
i++;
}
return sum;
}
/*
第一位默认入栈,从第二位开始等待进位信号,如果没有,则接着入栈,有进位则将栈中的数保存至buf,指针赋值0,count++
*/
int roma_int_thansform(int *int_buf,int *int_buf_2th,int lens)
{
int i = 0 , j=0,k=0,counter = 0 ,temp[10] ;
for (i = 0; i < lens; i++)
{
if(i==0)//first bit
{
temp[0] = int_buf[0];
j++;
continue;
}
if(wait_for_dec_signal(int_buf[i-1],int_buf[i])) //end this bit
{
#if LOG_FLAG
printf("before trans temp\n");
for(k=0;k<j;k++)
{
printf(" %d\t", temp[k]);
}
printf("\n");
#endif
int_buf_2th[counter]= combine_2_one(temp,j);
#if LOG_FLAG
printf("sum %d\n", int_buf_2th[counter]);
#endif
j=0;
counter++;
temp[j] = int_buf[i];
j++;
}
else
{
temp[j] = int_buf[i];
j++;
}
if(i==lens - 1)
{
#if LOG_FLAG
printf("end before trans temp\n");
for(k=0;k<j;k++)
{
printf(" %d\t", temp[k]);
}
printf("\n");
#endif
int_buf_2th[counter]= combine_2_one(temp,j);
#if LOG_FLAG
printf("sum %d\n", int_buf_2th[counter]);
#endif
j=0;
counter++;
}
}
return counter;
}
int get_real_num(int *buf_num,int lens)
{
int i,j=0,k=0,temp[10];
#if LOG_FLAG
printf("get real orig\n");
for(k=0;k<lens;k++)
{
printf(" %d\t", buf_num[k]);
}
printf("\n");
#endif
for(i=0;i<lens;i++)
{
for(j=0;j<30;j++)
{
if(buf_num[i] == lut_num_real_num[j][0])
{
temp[i] = lut_num_real_num[j][1];
break;
}
}
}
#if LOG_FLAG
printf("get real temp\n");
for(k=0;k<lens;k++)
{
printf(" %d\t", temp[k]);
}
printf("\n");
#endif
i=0;
for(k=0;k<lens;k++)
{
i += temp[k];
}
return i;
}
int roma_2_int(char *roma_buf)
{
int int_buf_1th[20],int_buf_2th[4];
int i = 0 , j = 0 , lens = 0 ;
lens = roma_separate(roma_buf,int_buf_1th);
#if LOG_FLAG
printf("int_buf_1th\n");
for(i=0;i<lens;i++)
{
printf(" %d\t", int_buf_1th[i]);
}
printf("\n");
#endif
if(lens < 0)
{
return -1;
}
lens = roma_int_thansform(int_buf_1th,int_buf_2th,lens);
#if LOG_FLAG
printf("int_buf_2th\n");
for(i=0;i<lens;i++)
{
printf(" %d\t", int_buf_2th[i]);
}
printf("\n");
#endif
if(lens<5)
{
return get_real_num(int_buf_2th,lens);
}
else
{
return -1;
}
}
int main(int argc, char **argv)
{
char roma_input[20];
if(argc!=2){
printf("Usage: roma2int roma_number(0-3999)\n");
return -1;
}
strcpy(roma_input,argv[1]);
#if LOG_FLAG
puts(roma_input);
#endif
printf("%d\n", roma_2_int(roma_input));
return 1;
}