C++ のローマ数字コンバーター
今日の世界では、さまざまな方法で数字を表現するのに役立つ複数の数体系があります。 そのうちの 1つがローマ数法です。
古代ローマ人は、日々の活動を数えたり実行したりするためにそれらを発明しました。 この記事では、ローマ数字のシステムと、10 進数をローマ数字に変換するプログラムについて説明します。
C++ のローマ数字コンバーター
ローマ数字は、カウントやその他の目的のために特定の形式で数値を表します。
学校でこれらのローマ数字について聞いたり、時計でその実際の例を見たりしたことがあるでしょう。 ローマ数字は、多くの場合、時計の数字を表します。
ローマ数字システムは、ラテン アルファベットの 7 文字の組み合わせで表されます。 7つの文字または記号のそれぞれには、明確な価値があります。
7つの文字とその特定の値を以下に示します。
I - 1
V - 5
X - 10
L - 50
C - 100
D - 500
M - 1000
ただし、覚えておくべきことは、1000 以降は 10000 の記号がないことです。 したがって、ローマ数字で表現できる最大数は 3999 です。
それでは、10 進数をローマ数字に変換する方法について説明しましょう。
ローマ数字の数字は、左から右に降順で書かれます。 ただし、場合によっては、(IIII または XXXX) のように、同じ 4つの連続する文字の繰り返しを避けるために、減算表記に従います。 減算表記は、4 と 9 を含む数字で使用されます。
減算表記では、I を V
または X
の前に置き、IV
(4) または IX
(9) にします。 同様に、X
を L
または C
の前に置き、XL
または XC
にします。
したがって、減算表記の記号は、2つの記号を組み合わせて作成されます。 そこで、減算表記も含むローマ数字を見てみましょう。
SYMBOL Number
I 1
IV 4
V 5
IX 9
X 10
XL 40
L 50
XC 90
C 100
CD 400
D 500
CM 900
M 1000
C++ で 10 進数をローマ数字に変換する
整数をローマ数字に変換する手順は次のとおりです。
- 与えられた 10 進数が 0 になるまで、以下のプロセスを繰り返します。
- 1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1.
- 基数が与えられた 10 進数 (基数の最大値) 以下の場合は、10 進数を基数で割ります。
- ここで、基準値の対応する記号、商の回数を変数に追加します。 例: 商が 3 で、基数が 10 の場合、対応する 10 の表現、つまり
X
は答えでXXX
として 3 回繰り返されます。 - ただし、残りはその後の分割の新しい番号になります。
- 10 進数が 0 になるまで記号が追加された変数には、答えが含まれます。
上記のアルゴリズムを使用してローマ数字に変換する 10 進数として 2954 という数値を使用します。
出力:
MMCMLIV
説明:
ステージ 1:
- 最初は、10 進数は 2954 です。
- 2954>=1000 であるため、最大のベース値は 1000 に対応します。
- 2954 を 1000 で割ると、商 = 2 余り = 954 になります。1000 に対応する記号は
M
なので、2 回繰り返されます。 - したがって、結果は今のところ、
MM
に等しくなります。 - 剰余は、さらなる分割を実行するための新しい数になります。
ステージ 2:
- これで、数字は 954 になります
- ベース値 1000>954>=900 と比較します。 したがって、最大の基準値は 900 です。
- 954 を 900 で割ると、商 = 1 余り = 54 になります。900 に対応する記号は
CM
であるため、1 回追加されます。 - したがって、結果は
MMCM
になります。 - 剰余は、さらなる分割を実行するための新しい数になります。
ステージ 3:
- これで54個になりました。
- ベース値 90>54>=50 と比較します。 したがって、最大の基準値は 50 です。
- 54 を 50 で割ると、商 = 1 余り = 4 になります。50 に対応する記号は
L
なので、1 回追加されます。 - したがって、結果は
MMCML
になります。 - 剰余は、さらなる分割を実行するための新しい数になります。
ステージ 4:
- これで数字が 4 になりました。
- ベース値 5>4>=4 と比較します。 したがって、最大の基本値は 4 です。
- 4 を 4 で割ると、商 = 1 余り = 0 になります。4 に対応する記号は
IV
なので、1 回追加されます。 - したがって、結果は
MMCMLIV
になります。 - 剰余がゼロになるので、反復は停止し、必要な答えが得られます。
10 進数をローマ数字に変換する C++ コードの例
C++ で 10 進数をローマ数字に変換するコード例を見てみましょう。
#include <bits/stdc++.h>
using namespace std;
int subDig(char n1, char n2, int i, char c[]) {
c[i++] = n1;
c[i++] = n2;
return i;
}
int digit(char ch, int n, int i, char c[]) {
for (int j = 0; j < n; j++) {
c[i++] = ch;
}
return i;
}
int convertRoman(int num) {
char c[10001];
int i = 0;
while (num != 0) {
if (num >= 1000) {
i = digit('M', num / 1000, i, c);
num = num % 1000;
} else if (num >= 500) {
if (num < 900) {
i = digit('D', num / 500, i, c);
num = num % 500;
} else {
i = subDig('C', 'M', i, c);
num = num % 100;
}
} else if (num >= 100) {
if (num < 400) {
i = digit('C', num / 100, i, c);
num = num % 100;
} else {
i = subDig('C', 'D', i, c);
num = num % 100;
}
} else if (num >= 50) {
if (num < 90) {
i = digit('L', num / 50, i, c);
num = num % 50;
} else {
i = subDig('X', 'C', i, c);
num = num % 10;
}
} else if (num >= 10) {
if (num < 40) {
i = digit('X', num / 10, i, c);
num = num % 10;
} else {
i = subDig('X', 'L', i, c);
num = num % 10;
}
} else if (num >= 5) {
if (num < 9) {
i = digit('V', num / 5, i, c);
num = num % 5;
} else {
i = subDig('I', 'X', i, c);
num = 0;
}
} else if (num >= 1) {
if (num < 4) {
i = digit('I', num, i, c);
num = 0;
} else {
i = subDig('I', 'V', i, c);
num = 0;
}
}
}
for (int j = 0; j < i; j++) {
cout << c[j];
}
}
int main() {
int number = 2954;
convertRoman(number);
return 0;
}
出力:
MMCMLIV
上記のコードでは、if/else
条件を使用して数値 num
を基本値と比較し、これに基づいて、対応する変数を回答に追加しました。
ただし、減算表記に従う数字は、subDig
関数で個別に処理され、2つの文字記号が回答に追加されます。
上記のコードは非常に長いです。 したがって、コードを要約すると、以前に説明したよりもはるかに短い別のアプローチについて説明しましょう。
アプローチ 2
このアプローチは、ベース値とそれに対応するシンボルを別々に配列に格納し、ループ中にそれらを使用することに基づいています。
同じコードを見てみましょう。
#include <bits/stdc++.h>
using namespace std;
int convertRoman(int num) {
int base_values[] = {1, 4, 5, 9, 10, 40, 50, 90, 100, 400, 500, 900, 1000};
string symbols[] = {"I", "IV", "V", "IX", "X", "XL", "L",
"XC", "C", "CD", "D", "CM", "M"};
int i = 12;
while (num > 0) {
int quot = num / base_values[i];
num = num % base_values[i];
while (quot--) {
cout << symbols[i];
}
i--;
}
}
int main() {
int number = 2543;
convertRoman(number);
return 0;
}
出力:
MMDXLIII
上記のコードでは、ベース値とそれに対応するシンボルを配列に格納し、数値をベース値と降順で比較しました。
これに続いて、数値を最大の基数で割り、商と剰余を求めます。 今度は、対応するシンボルが while
ループを使用して数回出力されます。
まとめ
この記事では、10 進数からローマ数字への変換について説明しました。 ローマ数字は、10 進数を記号で表す方法です。
ローマ数字は左から右に降順で書かれています。 ただし、いくつかのケースでは、小さい記号が大きい記号の前に書かれる減法表記法を使用します。
これらのケースは数字の 4 と 9 で発生し、この記事で説明されています。