[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;
}
时间: 2024-10-18 03:56:06

[LeetCode]Integer to Roman的相关文章

LeetCode: Integer to Roman 解题报告

Integer to Roman Given an integer, convert it to a roman numeral. Input is guaranteed to be within the range from 1 to 3999. SOLUTION 1: 从大到小的贪心写法.从大到小匹配,尽量多地匹配当前的字符. 罗马数字对照表: http://literacy.kent.edu/Minigrants/Cinci/romanchart.htm 1 package Algorit

[leetcode] Integer to Roman @ Python

题目: https://oj.leetcode.com/problems/integer-to-roman/ Given an integer, convert it to a roman numeral. Input is guaranteed to be within the range from 1 to 3999. 思路:不是很清楚. 代码: class Solution: # @return a string def intToRoman(self, num): ints = [100

LeetCode——Integer to Roman

Description: Given an integer, convert it to a roman numeral. Input is guaranteed to be within the range from 1 to 3999. noting to say. public class Solution { public String intToRoman(int number) { int[] values = {1000, 900, 500, 400, 100, 90, 50, 4

[LeetCode] Integer to Roman 整数转化成罗马数字

Given an integer, convert it to a roman numeral. Input is guaranteed to be within the range from 1 to 3999. 之前那篇文章写的是罗马数字转化成整数(http://www.cnblogs.com/grandyang/p/4120857.html), 这次变成了整数转化成罗马数字,基本算法还是一样.由于题目中限定了输入数字的范围(1 - 3999), 使得题目变得简单了不少. 基本字符 I V

LeetCode:Integer to Roman

1.题目名称 Integer to Roman (阿拉伯数字到罗马数字的转换) 2.题目地址 https://leetcode.com/problems/integer-to-roman 3.题目内容 英文:Given an integer, convert it to a roman numeral. Input is guaranteed to be within the range from 1 to 3999. 中文:给出一个整数,将它转换成罗马数字.输入在1-3999之间. 4.题目分

LeetCode之Integer to Roman, Roman to Integer

罗马数字以前只接触过I到VIII,第一次听说罗马数字也可以表示大于8的数字.阿拉伯数字和罗马数字之间的转换最重的是了解罗马数字的规则.Wiki了一把,又参考了其它的文档,总结如下: 罗马数字规则: 1, 罗马数字共有7个,即I(1).V(5).X(10).L(50).C(100).D(500)和M(1000). 罗马数字中没有"0". 2, 重复次数:一个罗马数字最多重复3次. 3, 右加左减: 在较大的罗马数字的右边记上较小的罗马数字,表示大数字加小数字. 在较大的罗马数字的左边记上

LeetCode 012 Integer to Roman

[题目] Given an integer, convert it to a roman numeral. Input is guaranteed to be within the range from 1 to 3999. [题意] 给定一个整数,将其表示成罗马数字 [思路] 罗马数字中只使用如下七个基值字母:M,D,C,L,X,V,I,分别用来表示1000.500.100.50.10.5.1. 罗马数组数规则: 基本数字Ⅰ.X .C 中的任何一个,自身连用构成数目,或者放在大数的右边连用构成

【LeetCode】Integer to Roman

Given an integer, convert it to a roman numeral. Input is guaranteed to be within the range from 1 to 3999. public class Solution { public String intToRoman(int num) { StringBuilder sb = new StringBuilder(); if(num==0) return sb.toString(); while(num

[LeetCode][Python]Integer to Roman

# -*- coding: utf8 -*-'''__author__ = '[email protected]'https://oj.leetcode.com/problems/integer-to-roman/Integer to Roman Given an integer, convert it to a roman numeral. Input is guaranteed to be within the range from 1 to 3999.===Comments by Daba