十年网站开发经验 + 多家企业客户 + 靠谱的建站团队
量身定制 + 运营维护+专业推广+无忧售后,网站问题一站解决
已经经过验证,可以实现,但输入数字不能有空格
网站建设哪家好,找成都创新互联公司!专注于网页设计、网站建设、微信开发、小程序定制开发、集团企业网站建设等服务项目。为回馈新老客户创新互联还提供了梁平免费建站欢迎大家使用!
public class Roman {
private final int num; // 罗马数字转换后的阿拉伯数字(十进制)
public Roman(String roman) throws RuntimeException {
if (roman.length() == 0) // 输入为空
{
throw new RuntimeException("不能输入空字符");
}
roman = roman.toUpperCase(); // 所有罗马数字都转换为大写
int i = 0; // 记录罗马数字每个字符的位置
int arabic = 0; // 转换后的阿拉伯数字
while (i roman.length()) {
char letter = roman.charAt(i); // 罗马数字当前位置的字符
int number = letterToNumber(letter); // 字符转化为阿拉伯数字
if (number 0) {
throw new RuntimeException("罗马数字中不包含" + letter);
}
i++; // 移动到字符串的下一个位置
if (i == roman.length()) // 罗马数字已处理完毕
{
arabic += number;
} else {
char nextLetter = roman.charAt(i);
int nextNumber = letterToNumber(nextLetter);
if (nextNumber number) // 后边的字符比前边的大
{
int result = nextNumber - number;
if (result == 4 || result == 9 || result == 40 || result == 90 || result == 400 || result == 900) {
arabic += result;
i++;
if (i == roman.length()) // 罗马数字已处理完毕
{
break;
} else {
char afterNextLetter = roman.charAt(i);
int afterNextNumber = letterToNumber(afterNextLetter);
if (afterNextNumber result) {
throw new RuntimeException("不合法的罗马数字" + letter + nextLetter + afterNextLetter);
}
}
} else {
throw new RuntimeException("不合法的罗马数字" + letter + nextLetter);
}
} else {
if ((number == 5 || number == 50 || number == 500) number == nextNumber) // V、L、D用于大数右边(相加),使用超过1次。
{
throw new RuntimeException("不合法的罗马数字" + letter + nextLetter);
}
if (number == nextNumber) {
i++; // 还要再看下一个字符
if (i == roman.length()) // 罗马数字已处理完毕
{
arabic += number + nextNumber;
break;
}
char afterNextLetter = roman.charAt(i);
int afterNextNumber = letterToNumber(afterNextLetter);
if (afterNextNumber nextNumber) // I、X、C在在大数左边(即相减时)使用超过2个
{
throw new RuntimeException("不合法的罗马数字" + letter + nextLetter + afterNextLetter);
} else if (afterNextNumber == nextNumber) // 出现3个字符都相同的情况,如III
{
i++; // 还要再看下一个字符,可能会出现IIII这种情况(不允许的,应抛出异常)
if (i == roman.length()) // 罗马数字已处理完毕
{
arabic += number + nextNumber + afterNextNumber;
break;
}
char afterNextNextLetter = roman.charAt(i);
int afterNextNextNumber = letterToNumber(afterNextNextLetter);
if (afterNextNextNumber == afterNextNumber) // 出现IIII这种情况
{
throw new RuntimeException("不合法的罗马数字" + letter + nextLetter + afterNextLetter + afterNextNextLetter);
} else {
arabic += number;
i = i - 2; // 回退2个字符(因为考虑了4个字符)
}
} else {
arabic += number + nextNumber;
}
} else {
arabic += number;
}
}
}
}
if (arabic 3999) {
throw new RuntimeException("输入的数字不能超过3999");
}
num = arabic;
}
/**
* 罗马字符转换为阿拉伯数字
*
* @param letter
* 罗马字符
* @return 正常罗马字符,返回阿拉伯数字;否则,返回-1
*/
private int letterToNumber(char letter) {
switch (letter) {
case 'I':
return 1;
case 'V':
return 5;
case 'X':
return 10;
case 'L':
return 50;
case 'C':
return 100;
case 'D':
return 500;
case 'M':
return 1000;
default:
return -1;
}
}
public int getNum() {
return num;
}
public static void main(String[] args) {
while (true) {
System.out.println();
System.out.print("请输入罗马数字(按Q键退出):");
Scanner cin = new Scanner(System.in);
String romanStr = cin.nextLine();
if (romanStr.equals("q") || romanStr.equals("Q")) // 退出循环
{
break;
}
Roman roman = null;
try {
roman = new Roman(romanStr);
System.out.println(romanStr+" is the year:" + roman.getNum());
} catch (RuntimeException e) {
System.out.println(e);
}
}
}
}
Java中有各国的文字段,正则表达式这玩意专门匹配各国语言的~
比如匹配汉字:
Pattern p=Pattern.Compile("[\u4e00-\u9fa5]");而匹配罗马数字的是:
^[1-9]\d*$
//匹配正整数
^-[1-9]\d*$
//匹配负整数
^-?[1-9]\d*$
//匹配整数
^[1-9]\d*|0$
//匹配非负整数(正整数 + 0)
^-[1-9]\d*|0$
//匹配非正整数(负整数 + 0)
^[1-9]\d*\.\d*|0\.\d*[1-9]\d*$
//匹配正浮点数
^-([1-9]\d*\.\d*|0\.\d*[1-9]\d*)$
//匹配负浮点数
^-?([1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0)$
//匹配浮点数
^[1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0$
//匹配非负浮点数(正浮点数 + 0)
^(-([1-9]\d*\.\d*|0\.\d*[1-9]\d*))|0?\.0+|0$
//匹配非正浮点数(负浮点数 + 0)
public class Test {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int s = Integer.parseInt(sc.next());
System.out.println(toRome(s));
sc.close();
}
// 阿拉伯数字转罗马数字:
// 把所有小数字在前的组合也作为基本数字,再做一个对应的数值表就可以解决问题了。
// I、V、X、 L、 C、 D、 M
// 1.5、10、50、100、500、1000
private static String toRome(int aNumber){
if(aNumber 1 || aNumber 3999){
return "-1";
}
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"};
String rNumber = "";
for(int i=0; iaArray.length; i++){
while(aNumber = aArray[i]){
rNumber += rArray[i];
aNumber -= aArray[i];
}
}
return rNumber;
}
}
一直对古罗马数字感兴趣,借这个题学习了一下,得出
罗马数转阿拉伯数,算法伪代码:
设输入"MCMLIV"为t,设输出数为sum=0,设最大字符数值为m=0
从右往左遍历t中的字符,比较方便
当遍历字符代表的值c大于等于m时,m=c且sum+=c(对应3III等的情况);否则sum减去该值c(对应4IV,9IX等情况)
比如依次VILMCM依次对应+5, -1, +50, +1000, -100, +1000, 得1954
遍历完输出阿拉伯数sum.
==============
阿拉伯数转罗马数,算法:
视罗马数为十进制,每数位有1,2,3,4,5,6,7,8,9共9种符号(无0)
设全进制单位为a(比如I1, X10, C100, M1000),设半进制单位为b(比如V5, L50, D500),
分别对应固定形式表示法:
1 a; 2 aa; 3 aaa; 4 ab; 5 b; 6 ba; 7 baa; 8 baaa; 9 a(a2)
对于数字2016逐数位分解
2千 得 MM
0百 得 无
1十 得X
6得 VI
合并得MMXVI即2016
原理通了代码实现就非常简单了
public class test {
public static void main(String args[]) {
int ss = Integer.parseInt(args[0]);
if(ss==0)
System.out.println("零");
else if (ss==1)
System.out.println("壹");
else if (ss==2)
System.out.println("贰");
else if (ss==3)
System.out.println("叁");
else if (ss==4)
System.out.println("肆");
else if (ss==5)
System.out.println("伍");
else if (ss==6)
System.out.println("陆");
else if (ss==7)
System.out.println("柒");
else if (ss==8)
System.out.println("捌");
else if (ss==9)
System.out.println("玖");
else
System.out.println("");
}
}