罗马和阿拉伯数字相互转换

之前做#1566 hihocoder 题目遇到了这个基本的问题,卡了一会儿,这里补齐这个问题。


参考:http://blog.sina.com.cn/s/blog_7025794a0101397g.html

http://blog.youkuaiyun.com/fightforyourdream/article/details/12934139


思路:

r2a:


基本字符:

  IVXLCDM

  相应的阿拉伯数字表示为:

  1510501005001000

  (1)相同的数字连写,所表示的数等于这些数字相加得到的数,如: = 3

  (2)小的数字在大的数字的右边,所表示的数等于这些数字相加得到的数, 如: = 8 = 12

  (3)小的数字,(限于X C)在大的数字的左边,所表示的数等于大数减小数得到的数,如:= 4= 9

  (4)正常使用时连写的数字重复不得超过三次。(表盘上的四点钟--“IIII”,例外。)

  (5)在一个数的上面画一条横线,表示这个数增值1000 倍。


其实要是想简单的话,我觉得建立一个很多的表是最简单的,不过这里先谈谈我用的方法:
不难发现,罗马数字是没有禁止,我建议大家可以先试着从I数到C,这样便对罗马数字有个了解,然后发现其为纯粹叠加而成的,所以用户输入一个数后,我们可以来遍历这个数,用sum来总计和,比较i和i+1,如果,i+1比i小的话,直接相加,如果i大于i+1的话,则将总和sum减去i这个地方数的两倍,同时加上i+1
就相当于后边的数比左边的数大,则用右边的数减左边的数。但因为之前已经加过一次了,所以减两次。
以上就是基本思路了,下面附上代码


a2r:

  1. // 阿拉伯数字转罗马数字:  
  2.     // 把所有小数字在前的组合也作为基本数字,再做一个对应的数值表就可以解决问题了。  
  3.     // I、V、X、   L、   C、     D、     M  
  4.     // 1.5、10、50、100、500、1000 

贴上JAVA代码:


import java.util.Scanner;
public class Main{
public static void main(String[] args){
Scanner in = new Scanner(System.in);
int n = in.nextInt();
for(int i=0;i < n;i++){
int ntmp = in.nextInt();
String tmp = a2r(ntmp);
System.out.println(tmp);
System.out.println(r2a(tmp));
}
}
//罗马数字转化为阿拉伯数字
public static int r2a(String roma){
int[] nums = new int[roma.length()];
for(int i=0;i < roma.length();i++){
switch(roma.charAt(i)){
case 'I':
nums[i] = 1;
break;
case 'V':
nums[i] = 5;
break;
case 'X':
nums[i] = 10;
break;
case 'L':
nums[i] = 50;
break;
case 'C':
nums[i] = 100;
break;
case 'D':
nums[i] = 500;
break;
case 'M':
nums[i] = 1000;
break;
}
}
int res = nums[0];
for(int i =0;i < nums.length-1;i++){
if(nums[i+1] <= nums[i]) res += nums[i+1];
else res = res + nums[i+1] - 2*nums[i];
}
return res;
}
//阿拉伯数字转化为罗马数字1~3999
public static String a2r(int num){
if(num < 1 || num > 3999){
return "NA";
}


int[] aArray = {1000,900,500,400,100,90,50,40,10,9,5,4,1};
String[] rArray = {"M","CM","D","CD","C","XC","L","XL","X","IX","V","IV","I"};
StringBuffer rNumber = new StringBuffer();
for(int i=0;i < aArray.length;i++){
while(num >= aArray[i]){
rNumber.append(rArray[i]);
num  -= aArray[i];
}
}
return rNumber.toString();
}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值