ローマ数字とアラビア数字の変換
概要
0 から 3999 まで対応
実装
int from_roman(const std::string &s) {
static const std::map<char, int> m = {{'I', 1}, {'V', 5}, {'X', 10}, {'L', 50},
{'C', 100}, {'D', 500}, {'M', 1000}};
static const auto get = [&](char c) {
assert(m.find(c) != m.end());
return m.find(c)->second;
};
int n = 0;
for (int i = 0; i < (int)s.size(); ++i) {
if (i + 1 == (int)s.size() || get(s[i]) >= get(s[i + 1]))
n += get(s[i]);
else
n -= get(s[i]);
}
return n;
}
std::string to_roman(int n) {
static const std::map<int, std::string> m = {{1, "I"}, {5, "V"}, {10, "X"}, {50, "L"},
{100, "C"}, {500, "D"}, {1000, "M"}};
static const auto get = [&](int c) {
assert(m.find(c) != m.end());
return m.find(c)->second;
};
std::string res;
int p = 1;
while (n) {
int d = n % 10;
int f = d % 5;
std::string s = "";
if (f == 0) {
} else if (f <= 3) {
for (int i = 0; i < f; ++i) s += get(p);
} else if (f == 4) {
s += get(p);
}
if (f <= 3) {
if (d >= 5) s = get(p * 5) + s;
} else {
if (d >= 5)
s += get(p * 10);
else
s += get(p * 5);
}
res = s + res;
p *= 10;
n /= 10;
}
return res;
}
検証
AOJ0039 http://judge.u-aizu.ac.jp/onlinejudge/review.jsp?rid=2189361
using namespace std;
int main(){
for(int i = 0;; ++i){
cout << i << endl;
assert(from_roman(to_roman(i)) == i);
}
}