blog

ローマ数字を10進数に変換する3つの方法

簡単なものから難しいものまで、3つのメソッドに分かれています。しかし、それはすべて暴力的な解決法です。 引き算を構成する文字列を見つけるのは簡単で、まず足し算を終えてから引き算をします。 隣り合うロー...

Oct 18, 2020 · 3 min. read
シェア

必要条件

古代ローマ帝国は人類に輝かしい文明をもたらしましたが、彼らの数字の表現は実に煩雑で、特に大きな数を表すとなると、現在ではとても耐えられないようなものでした。これは、この表現を考案した人々の知性に問題があったわけではなく、当時、数字の0という概念を禁じていた宗教的な理由によるものです!ローマ数字の表現は、次の基本記号に依存しています: I -> 1 V -> 5 X -> 10 L -> 50 C -> 100 D -> 500 MD -> 500 M -> 1000 ここでは、1000までの数の表現のみを説明します。一つの記号はその回数だけ繰り返されます。最大3回まで繰り返します。例:CCCは300 XXは20を表しますが、150はLLLを表すのに使われず、このルールはI X C Mにのみ適用されます。隣接するレベルの大単位が右側にあり、小単位が左側にある場合、大単位から小単位を引くことを意味します。例:IXは9 IVは4 XLは40 49 = XLIX より多くの例については下の表を参照してください。i = 1 ii = 2 iii = 3 iv = 4 v = 5 vi = 6 vii = 7 viii = 8 ix = 9 x = 10 xi = 11 xii = 12 xiii = 13 xiv = 14 xv = 15 xvi = 16 xvii = 17 xviii = 18 xix = 19 xx = 20 xxi = 21 xxii = 22 xxix = 29 xxx = 30xxxiv = 34 xxxv = 35 xxxix = 39 xl = 40 l = 50 li = 51 lv = 55 lx = 60 lxv = 65 lxxx = 80 xc = 90 xciii = 93 xcv = 95 xcviii = 98 xcix = 99 c = 100 cc = 200 ccc = 300 cd = 400 d = 500 dc = 600DCC = 700 DCCC = 800 CM = 900 CMXCIX = 999 この問題の要求:ユーザがローマ数字の文字列を入力し、プログラムが対応する10進数表現を出力するプログラムを書きなさい。入力形式は次の通り:最初の行は整数nで、後に続くローマ数字がn個あることを示します。続く各行はローマ数字です。ローマ数字の大きさは999を超えません。 プログラムは、ローマ数字の対応する10進データであるn行を出力する必要があります。例えば、ユーザが 3 LXXX XCIII DCCII と入力した場合、プログラムは 80 93 207 と出力します。

解答

3つのメソッドに分かれていて、3つのメソッドは簡単なものから難しいものまであります。しかし、それはすべて暴力的な解法です。

  1. 引き算を構成する文字列を見つけ、引き算の前に足し算を終わらせるのは簡単です。
  2. 変換規則に従って文字列を繰り返します。
    • 隣接するローマ数字は加算されます。
    • 隣接するローマ数字は、左が右より小さい場合、右 - 左に等しくなります。
  3. アイデアは第2幕と同じですが、アルゴリズム的にはよりクリーンです。
import java.util.*;
/*この問題の要件は次のとおりである: ユーザーがローマ数字の文字列を入力し、対応する10進数表現を出力するプログラムを書きなさい 
 入力形式は次のとおりである:最初の行は整数nで、次のn個のローマ数字(n<100)。
 以後は1行に1つのローマ数字とする。ローマ数字の大きさは999を超えない。
 プログラムにはn行の出力が要求されるが、これはローマ数字に対応する10進数データである。*/
public class Test3 {
 public static void main(String[] args) {
 method1("XCV");
// method2("XCV");
// method3("XCV");
 }
 //引き算を構成する文字列を直接見つける
 private static void method1(String lm) {
 int sum =0;
 //文字列を繰り返し処理し、もし存在すれば、その文字列に
 for (int i = 0; i < lm.length(); i++) {
 char c = lm.charAt(i);
 if (c == 'I') sum += 1;
 if (c == 'V') sum += 5;
 if (c == 'X') sum += 10;
 if (c == 'L') sum += 50;
 if (c == 'C') sum += 100;
 if (c == 'D') sum += 500;
 if (c == 'M') sum += 1000;
 }
 //indexOF(V)変更された部分文字列のインデックスを返す
 if (lm.indexOf("IV")>=0) sum -= 2;
 if (lm.indexOf("IX")>=0) sum -= 2;
 if (lm.indexOf("XL")>=0) sum -= 20;
 if (lm.indexOf("CD")>=0) sum -= 200;
 if (lm.indexOf("CM")>=0) sum -= 200;
 if (lm.indexOf("XC")>=0) sum -= 20;
 System.out.println(sum);
 }
 //それらをキーと値のペアにし、一つずつ繰り返し処理する。
 private static void method2(String lm) {
 //ローマ数字に値を割り当てる
 Map<Character,Integer> map = new HashMap<>();
 map.put('I',1);
 map.put('V',5);
 map.put('X',10);
 map.put('L',50);
 map.put('C',100);
 map.put('D',500);
 map.put('M',1000);
 //数字を配列に分割する
 //10進数値
 int sum = 0;
 char[] chars = lm.toCharArray();
 //文字の配列を右から左にループする。,
 for (int i = chars.length-1; i >= 1; i--) {
 //インデックスの代わりにiの初期値を変更する方がよい。
 //現在の値
 int cur = map.get(chars[i]);
 //前の
 int left = map.get(chars[i - 1]);
 //現在の値がleftより大きい場合、left-leftを引く。
 //初めての場合は、次の式を変更する必要がある。
 if (i == chars.length-1){
 if (left < cur){
 sum = sum + cur - left;
 }else {
 sum = sum +cur+ left;
 }
 }else{
 if (left < cur){
 sum = sum - left;
 }else {
 sum = sum + left;
 }
 }
 }
 System.out.println(sum);
 }
 //考え方は第2法と同じだが、アルゴリズム的に単純化されている。
 private static void method3(String lm) {
 HashMap<String, Integer> map=new HashMap<String, Integer>();
 map.put("I", 1);
 map.put("V", 5);
 map.put("X", 10);
 map.put("L", 50);
 map.put("C", 100);
 map.put("D", 500);
 map.put("M", 1000);
 int result=0;
 for(int i=0;i<lm.length();i++){
 //割り算の最後の桁の前の数字だけを数える。
 if(i <= lm.length()-2){
 //+""私のMapキーはString型なので、この効果は文字列に変えることである。
 //左が右より小さければ引き、iが加えられる。+1,次の2つにスキップし、そうでなければ一度に1桁ずつ加算する。
 if(map.get(lm.charAt(i)+"") < map.get(lm.charAt(i+1)+"")){
 result += (map.get(lm.charAt(i+1)+"")-map.get(lm.charAt(i)+""));
 i++;
 }else{
 result += map.get(lm.charAt(i)+"");
 }
 //最後の桁は直接加算される
 }else{
 result += map.get(lm.charAt(i)+"");
 }
 }
 System.out.println(result);
 }
}
Read next

vueは動的にリアルタイムで時刻を表示する。

次の2つの方法があります。\n日付と時刻を扱うjsライブラリであるday.jsを使います。\n使い方 npm install dayjs --save\ndayjs を 'dayjs' からインポートします。\n次に、最新の時刻を更新するタイマーを作成します。\nt

Oct 17, 2020 · 2 min read

テスト済み

Oct 15, 2020 · 2 min read

Threadローカルのメモリリーク

Oct 14, 2020 · 3 min read

golangランタイムのGOMAXPROCS。

Oct 14, 2020 · 1 min read