Roman Numerals: Step 17
We’re now done. Here’s the final, entire source:
#ifndef _TO_ROMAN_H
#define _TO_ROMAN_H
#include <string>
namespace RomanNumerals
{
struct Convert
{
static const std::string ToRoman(int n)
{
struct numeralData
{
int n;
const char* s;
} nd[] =
{
{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" },
};
std::string s;
for (const auto& e : nd) {
while (n >= e.n) {
n -= e.n;
s += e.s;
}
}
return s;
}
};
}
#endif
I’m pretty happy with how it turned out. It’s tight, clear, easy to understand.
But it’s not the only way. Here’s another one:
static const std::string ToRoman(int n)
{
std::string M[] = { "","M","MM","MMM" };
std::string C[] = { "","C","CC","CCC","CD","D","DC","DCC","DCCC","CM" };
std::string X[] = { "","X","XX","XXX","XL","L","LX","LXX","LXXX","XC" };
std::string I[] = { "","I","II","III","IV","V","VI","VII","VIII","IX" };
return M[n/1000] + C[(n%1000)/100] + X[(n%100)/10] + I[(n%10)];
}
I like this one, too (well, mostly: there’s an out-of-bounds error if n is too big). Surprisingly, it runs several times slower than the while loop version, probably from copying all the std::string objects around.
When I get around to it, maybe I’ll work up the steps of a Kata that ends up with that implementation.