我正在研究针对一般编程实践的UVa问题,因为我希望在编程方面做得更好。但是我遇到了这个问题 - 罗马数字。在这个问题中,目标是采用罗马数字或阿拉伯数字形式的输入,然后我必须从一个转换为另一个。根据在线评判,我觉得我的代码应该没有足够快的处理速度,它的处理速度不够快。我需要帮助找出如何优化我的代码,以便它运行得更快,而不是接收TLE。
以下是我的计划,任何有关解释我接收超时限制的原因的帮助将不胜感激。提前谢谢。
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
class Main {
private static String order = "IVXLCDM";
private static String order2 = "IXCM"; // These chars are the result of 10^n (n depending on index in the string)
private static String order3 = "VLD"; // These chars are products of 5*10^n (n depending on index in the string)
public static void main(String[] args) {
InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader br = new BufferedReader(isr);
String ans = "";
while (true) {
String read = "";
int aNum = 0;
String rNum = "";
try {
read = br.readLine();
if (read=="")
break;
} catch (IOException e) {
if (read=="")
break;
e.printStackTrace();
}
try {
aNum = Integer.parseInt(read);
// System.out.println(aNum);
int thousands = aNum/1000;
// System.out.println(thousands);
int hundreds = aNum/100;
hundreds = hundreds%10;
// System.out.println(hundreds);
int tens = aNum%100;
tens = tens/10;
// System.out.println(tens);
int ones = aNum%10;
// System.out.println(ones);
rNum+= a2R(thousands,"M");
rNum+= a2R(hundreds,"C");
rNum+= a2R(tens,"X");
rNum+= a2R(ones,"I");
// System.out.println(rNum);
ans+=(rNum+"\n");
// System.out.print(ans);
} catch (NumberFormatException c) {
rNum = read;
if (rNum.equals(""))
break;
aNum = r2A(rNum);
// System.out.println(aNum);
ans+=(aNum+"\n");
// System.out.print(ans);
}
}
System.out.print(ans);
}
private static int r2A(String rNum) {
int aNum = 0;
for (int i = order.length()-1; i >= 0; i--) {
char curChar = order.charAt(i);
while (rNum.indexOf(curChar)!=-1) {
if (rNum.indexOf(curChar)==0) {
if (order2.indexOf(curChar)!=-1) {
aNum+=((int)Math.pow(10, order2.indexOf(curChar)));
}
else if (order3.indexOf(curChar)!=-1) {
aNum+=(5*((int)Math.pow(10, order3.indexOf(curChar))));
}
rNum = rNum.substring(1);
}
else if (rNum.indexOf(curChar)==1) {
if (order2.indexOf(curChar)!=-1) {
aNum+=((int)(Math.pow(10, order2.indexOf(curChar))-Math.pow(10, order2.indexOf(curChar)-1)));
}
else if (order3.indexOf(curChar)!=-1) {
aNum+=((int)((5*Math.pow(10, order3.indexOf(curChar)))-Math.pow(10,order3.indexOf(curChar))));
}
rNum = rNum.substring(2);
}
}
}
return aNum;
}
private static String a2R(int num, String theNum) {
// num is the digit of an Arabic digit number to be replaced by Roman Numerals for that digit
// theNum is the value of Roman Numerals that would go into the specific digit place (tens, ones,...)
String rNum = "";
if (!theNum.equals("M")) {
if (num==9) {
rNum = theNum + order.charAt(order.indexOf(theNum)+2);
}
else if (num==4) {
rNum = theNum + order.charAt(order.indexOf(theNum)+1);
}
else if (num>=5) {
rNum+= order.charAt(order.indexOf(theNum)+1);
for (int i = 0; i < num-5; i++) {
rNum+=theNum;
}
}
else {
for (int i = 0; i < num; i++) {
rNum+=theNum;
}
}
}
else {
for (int i = 0; i < num; i++) {
rNum+=theNum;
}
}
return rNum;
}
}
`
答案 0 :(得分:1)
我预计TLE是由你的程序永远不会终止造成的。
目前您有一个while (true)
循环,当您看到一个空行时break
。{
然而,根据problem ......
The input consists of several lines, each one containing
either an Arabic or a Roman number n, where 0 < n < 4000.
没有任何地方声明会有一个额外的空白行终止输入 所以你的程序不会终止,永远等待,直到输入一个额外的空行。
而不是像这样阅读你的输入
while (true) {
String read = "";
int aNum = 0;
String rNum = "";
try {
read = br.readLine();
if (read=="")
break;
} catch (IOException e) {
if (read=="")
break;
e.printStackTrace();
}
//etc
试试这个
String read = "";
while ((read = br.readLine()) != null) {
int aNum = 0;
String rNum = "";
//etc
答案 1 :(得分:0)
我通过以不同的方式解决了我的问题,我使用了几个HashMaps将罗马数字值映射到阿拉伯数字值,反之亦然。我有四个辅助方法:一个用于设置哈希图,另一个用罗马数字转换为阿拉伯数字,另外两个用于将阿拉伯数字转换为罗马数字。
从Roman转换为阿拉伯语的方法将从字符串的开头开始经过for循环中的字符串。它将检查字符串的长度是否大于1,如果是,则检查前两个值的子字符串是否在罗马字母到阿拉伯语的hashmap中。如果是这样,它会将罗马数字值等于的值添加到int变量。该方法还将检查长度为1的子串。
在从阿拉伯语转换为罗马语的方法中,首先会分析输入整数,然后将它拆分成小块。在第一种方法中,首先会产生四个整数值:千位值,百位值,十位值,然后是一些值。第二种方法是将这些值组织成正确的罗马数字形式。
感谢所有帮助我解决这个问题的人,我没有意识到我犯的一些错误,可能是由于我缺乏编程经验,所以这对我来说是一次很棒的学习经历。
以下是我的解决方案:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
class Main {
private static HashMap<String,Integer> r2A = new HashMap<String,Integer>();
private static HashMap<Integer,String> a2R = new HashMap<Integer,String>();
public static void main(String[] args) throws IOException {
InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader br = new BufferedReader(isr);
makeMaps();
String read;
StringBuilder answers = new StringBuilder("");
while ((read=br.readLine())!=null) {
int aNum = 0;
String rNum = "";
try {
aNum = Integer.parseInt(read);
System.out.println(arab2Roman(aNum));
} catch (NumberFormatException c) {
rNum = read;
int ans = roman2Arab(rNum);
System.out.println(ans);
}
}
}
private static int roman2Arab(String rNum) {
int aNum = 0;
for (int i = 0; i < rNum.length(); i++) {
boolean done = false;
String theNum = rNum.substring(i,i+1);
if (i < rNum.length()-1) {
String part = rNum.substring(i, i+2);
if (r2A.containsKey(part)) {
aNum+=r2A.get(part);
i++;
done = true;
}
}
if (!done) {
if (r2A.containsKey(theNum)) {
aNum+=r2A.get(theNum);
}
}
}
return aNum;
}
private static String arab2Roman(int num) {
StringBuilder rNum = new StringBuilder("");
int thousands = num-(num%1000);
int hundreds = ((num/100)%10)*100;
int tens = ((num/10)%10)*10;
int ones = num%10;
rNum.append(simpleConv(thousands,"thousands"));
rNum.append(simpleConv(hundreds,"hundreds"));
rNum.append(simpleConv(tens,"tens"));
rNum.append(simpleConv(ones,"ones"));
return rNum.toString();
}
private static String simpleConv(int num, String place) {
StringBuilder ans = new StringBuilder("");
int pNum = (place.equals("thousands")) ? 1000 : (place.equals("hundreds")) ? 100 : (place.equals("tens")) ? 10 : 1;
if (a2R.containsKey(num)) {
ans.append(a2R.get(num));
}
else {
if (num/pNum>=5) {
ans.append(a2R.get(5*pNum));
for (int i = 0; i < ((num/pNum)-5); i++) {
ans.append(a2R.get(pNum));
}
}
else {
for (int i = 0; i < num/pNum; i++) {
ans.append(a2R.get(pNum));
}
}
}
return ans.toString();
}
private static void makeMaps() {
// First r2A
r2A.put("I", 1);
r2A.put("IV", 4);
r2A.put("V", 5);
r2A.put("IX", 9);
r2A.put("X", 10);
r2A.put("XL", 40);
r2A.put("L", 50);
r2A.put("XC", 90);
r2A.put("C", 100);
r2A.put("CD", 400);
r2A.put("D", 500);
r2A.put("CM", 900);
r2A.put("M", 1000);
// Second a2R
a2R.put(1, "I");
a2R.put(4, "IV");
a2R.put(5, "V");
a2R.put(9, "IX");
a2R.put(10, "X");
a2R.put(40, "XL");
a2R.put(50, "L");
a2R.put(90, "XC");
a2R.put(100, "C");
a2R.put(400, "CD");
a2R.put(500, "D");
a2R.put(900, "CM");
a2R.put(1000, "M");
}
}