#include <array>
#include <string>
#include <string_view>
#include <utility>
using namespace std::literals;
class Roman {
private:
using roman_pair = std::pair<std::string_view, int>;
static constexpr std::array<roman_pair, 13> lookup{{
{"M"sv , 1000},
{"CM"sv, 900},
{"D"sv , 500},
{"CD"sv, 400},
{"C"sv , 100},
{"XC"sv, 90},
{"L"sv , 50},
{"XL"sv, 40},
{"X"sv , 10},
{"IX"sv, 9},
{"V"sv , 5},
{"IV"sv, 4},
{"I"sv , 1}
}};
public:
static std::string romanize(int n) noexcept {
std::string result;
for (const roman_pair& p : lookup) {
while (n >= p.second) {
result += p.first;
n -= p.second;
}
}
return result;
}
static int to_int(std::string_view s) noexcept {
int result = 0;
for (const roman_pair& p : lookup) {
while (s.size() >= p.first.size() &&
std::equal(p.first.begin(), p.first.end(), s.begin())) {
result += p.second;
s.remove_prefix(p.first.size());
}
}
return result;
}
static bool is_valid_roman(std::string_view s) noexcept {
for (const roman_pair& p : lookup) {
while (s.size() >= p.first.size() &&
std::equal(p.first.begin(), p.first.end(), s.begin())) {
s.remove_prefix(p.first.size());
}
}
return s.empty();
}
};
#include <algorithm>
#include <iostream>
int main() {
std::cout << "输入你想转换的内容。输入阿拉伯数字转换为罗马数字,输入罗马数字转化为阿拉伯数字,输入Q退出。" << std::endl;
for (;;) {
int n;
std::cin >> n;
if (std::cin.fail()) {
std::cin.clear();
std::string s;
std::getline(std::cin, s);
std::transform(s.begin(), s.end(), s.begin(), ::toupper);
if (s == "Q") break;
if (!Roman::is_valid_roman(s)) {
std::cout << "你输入的既不是阿拉伯数字也不是正确的罗马数字。" << std::endl;
continue;
}
std::cout << Roman::to_int(s) << std::endl;
} else {
if (n <= 0 || n >= 4000) {
std::cout << "罗马数字不能表示0、负数和大于3999的数。" << std::endl;
continue;
}
std::cout << Roman::romanize(n) << std::endl;
}
}
return 0;
}