Advertisement
Guest User

Roman_int.cpp

a guest
Aug 8th, 2012
71
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.98 KB | None | 0 0
  1. #include "Roman_int.h"
  2.  
  3. using std::string;
  4. using std::istream;
  5. using std::ostream;
  6. using std::runtime_error;
  7.  
  8. //------------------------------------------------------------------------------
  9.  
  10. int Roman_int::as_int() const
  11. {
  12.     int i_roman = 0;
  13.  
  14.     size_t roman_size = roman.size();
  15.  
  16.     for (size_t i=0; i<roman_size; ++i) {
  17.         switch (roman[i]) {
  18.         case 'I':
  19.             i_roman += valueof(roman[i]);
  20.             break;
  21.         case 'V':
  22.             if (i>0) {
  23.                 if (valueof(roman[i-1]) < valueof(roman[i]))
  24.                     i_roman += valueof(roman[i]) - 2*valueof(roman[i-1]);
  25.                 else
  26.                     i_roman += valueof(roman[i]);
  27.             } else
  28.                 i_roman += valueof(roman[i]);
  29.             break;
  30.         case 'X':
  31.             if (i>0) {
  32.                 if (valueof(roman[i-1]) < valueof(roman[i]))
  33.                     i_roman = i_roman + valueof(roman[i]) - 2*valueof(roman[i-1]);
  34.                 else
  35.                     i_roman += valueof(roman[i]);
  36.             } else
  37.                 i_roman += valueof(roman[i]);
  38.             break;
  39.         case 'L':
  40.             if (i>0) {
  41.                 if (valueof(roman[i-1]) < valueof(roman[i]))
  42.                     i_roman = i_roman + valueof(roman[i]) - 2*valueof(roman[i-1]);
  43.                 else
  44.                     i_roman += valueof(roman[i]);
  45.             } else
  46.                 i_roman += valueof(roman[i]);
  47.             break;
  48.         case 'C':
  49.             if (i>0) {
  50.                 if (valueof(roman[i-1]) < valueof(roman[i]))
  51.                     i_roman = i_roman + valueof(roman[i]) - 2*valueof(roman[i-1]);
  52.                 else
  53.                     i_roman += valueof(roman[i]);
  54.             } else
  55.                 i_roman += valueof(roman[i]);
  56.             break;
  57.         case 'D':
  58.             if (i>0) {
  59.                 if (valueof(roman[i-1]) < valueof(roman[i]))
  60.                     i_roman = i_roman + valueof(roman[i]) - 2*valueof(roman[i-1]);
  61.                 else
  62.                     i_roman += valueof(roman[i]);
  63.             } else
  64.                 i_roman += valueof(roman[i]);
  65.             break;
  66.         case 'M':
  67.             if (i>0) {
  68.                 if (valueof(roman[i-1]) < valueof(roman[i]))
  69.                     i_roman = i_roman + valueof(roman[i]) - 2*valueof(roman[i-1]);
  70.                 else
  71.                     i_roman += valueof(roman[i]);
  72.             } else
  73.                 i_roman += valueof(roman[i]);
  74.             break;
  75.         default:
  76.             i_roman = NO_VALUE;
  77.             break;
  78.         }
  79.  
  80.     }
  81.  
  82.     return i_roman;
  83. }
  84.  
  85. //------------------------------------------------------------------------------
  86.  
  87. std::istream& operator>>(std::istream& is, Roman_int& r)
  88. {
  89.     string numeral_input;
  90.     is >> numeral_input;
  91.  
  92.     if (isValidNumeral(numeral_input))
  93.         r.roman = numeral_input;
  94.     else {
  95.         r.roman = NO_VALUE;
  96.         std::cerr << "Error: Invalid input\n\n";
  97.         //throw runtime_error("Roman_int(): operator>>(): Ivalid input");
  98.     }
  99.  
  100.     return is;
  101. }
  102.  
  103.  
  104. std::ostream& operator<<(std::ostream& os, const Roman_int& r)
  105. {
  106.     os << r.roman;
  107.  
  108.     return os;
  109. }
  110.  
  111. //------------------------------------------------------------------------------
  112.  
  113. bool isValidNumeral(std::string& numeral)
  114. // A roman numeral is invalid if:
  115. // 1. it consists of a non-numerical roman letter
  116. // 2. a roman letter appears more than 3 times in a row.
  117. {
  118.     int numeral_size = numeral.size();
  119.  
  120.     // convert to uppercase
  121.     for (int i=0; i<numeral_size; ++i) {
  122.         if (int(numeral[i])>=97 && int(numeral[i])<=122) {
  123.             numeral[i] -= 32;
  124.         }
  125.     }
  126.  
  127.     // Check to see, if input consists of non-numerical roman letters.
  128.     std::array<char,14> possible_numerals {
  129.         { 'I', 'V', 'X', 'L', 'C', 'D', 'M' }
  130.     };
  131.     int possible_numerals_size = possible_numerals.size();
  132.  
  133.     bool invalid_numeral;
  134.  
  135.     for (int i=0; i<numeral_size; ++i) {
  136.         invalid_numeral = true;
  137.         for (int j=0; j<possible_numerals_size; ++j){
  138.             if (char(numeral[i]) == possible_numerals[j]) {
  139.                 invalid_numeral = false;
  140.                 break;
  141.             }
  142.         }
  143.         if (invalid_numeral == true)
  144.             return false;
  145.     }
  146.  
  147.  
  148.     // Check to see, if a roman letter appears more than 3 times in a row.
  149.     char letter = ' ';
  150.     int times_in_a_row = 0;
  151.  
  152.     for (int i=0; i<numeral_size; ++i) {
  153.         if (numeral[i] != letter) {
  154.             times_in_a_row = 1;
  155.             letter = numeral[i];
  156.         } else {
  157.             ++times_in_a_row;
  158.         }
  159.  
  160.         if (times_in_a_row > 3)
  161.             return false;
  162.     }
  163.  
  164.     return true;
  165. }
  166.  
  167. int valueof(const char c)
  168. {
  169.     switch (c) {
  170.     case 'I':
  171.         return 1;
  172.     case 'V':
  173.         return 5;
  174.     case 'X':
  175.         return 10;
  176.     case 'L':
  177.         return 50;
  178.     case 'C':
  179.         return 100;
  180.     case 'D':
  181.         return 500;
  182.     case 'M':
  183.         return 1000;
  184.     default:
  185.         return -1;
  186.     }
  187.  
  188. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement