我的代码遇到问题。请帮忙。这是我到目前为止我的代码,我需要使用方法。它需要能够取整数1-3999并将其转换为罗马数字。有没有比我做的更简单的方法呢?
public static void main(String[] args) {
Scanner in = new Scanner (System.in);
System.out.print("Enter a number between 1 and 3999 (0 to quit): ");
int input = in.nextInt();
while (input !=0 )
{
if(input < 0 || input > 3999){
System.out.println("ERROR! NUmber must be between 1 and 3999 (0 to quit): ");
System.out.print("Enter a number between 1 and 3999 (0 to quit): ");
input = in.nextInt();
}
else if(input > 0){
String roman = convertNumberToNumeral(input);
System.out.println("The number " + input + " is the Roman numberal " + roman);
System.out.print("Enter a number between 1 and 3999 (0 to quit): ");
input = in.nextInt();
}
}
while (input == 0)
{
break;
}
System.out.println("Goodbye!");
}
// Given a Scanner as input, prompts the user to input a number between 1 and 3999.
// Checks to make sure the number is within range, and provides an error message until
// the user provides a value within range. Returns the number input by the user to the
// calling program.
private static int promptUserForNumber(Scanner inScanner, int input) {
}
// Given a number as input, converts the number to a String in Roman numeral format,
// following the rules in the writeup for Lab 09. Returns the String to the calling
// program. NOTE: This method can possibly get long and complex. Use the
// convertDigitToNumeral method below to break this up and make it a bit simpler to code.
private static String convertNumberToNumeral(int input) {
String romanOnes = ("");
String romanTens = ("");
String romanHundreds = ("");
String romanThousands = ("");
int ones = input % 10;
int tens2 = input / 10;
if (tens2 < 10)
{
tens2 = input / 10;
}
else {
tens2 = tens2 % 100;
}
int tens = tens2;
int hundreds2 = input / 100;
if (hundreds2 < 10)
{
hundreds2 = input / 10;
}
else {
hundreds2 = hundreds2 % 1000;
}
int hundreds = hundreds2;
int thousands2 = input / 1000;
if (thousands2 < 10)
{
thousands2 = input / 10;
}
else {
thousands2 = thousands2 % 10000;
}
int thousands = input & 10000;
{
if (ones == 0)
{
romanOnes = ("");
}
else if (ones == 1)
{
romanOnes = ("I");
}
else if (ones == 2)
{
romanOnes = ("II");
}
else if(ones == 3)
{
romanOnes = ("III");
}
else if(ones == 4)
{
romanOnes = ("IV");
}
else if(ones == 5)
{
romanOnes = ("V");
}
else if(ones == 6)
{
romanOnes = ("VI");
}
else if(ones == 7)
{
romanOnes = ("VII");
}
else if(ones == 8)
{
romanOnes = ("VIII");
}
else if(ones == 9)
{
romanOnes = ("IX");
}
}
{
if (tens == 0)
{
romanTens = ("");
}
else if (tens == 1)
{
romanTens = ("X");
}
else if (tens == 2)
{
romanTens = ("XX");
}
else if(tens == 3)
{
romanTens = ("XXX");
}
else if(tens == 4)
{
romanTens = ("XL");
}
else if(tens == 5)
{
romanTens = ("L");
}
else if(tens == 6)
{
romanTens = ("LX");
}
else if(tens == 7)
{
romanTens = ("LXX");
}
else if(tens == 8)
{
romanTens = ("LXXX");
}
else if(tens == 9)
{
romanTens = ("XC");
}
}
{
if (hundreds == 0)
{
romanHundreds = ("");
}
else if (hundreds == 1)
{
romanHundreds = ("C");
}
else if (hundreds == 2)
{
romanHundreds = ("CC");
}
else if(hundreds == 3)
{
romanHundreds = ("CCC");
}
else if(hundreds == 4)
{
romanHundreds = ("CD");
}
else if(hundreds == 5)
{
romanHundreds = ("D");
}
else if(hundreds == 6)
{
romanHundreds = ("DC");
}
else if(hundreds == 7)
{
romanHundreds = ("DCC");
}
else if(hundreds == 8)
{
romanHundreds = ("DCCC");
}
else if(hundreds == 9)
{
romanHundreds = ("CM");
}
}
{
if (thousands == 0)
{
romanThousands = ("");
}
else if (thousands == 1)
{
romanThousands = ("M");
}
else if (thousands == 2)
{
romanThousands = ("MM");
}
else if(thousands == 3)
{
romanThousands = ("MMM");
}
}
String roman = (romanThousands + romanHundreds + romanTens + romanOnes);
return roman;
}
// Given a digit and the Roman numerals to use for the "one", "five" and "ten" positions,
// returns the appropriate Roman numeral for that digit. For example, if the number to
// convert is 49 we would call convertDigitToNumeral twice. The first call would be:
// convertDigitToNumeral(9, 'I','V','X')
// and would return a value of "IX". The second call would be:
// convertDigitToNumeral(4, 'X','L','C')
// and would return a value of "XL". Putting those togeter we would see that 49 would be the
// Roman numeral XLIX.
// Call this method from convertNumberToNumeral above to convert an entire number into a
// Roman numeral.
private static String convertDigitToNumeral(int digit, char one, char five, char ten) {
}
答案 0 :(得分:7)
哇!你好像这样太复杂了。 4clojure.com上有一个非常类似的问题:Write Roman Numerals。你在这里有一些额外的错误检查逻辑,但即便如此,你也不需要这么多代码。我用Clojure中的10行函数解决了这个问题。但是,鉴于大多数人对Lisps不太满意,我会给你一个Python解决方案,我可以从我的Clojure解决方案中快速翻译出来。
def to_roman(n):
digits = [(1000, 'M'), (900, 'CM'), (500, 'D'), (400, 'CD' ),
(100, 'C'), (90, 'XC'), (50, 'L'), (40, 'XL'),
(10, 'X'), (9, 'IX'), (5, 'V'), (4, 'IV'), (1, 'I')]
result = ""
while len(digits) > 0:
(val, romn) = digits[0] # Unpacks the first pair in the list
if n < val:
digits.pop(0) # Removes first element
else:
n -= val
result += romn
return result
Python的语法就像伪代码一样,即使你实际上并不了解Python,你也可以理解它。我会留给你把它翻译成Java。
回复您的评论:
我认为我的问题是使用这些方法,我是如何使用我列出的方法进行的?
关于你的方法的评论非常明确他们应该做什么。您需要使用Scanner
中的main
将所有代码移至promptUserForNumber
。您将从promptUserForNumber
致电main
以获取有效的输入号码。
获得号码后,将其传递给convertNumberToNumeral
以处理转化。 convertNumberToNumeral
应循环遍历数字的每个数字,并调用convertDigitToNumeral
将每个数字转换为相应的罗马数字字符串。在concatenating之后,所有数字组件convertNumberToNumeral
可以返回完整的罗马数字表示字符串作为结果。
convertDigitToNumeral
的逻辑几乎与我上面发布的to_roman
解决方案相同,但您只需要处理一个数字。它看起来像这样:
def digit2roman(n, ten, five, one):
digits = [(9, one+ten), (5, five), (4, one+five), (1, one)]
result = ""
while len(digits) > 0:
val, romn = digits[0]
if n < val:
digits.pop(0)
else:
n -= val
result += romn
return result
将digits
拆分为2个列表可能会使转换为Java更容易:
def digit2roman(n, ten, five, one):
digitsV = [9, 5, 4, 1]
digitsR = [one+ten, five, one+five, one]
result = ""
i = 0
while i < len(digitsV):
if n < digitsV[i]:
i += 1
else:
n -= digitsV[i]
result += digitsR[i]
return result
在高级语言中,当您想要同时迭代2个序列时,将两个序列压缩成单个序列对是很常见的,但在Java中,您通常只是迭代索引。您应该有一个简单的时间使用Java数组翻译此代码。
答案 1 :(得分:1)
static HashMap<Character, Integer> numToInt;
public static void setup()
{
numToInt = new HashMap<Character, Integer>();
// this is my trick to avoid listing the numbers
String numerals = "MDCLXVI";
int number = 1000;
int factor = 2;
for (char numeral : numerals.toCharArray()) {
numToInt.put(numeral, number);
number /= factor;
factor = (factor == 2 ? 5 : 2);
}
}
public static int romanNumeralsToInt(String numeralStr)
{
int total = 0;
int prevVal = 0;
for (int i = 0; i < numeralStr.length(); i++) {
int val = numToInt.get(numeralStr.charAt(i));
total += val - (prevVal > val && prevVal != 0 ? 0 : 2 * prevVal);
prevVal = val;
}
int len = numeralStr.length();
return total;
}
答案 2 :(得分:1)
@DaoWen的答案非常好,但由于convertDigitToNumeral
方法处理的情况很少,你可以硬编码所有这些。这是使用Java's format strings(使用位置参数)的简单解决方案:
private static final String[] digitFormats = new String[] {
"", "%1$c", "%1$c%1$c", "%1$c%1$c%1$c", "%1$c%2$c",
"%2$c", "%2$c%1$c", "%2$c%1$c%1$c", "%2$c%1$c%1$c%1$c", "%2$c%3$c"
};
private static String convertDigitToNumeral(int digit, char one, char five, char ten) {
return String.format(digitFormats[digit], one, five, ten);
}
格式字符串"%2$c%1$c%1$c"
与说five.toString() + one.toString() + one.toString()
相同(假设格式参数按one
,five
,ten
的顺序传递。
答案 3 :(得分:0)
有更简单的方法吗?
如前所述,您可以使用HashTable作为罗马代码的查找。你可以有一个更大的查找,每个选项都有10个和10个选项。或者在答案中使用python代码中的一些算术将其限制为仅需要的算法。
如果您只是希望您的代码更具可读性:
string result = ""; int ones = input % 10; int tens = (input /10) % 10; int hundreds = (input / 100) % 10; int thousands = input / 1000; switch (thousands) { case 1: result = "M" break; case 2: result = "MM" break; // etc ... } switch (tens) { case 1: result = result + "C" break; // etc .. } switch (hundreds) { // etc .. } switch (ones) { // etc .. } return result;