码迷,mamicode.com
首页 > 其他好文 > 详细

leetcode--Integer to Roman

时间:2015-05-10 09:57:55      阅读:136      评论:0      收藏:0      [点我收藏+]

标签:

题目描述:

Given an integer, convert it to a roman numeral.

Input is guaranteed to be within the range from 1 to 3999.

题目解析:

将一个整形数的罗马形式表示出来。罗马数字和整形数转换规则参考http://blog.csdn.net/sinat_24520925/article/details/44560375。 
罗马数字是最古老的数字表示方式,比阿拉伯数组早2000多年,起源于罗马 
罗马数字有如下符号: 
基本字符 I V X L C D M
对应阿拉伯数字 1 5 10 50 100 500 1000
计数规则: 相同的数字连写,所表示的数等于这些数字相加得到的数,例如:III = 3小的数字在大的数字右边,所表示的数等于这些数字相加得到的数,例如:VIII = 8小的数字,限于(I、X和C)在大的数字左边,所表示的数等于大数减去小数所得的数,例如:IV = 4正常使用时,连续的数字重复不得超过三次,在一个数的上面画横线,表示这个数扩大1000倍(本题只考虑3999以内的数,所以用不到这条规则) 
其次,罗马数字转阿拉伯数字规则(仅限于3999以内): 
下面给出三种算法。

方法一、

首先给出数字对应的罗马字符形式。根据计数规则,我们可以给出30个数字对应的字符串,分别为9(1~9)、9(10~90)、9(100~900)、3(1000~3000)之后将给定的整形数n由高位向低位依次输出其对应的罗马字符。具体代码如下:
string intToRoman(int num) 
{
	string M[]={"","M","MM","MMM"};
	string C[]={"","C","CC","CCC","CD","D","DC","DCC","DCCC","CM"};
	string X[]={"","X","XX","XXX","XL","L","LX","LXX","LXXX","XC"};
	string I[]={"","I","II","III","IV","V","VI","VII","VIII","IX"};
	return M[num/1000]+C[(num%1000)/100]+X[(num%100)/10]+I[(num%10)];
}

方法二


因为连续的数字重复不得超过三次,所以当大于三次的时候就有特殊的形式。我们不用列出所有30中组合,只要其中特殊的形式(13种),其他的各种形式可由这13种组合得到。将给定整形数最大的对应的罗马字符输出,并减去此罗马字符对应的整形数。这样一直判断,直到给定整形数的个位数也都输出完。代码如下:
string intToRoman2(int num) {
	if (num>=1000) return "M"+intToRoman(num-1000);
	if (num>=900) return "CM"+intToRoman(num-900);
	if (num>=500) return "D"+intToRoman(num-500);
	if (num>=400) return "CD"+intToRoman(num-400);
	if (num>=100) return "C"+intToRoman(num-100);
	if (num>=90) return "XC"+intToRoman(num-90);
	if (num>=50) return "L"+intToRoman(num-50);
	if (num>=40) return "XL"+intToRoman(num-40);
	if (num>=10) return "X"+intToRoman(num-10);
	if (num>=9) return "IX"+intToRoman(num-9);
	if (num>=5) return "V"+intToRoman(num-5);
	if (num>=4) return "IV"+intToRoman(num-4);
	if (num>=1) return "I"+intToRoman(num-1);
	return "";
}

方法三

思想同方法二,不过将13个罗马字符和其对应的整形对应存储在数组中,代码如下;
string intToRoman(int num) {
       
	for (int i=12;i>=0;i--)
	{
		if (inte[i]<=num)
		{
			return roman[i]+intToRoman(num-inte[i]);
		}
	}
	return "";
    }
   private:
    int  inte[13]={1,4,5,9,10,40,50,90,100,400,500,900,1000};
	string roman[13]={"I","IV","V","IX","X","XL","L","XC","C","CD","D","CM","M"};

第一种方法虽然简单直接,但是空间复杂度大,并且在leetcode中运行时间长为96ms。第二种方法降低了空间复杂度,运行时间为54ms。第三种方法在方法二的思想上进一步减小了空间复杂度,leetcode中运行时间为51ms.
完整代码如下,其中我们使用http://blog.csdn.net/sinat_24520925/article/details/44560375中的roman to integer函数来判断roman to integer三种算法的正确性。
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int romanToInt(string s)  ;
string intToRoman(int num) ;
string intToRoman1(int num);
string intToRoman2(int num);
void main()
{
	int n=2549;
	cout<<n<<endl;
	string res=intToRoman(n) ;
	cout<<res<<endl;
	cout<<romanToInt(res)<<endl; 

	string res1=intToRoman1(n) ;
	cout<<res1<<endl;
	cout<<romanToInt(res1)<<endl; 

	string res2=intToRoman2(n) ;
	cout<<res2<<endl;
	cout<<romanToInt(res2); 
}
string intToRoman(int num) 
{
	string M[]={"","M","MM","MMM"};
	string C[]={"","C","CC","CCC","CD","D","DC","DCC","DCCC","CM"};
	string X[]={"","X","XX","XXX","XL","L","LX","LXX","LXXX","XC"};
	string I[]={"","I","II","III","IV","V","VI","VII","VIII","IX"};
	return M[num/1000]+C[(num%1000)/100]+X[(num%100)/10]+I[(num%10)];
}
int  inte[13]={1,4,5,9,10,40,50,90,100,400,500,900,1000};
string roman[13]={"I","IV","V","IX","X","XL","L","XC","C","CD","D","CM","M"};
string intToRoman1(int num) {
	for (int i=12;i>=0;i--)
	{
		if (inte[i]<=num)
		{
			return roman[i]+intToRoman(num-inte[i]);
		}
	}
	return "";
}
string intToRoman2(int num) {
	if (num>=1000) return "M"+intToRoman(num-1000);
	if (num>=900) return "CM"+intToRoman(num-900);
	if (num>=500) return "D"+intToRoman(num-500);
	if (num>=400) return "CD"+intToRoman(num-400);
	if (num>=100) return "C"+intToRoman(num-100);
	if (num>=90) return "XC"+intToRoman(num-90);
	if (num>=50) return "L"+intToRoman(num-50);
	if (num>=40) return "XL"+intToRoman(num-40);
	if (num>=10) return "X"+intToRoman(num-10);
	if (num>=9) return "IX"+intToRoman(num-9);
	if (num>=5) return "V"+intToRoman(num-5);
	if (num>=4) return "IV"+intToRoman(num-4);
	if (num>=1) return "I"+intToRoman(num-1);
	return "";
}
int romanToInt(string s)  
{  
    /*roman['I']=1;   
    roman['V']=5;   
    roman['X']=10;   
    roman['L']=50;   
    roman['C']=100;   
    roman['D']=500;   
    roman['M']=1000;  */  
    char *p=new char[s.size()];    
    strcpy(p,s.c_str());//将string型转为char型数组  
    vector<int> array;  
    array.resize(s.size());  
    int n=0;  
    for (int i=0;i<s.size();i++)  
    {  
        switch (p[i])  
        {  
        case 'I':array[i]=1;break;  
        case 'V':array[i]=5;break;  
        case 'X':array[i]=10;break;  
        case 'L':array[i]=50;break;  
        case 'C':array[i]=100;break;  
        case 'D':array[i]=500;break;  
        case 'M':array[i]=1000;break;  
        default:cout<<"error\n";  
        }  
        if (i==0)  
        {  
            n+=array[i];  
        }  
        else  
        {  
            if (array[i]<=array[i-1])  
            {  
                n+=array[i];  
            }  
            else  
            {  
                n+=array[i]-2*array[i-1];  
            }  
        }  
    }  
    return n;  
}  


技术分享


leetcode--Integer to Roman

标签:

原文地址:http://blog.csdn.net/sinat_24520925/article/details/45602831

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!