• [LeetCode]Integer to Roman


    题目: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
    ",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] = '';
    49 
    50     return rstr;
    51 }
    52 
    53 int main(){
    54     int n = 3999;
    55     char *s = intToRoman(n);
    56     printf("%s
    ",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
    ",s);
        free(s);
        return 0;
    }
  • 相关阅读:
    win7承载网络状态不可用,无线网卡驱动更新后也仍然不可用。
    oracle中读写blob字段的问题
    The import javax.servlet cannot be resolved
    关于BLOB数据类型插入ORACLE数据库的操作
    Android Spinner自动弹出列表,设置title
    java.lang.LinkageError: loader constraint violation: when resolving interface... 异常解决
    Java获取网络时间
    android 改变CheckBox和后面文字的间距
    大白话系列之C#委托与事件讲解(序言)
    大白话系列之C#委托与事件讲解(一)
  • 原文地址:https://www.cnblogs.com/yeqluofwupheng/p/6663752.html
Copyright © 2020-2023  润新知