parseRomanNumbers.cpp 2.45 KB
/* 
 * File:   parseRomanNumbers.cpp
 * Author: Derzu
 * 
 * Created on 24 de Fevereiro de 2010, 11:38
 */

#include <stdlib.h>
#include <string.h>

#include "parseRomanNumbers.h"
#include "dprintf.h"
#include "stringAux.h"

using namespace std;

namespace Util {
    /**
     * Principais numeros romanos
     */
    const string ParseRomanNumbers::BASIC_ROMAN_NUMBERS[] = { "M", "CM", "D", "CD",
                    "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I" };

    /**
     * numeros arabicos correspondentes
     */
    const int ParseRomanNumbers::BASIC_VALUES[] = { 1000, 900, 500, 400, 100, 90,
                    50, 40, 10, 9, 5, 4, 1 };

    ParseRomanNumbers::ParseRomanNumbers() {
    }

    ParseRomanNumbers::~ParseRomanNumbers() {
    }

    string ParseRomanNumbers::toRomanValue(int value) {
        string romanString = "";
        int length = sizeof(BASIC_VALUES)/sizeof(int);

        int remainder = value;
        for (int i = 0; i < length; i++) {
            while (remainder >= BASIC_VALUES[i]) {
                romanString += BASIC_ROMAN_NUMBERS[i];
                remainder -= BASIC_VALUES[i];
            }
        }

        return romanString;
    }

    int ParseRomanNumbers::toArabicValue(char * roman) {
        return toArabicValue(string(roman));
    }

    int ParseRomanNumbers::toArabicValue(string roman) {
        char * copy = StringAux::clone(roman.c_str());

        //DDPRINTF("roman _%s_, copy _%s_\n", roman.c_str(), copy);

        StringAux::toUpper((unsigned char *)copy);
        string r = string(copy);
        free(copy);
        int length = sizeof(BASIC_VALUES)/sizeof(int);
        int value = 0;
        int index = 0;
        for (int i = 0; i < length; i++) {
            while (strstr(r.c_str()+index, BASIC_ROMAN_NUMBERS[i].c_str())==(r.c_str()+index)) {
            //while (r.find_first_of(BASIC_ROMAN_NUMBERS[i], index)==0) {
                value += BASIC_VALUES[i];
                index += BASIC_ROMAN_NUMBERS[i].length();
                //DDPRINTF("value = %d, index = %d\n", value, index);
            }
        }

        // Verify the input string is a valid roman number.
        if (1 > value || value > 3999) {
            DDDPRINTF("numero invalido, deveria ser entre 1 e 3999, e eh %d\n", value);
            value = 0;
        }

        if (toRomanValue(value).compare(r)) {
            DDDPRINTF("conversao invalida (%d) e (%s)\n", value, roman.c_str());
            value = 0;
        }

        return value;
    }

}