Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "Roman_int.h"
- using std::string;
- using std::istream;
- using std::ostream;
- using std::runtime_error;
- //------------------------------------------------------------------------------
- int Roman_int::as_int() const
- {
- int i_roman = 0;
- size_t roman_size = roman.size();
- for (size_t i=0; i<roman_size; ++i) {
- switch (roman[i]) {
- case 'I':
- i_roman += valueof(roman[i]);
- break;
- case 'V':
- if (i>0) {
- if (valueof(roman[i-1]) < valueof(roman[i]))
- i_roman += valueof(roman[i]) - 2*valueof(roman[i-1]);
- else
- i_roman += valueof(roman[i]);
- } else
- i_roman += valueof(roman[i]);
- break;
- case 'X':
- if (i>0) {
- if (valueof(roman[i-1]) < valueof(roman[i]))
- i_roman = i_roman + valueof(roman[i]) - 2*valueof(roman[i-1]);
- else
- i_roman += valueof(roman[i]);
- } else
- i_roman += valueof(roman[i]);
- break;
- case 'L':
- if (i>0) {
- if (valueof(roman[i-1]) < valueof(roman[i]))
- i_roman = i_roman + valueof(roman[i]) - 2*valueof(roman[i-1]);
- else
- i_roman += valueof(roman[i]);
- } else
- i_roman += valueof(roman[i]);
- break;
- case 'C':
- if (i>0) {
- if (valueof(roman[i-1]) < valueof(roman[i]))
- i_roman = i_roman + valueof(roman[i]) - 2*valueof(roman[i-1]);
- else
- i_roman += valueof(roman[i]);
- } else
- i_roman += valueof(roman[i]);
- break;
- case 'D':
- if (i>0) {
- if (valueof(roman[i-1]) < valueof(roman[i]))
- i_roman = i_roman + valueof(roman[i]) - 2*valueof(roman[i-1]);
- else
- i_roman += valueof(roman[i]);
- } else
- i_roman += valueof(roman[i]);
- break;
- case 'M':
- if (i>0) {
- if (valueof(roman[i-1]) < valueof(roman[i]))
- i_roman = i_roman + valueof(roman[i]) - 2*valueof(roman[i-1]);
- else
- i_roman += valueof(roman[i]);
- } else
- i_roman += valueof(roman[i]);
- break;
- default:
- i_roman = NO_VALUE;
- break;
- }
- }
- return i_roman;
- }
- //------------------------------------------------------------------------------
- std::istream& operator>>(std::istream& is, Roman_int& r)
- {
- string numeral_input;
- is >> numeral_input;
- if (isValidNumeral(numeral_input))
- r.roman = numeral_input;
- else {
- r.roman = NO_VALUE;
- std::cerr << "Error: Invalid input\n\n";
- //throw runtime_error("Roman_int(): operator>>(): Ivalid input");
- }
- return is;
- }
- std::ostream& operator<<(std::ostream& os, const Roman_int& r)
- {
- os << r.roman;
- return os;
- }
- //------------------------------------------------------------------------------
- bool isValidNumeral(std::string& numeral)
- // A roman numeral is invalid if:
- // 1. it consists of a non-numerical roman letter
- // 2. a roman letter appears more than 3 times in a row.
- {
- int numeral_size = numeral.size();
- // convert to uppercase
- for (int i=0; i<numeral_size; ++i) {
- if (int(numeral[i])>=97 && int(numeral[i])<=122) {
- numeral[i] -= 32;
- }
- }
- // Check to see, if input consists of non-numerical roman letters.
- std::array<char,14> possible_numerals {
- { 'I', 'V', 'X', 'L', 'C', 'D', 'M' }
- };
- int possible_numerals_size = possible_numerals.size();
- bool invalid_numeral;
- for (int i=0; i<numeral_size; ++i) {
- invalid_numeral = true;
- for (int j=0; j<possible_numerals_size; ++j){
- if (char(numeral[i]) == possible_numerals[j]) {
- invalid_numeral = false;
- break;
- }
- }
- if (invalid_numeral == true)
- return false;
- }
- // Check to see, if a roman letter appears more than 3 times in a row.
- char letter = ' ';
- int times_in_a_row = 0;
- for (int i=0; i<numeral_size; ++i) {
- if (numeral[i] != letter) {
- times_in_a_row = 1;
- letter = numeral[i];
- } else {
- ++times_in_a_row;
- }
- if (times_in_a_row > 3)
- return false;
- }
- return true;
- }
- int valueof(const char c)
- {
- switch (c) {
- case 'I':
- return 1;
- case 'V':
- return 5;
- case 'X':
- return 10;
- case 'L':
- return 50;
- case 'C':
- return 100;
- case 'D':
- return 500;
- case 'M':
- return 1000;
- default:
- return -1;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement