2013-07-04 55 views
1

我遇到了我的代碼問題。請幫助。這是我到目前爲止的代碼,我需要使用方法。它需要能夠取整數1-3999並將其轉換爲羅馬數字。有沒有比我所做的更簡單的方法來做到這一點?將Int轉換爲羅馬數字

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) { 


} 
+2

當你得到很多其他的if時,考慮使用switch語句來代替(它提高了可讀性,特別是當幾個案例給出相同的答案時)。 – keyser

+2

僅供參考在這個問題的答案中有幾個很好的Java解決方案:[將整數轉換爲羅馬數字 - Java](http://stackoverflow.com/questions/12967896/converting-integers-to-roman-numerals-java) – IgnisErus

回答

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。


響應您的評論:

我想我的問題是使用方法,我該怎麼辦呢利用我所列出的方法?

對你的方法的評論非常清楚他們應該做什麼。您需要將所有使用Scannermain的代碼移動到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數組翻譯此代碼的簡單時間。

+0

我認爲我的問題是使用這些方法,我如何使用我列出的方法來做到這一點? – user2509405

+0

@ user2509405 - 查看我的編輯。 – DaoWen

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; 
} 
+0

只是看着這個,我覺得有些不對勁。你將'I'設置爲1000,V爲500,X爲100,L爲50(正確),C爲10,D爲5,M爲1. – 2013-07-05 00:12:26

+0

我認爲你想以'number = 1000,factor = 5',然後乘以係數而不是除數。 – 2013-07-05 00:13:14

+0

對不起,我列出了字母倒退。立即切換。謝謝@DaftPunk。 – isaach1000

0

有沒有更簡單的方法?

如前所述,您可以使用HashTable作爲羅馬代碼的查找。您可以使用全部十個選項中的一個,十個和幾百個選項進行更大的查找。或者在答案中用python代碼中的一些算術來限制它只是必需的。

如果你只是想你的代碼更易讀:

  1. 凝聚你的計算。
  2. 將嵌套的ifs轉換爲switch語句。
 
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; 

+0

我不會切換(數千),而是新的字符串(新字符[千]]。這首先創建一個空字符串(\ 0),然後用M替換它們。對於其他 – Xesau

+0

@Xesau來說,有無數更好的方法來解決這個問題(一些已經提出)。正如我在回答中所提到的那樣,switch語句的使用是在不改變邏輯的情況下「使OP的代碼更易讀」的一種建議。 –

1

@道韞的回答非常好,但因爲有這麼幾個案例爲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()(假設參數的順序onefiveten通過格式)。