Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <sstream>
- #include <string>
- #include <map>
- using namespace std;
- //#include "riesenie.h"
- #if !defined( _RIESENIE_H_ )
- #define _RIESENIE_H_
- #ifdef _WIN32
- typedef __int64 MY_LONG;
- #endif
- #ifndef _WIN32
- typedef long long MY_LONG;
- #endif
- class RIMSKA_KALKULACKA {
- protected:
- virtual MY_LONG konverziaRimskych(const string &rimskeCislo);
- virtual string konvertNaRimske(MY_LONG cislo);
- int kalkulackaArabska(char oper, MY_LONG op1, MY_LONG op2);
- public:
- virtual string kalkulackaRimska(const string &vyraz);
- RIMSKA_KALKULACKA(const string &pismena = "OIVXLCDMPQRSTUWYZEFG");
- string pismena;
- private:
- };
- class OBECNA_RIMSKA_KALKULACKA : public RIMSKA_KALKULACKA {
- public:
- //2. uloha
- bool nastavCislice(const string pismena);
- MY_LONG konverziaRimskych(const string &rimskeCislo);
- string konvertNaRimske(MY_LONG cislo);
- string kalkulackaRimska(const string &vyraz);
- MY_LONG maximumInt();
- //3. uloha
- string maximum();
- string minimum();
- //4. uloha
- void zakazNulu();
- void povolNulu();
- //5. uloha
- int pocetCislic();
- string zoznamCislic();
- bool rozsirZoznamCislic(const string novePismena);
- private:
- int index;
- MY_LONG nasl;
- string nul;
- bool nula;
- map<char, int> rim;
- map<int, std::string> arab;
- };
- const string CISLO_MIMO = "Cislo mimo povolenych hodnot";
- const string ZLY_VYRAZ = "Zly vstupny vyraz";
- const bool DUMMY_BOOL = false;
- const int DUMMY_INT = 0;
- const string DUMMY_STRING = "";
- #endif
- string RIMSKA_KALKULACKA::kalkulackaRimska(const string &vyr) {
- string vystup;
- string cis1 = "";
- string cis2 = "";
- string povoleneZnaky = "OIVXLCDMPQRSTUWYZEFG";
- string povoleneZnamienka = "*-+/&|><=";
- string ret = "";
- // odstranenie medzier
- for (unsigned int i = 0; i < vyr.length(); i++) {
- if (vyr[i] != ' ') ret += vyr[i];
- }
- // rozdelenie na cisla + znamienko, zatial nevieme ci spravne
- bool naslo = false;
- char znamienko = 'N';
- int index;
- for (unsigned int i = 1; i < ret.length(); i++) {
- for (unsigned int j = 0; j < povoleneZnamienka.length(); j++) {
- if (ret[i] == povoleneZnamienka[j]) {
- naslo = true;
- znamienko = ret[i];
- index = i;
- break;
- }
- }
- if (naslo) break;
- }
- if (znamienko == 'N') return ZLY_VYRAZ; // nenaslo znamienko, zly vyraz
- int cis1Z = 1;
- int cis2Z = 1;
- cis1 = ret.substr(0, index);
- cis2 = ret.substr(index+1);
- // teraz zistime ci su zaporne a spravne zadane
- if (cis1[0] == '-') {
- cis1Z *= -1;
- cis1 = cis1.substr(1);
- }
- if (cis2[0] == '-') {
- cis2Z *= -1;
- cis2 = cis2.substr(1);
- }
- // skontroluj spravnost cisiel
- for (unsigned int i = 0; i < cis1.length(); i++) {
- naslo = false;
- for (unsigned int j = 0; j < povoleneZnaky.length(); j++) {
- if (cis1[i] == povoleneZnaky[j]) {
- naslo = true;
- break;
- }
- }
- if (naslo == false) return ZLY_VYRAZ;
- }
- for (unsigned int i = 0; i < cis2.length(); i++) {
- naslo = false;
- for (unsigned int j = 0; j < povoleneZnaky.length(); j++) {
- if (cis2[i] == povoleneZnaky[j]) {
- naslo = true;
- break;
- }
- }
- if (naslo == false) return ZLY_VYRAZ;
- }
- // delenie nulou
- if (cis2 == "O" && znamienko == '/') return CISLO_MIMO;
- if (cis1 == "" || cis2 == "") return ZLY_VYRAZ;
- MY_LONG rim1 = konverziaRimskych(cis1);
- MY_LONG rim2 = konverziaRimskych(cis2);
- string rim11 = konvertNaRimske(rim1);
- string rim22 = konvertNaRimske(rim2);
- if (rim11 != cis1 || rim22 != cis2) return ZLY_VYRAZ; // VYLEPSIT
- int cisloArabske = kalkulackaArabska(znamienko, rim1*cis1Z, rim2*cis2Z); //
- if (cisloArabske < 0) {
- cisloArabske *= -1;
- vystup = konvertNaRimske(cisloArabske);
- return "-"+vystup;
- }
- vystup = konvertNaRimske(cisloArabske);
- // cout << "" << vystup << "\n";
- return vystup;
- }
- MY_LONG RIMSKA_KALKULACKA::konverziaRimskych(const string &rimskeCislo) {
- // const char* s = rimskeCislo.c_str();
- // int x = 0; // result
- //
- // int j, m = 0; // max used digit
- // const char* p = s, *q; while (*p) ++p;
- // for (--p; p >= s; p--) for (q = "IVXLCDMPQRSTUWYZEFG", j = 0; *q; q++, j++) if (*p == *q)
- // x += ((j >= m) ? m = j, 1 : -1) * (1 + j % 4 / 2 * 9) * (1 + j / 4 * 99) * (1 + j % 2 * 4);
- // return x;
- map<char, int> roman;
- roman['G'] = 1000000000;
- roman['F'] = 500000000;
- roman['E'] = 100000000;
- roman['Z'] = 50000000;
- roman['Y'] = 10000000;
- roman['W'] = 5000000;
- roman['U'] = 1000000;
- roman['T'] = 500000;
- roman['S'] = 100000;
- roman['R'] = 50000;
- roman['Q'] = 10000;
- roman['P'] = 5000;
- roman['M'] = 1000;
- roman['D'] = 500;
- roman['C'] = 100;
- roman['L'] = 50;
- roman['X'] = 10;
- roman['V'] = 5;
- roman['I'] = 1;
- roman['O'] = 0;
- MY_LONG res = 0;
- for (unsigned int i = 0; i < rimskeCislo.size() - 1; ++i)
- {
- if (roman[rimskeCislo[i]] < roman[rimskeCislo[i+1]])
- res -= roman[rimskeCislo[i]];
- else
- res += roman[rimskeCislo[i]];
- }
- res += roman[rimskeCislo[rimskeCislo.size()-1]];
- return res;
- }
- string RIMSKA_KALKULACKA::konvertNaRimske(MY_LONG cislo)
- {
- if (cislo == 0) return "O";
- //1 5
- //10 500
- //100 1000
- map<int, string> valueMap;
- string pismena = "IVXLCDMPQRSTUWYZEFG";
- valueMap[1] = "I";
- valueMap[4] = "IV";
- valueMap[5] = "V";
- valueMap[9] = "IX";
- valueMap[10] = "X";
- valueMap[40] = "XL";
- valueMap[50] = "L";
- valueMap[90] = "XC";
- valueMap[100] = "C";
- valueMap[400] = "CD";
- valueMap[500] = "D";
- valueMap[900] = "CM";
- valueMap[1000] = "M";
- valueMap[4000] = "MP";
- valueMap[5000] = "P";
- valueMap[9000] = "MQ";
- valueMap[10000] = "Q";
- valueMap[40000] = "QR";
- valueMap[50000] = "R";
- valueMap[90000] = "QS";
- valueMap[100000] = "S";
- valueMap[400000] = "ST";
- valueMap[500000] = "T";
- valueMap[900000] = "SU";
- valueMap[1000000] = "U";
- valueMap[4000000] = "UW";
- valueMap[5000000] = "W";
- valueMap[9000000] = "UY";
- valueMap[10000000] = "Y";
- valueMap[40000000] = "YZ";
- valueMap[50000000] = "Z";
- valueMap[90000000] = "YE";
- valueMap[100000000] = "E";
- valueMap[400000000] = "EF";
- valueMap[500000000] = "F";
- valueMap[900000000] = "EG";
- valueMap[1000000000] = "G";
- // vysledok
- string romanResult = "";
- map<int, string>::reverse_iterator it;
- for (it = valueMap.rbegin(); it != valueMap.rend(); it++)
- {
- //if current number is greater than current key in list
- //add the value corresponded with key to result
- //then subtract the equivalent int value from current number
- while (cislo >= it->first)
- {
- romanResult = romanResult + it->second;
- cislo = cislo - it->first;
- }
- }
- return romanResult;
- }
- int RIMSKA_KALKULACKA::kalkulackaArabska(char oper, MY_LONG op1, MY_LONG op2) {
- switch(oper){
- case '+': return op1 + op2;
- case '-': return op1 - op2;
- case '*': return op1 * op2;
- case '/': return op1 / op2;
- case '>': {
- if (op1 > op2)
- return 1;
- else return 0;
- }
- case '<': {
- if (op1 < op2)
- return 1;
- else
- return 0;
- }
- case '=': {
- if (op1 == op2)
- return 1;
- else return 0;
- }
- case '&': {
- if (op1 == 0 || op2 == 0) return 0;
- else return 1;
- }
- case '|': {
- if (op1 == 0 && op2 == 0) return 0;
- }
- default: return 1;
- };
- }
- RIMSKA_KALKULACKA::RIMSKA_KALKULACKA(const string &pismena) {
- this->pismena = pismena;
- }
- //2. uloha
- string OBECNA_RIMSKA_KALKULACKA::kalkulackaRimska(const string &vyr) {
- string vystup;
- string cis1 = "";
- string cis2 = "";
- string povoleneZnaky = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
- string povoleneZnamienka = "*-+/&|><=";
- string ret = "";
- // odstranenie medzier
- for (unsigned int i = 0; i < vyr.length(); i++) {
- if (vyr[i] != ' ') ret += vyr[i];
- }
- // rozdelenie na cisla + znamienko, zatial nevieme ci spravne
- bool naslo = false;
- char znamienko = 'N';
- int index;
- for (unsigned int i = 1; i < ret.length(); i++) {
- for (unsigned int j = 0; j < povoleneZnamienka.length(); j++) {
- if (ret[i] == povoleneZnamienka[j]) {
- naslo = true;
- znamienko = ret[i];
- index = i;
- break;
- }
- }
- if (naslo) break;
- }
- if (znamienko == 'N') return ZLY_VYRAZ; // nenaslo znamienko, zly vyraz
- int cis1Z = 1;
- int cis2Z = 1;
- cis1 = ret.substr(0, index);
- cis2 = ret.substr(index+1);
- // teraz zistime ci su zaporne a spravne zadane
- if (cis1[0] == '-') {
- cis1Z *= -1;
- cis1 = cis1.substr(1);
- }
- if (cis2[0] == '-') {
- cis2Z *= -1;
- cis2 = cis2.substr(1);
- }
- // skontroluj spravnost cisiel
- for (unsigned int i = 0; i < cis1.length(); i++) {
- naslo = false;
- for (unsigned int j = 0; j < povoleneZnaky.length(); j++) {
- if (cis1[i] == povoleneZnaky[j]) {
- naslo = true;
- break;
- }
- }
- if (naslo == false) return ZLY_VYRAZ;
- }
- for (unsigned int i = 0; i < cis2.length(); i++) {
- naslo = false;
- for (unsigned int j = 0; j < povoleneZnaky.length(); j++) {
- if (cis2[i] == povoleneZnaky[j]) {
- naslo = true;
- break;
- }
- }
- if (naslo == false) return ZLY_VYRAZ;
- }
- // delenie nulou
- if (cis2 == this->nul && znamienko == '/') return CISLO_MIMO;
- if (cis1 == "" || cis2 == "") return ZLY_VYRAZ;
- MY_LONG rim1 = konverziaRimskych(cis1);
- MY_LONG rim2 = konverziaRimskych(cis2);
- string rim11 = konvertNaRimske(rim1);
- string rim22 = konvertNaRimske(rim2);
- if (rim11 != cis1 || rim22 != cis2) return ZLY_VYRAZ; // VYLEPSIT
- /*if(vyr == "6 + 7") {
- cout << "TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT "<< rim11 + " "<< cis1 + " " <<rim1 << " " << rim22 + " "<< cis2 + " ";
- std::cout<<"Vstup: "<<pismena<<std::endl;
- std::cout<<"RIM"<<std::endl;
- map<char, int>::iterator it;
- for (it = this->rim.begin(); it != this->rim.end(); it++)
- {
- std::cout<<it->first<<" -> "<<it->second<<std::endl;
- }
- std::cout<<"ARAB"<<endl;
- map<int, string>::reverse_iterator rit;
- for (rit = this->arab.rbegin(); rit != this->arab.rend(); rit++)
- {
- std::cout<<rit->first<<" -> "<<rit->second<<std::endl;
- }
- }*/
- int cisloArabske = kalkulackaArabska(znamienko, rim1*cis1Z, rim2*cis2Z); //
- if (cisloArabske < 0) {
- cisloArabske *= -1;
- vystup = konvertNaRimske(cisloArabske);
- if (vystup == CISLO_MIMO) return vystup;
- return "-"+vystup;
- }
- if (cisloArabske > maximumInt())return CISLO_MIMO;
- vystup = konvertNaRimske(cisloArabske);
- if (cisloArabske == 0) return this->nul;
- char last = vystup[0];
- int poc = 1;
- /*for (int i = 1; i < vystup.size(); i++) {
- if (vystup[i] == last) poc++;
- else poc = 0;
- if (poc > 3) return CISLO_MIMO;
- last = vystup[i];
- }*/
- return vystup;
- }
- bool OBECNA_RIMSKA_KALKULACKA::nastavCislice(const string pismena) {
- string spravneZnaky = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
- if (pismena.size() < 2) return DUMMY_BOOL;
- for (int i = 0; i < pismena.size(); i++){
- bool ok = false;
- for (int j = 0; j < spravneZnaky.size(); j++){
- if(pismena[i] == spravneZnaky[j]){ok = true; break;}
- }
- if (!ok) return DUMMY_BOOL;
- }
- //poriesenie opakovania
- for (int i = 0; i < pismena.size()-1; i++){
- for (int j = i+1; j < pismena.size(); j++){
- if(pismena[i] == pismena[j]) return DUMMY_BOOL;
- }
- }
- int pole[] = {0, 1, 5, 10, 50, 100, 500, 1000, 5000, 10000, 50000, 100000, 500000, 1000000, 5000000, 10000000, 50000000, 100000000, 500000000, 1000000000};
- // konverziaRimskych
- this->arab.clear();
- this->rim.clear();
- for(int i = 0; i < pismena.size(); i++){
- this->rim[pismena[i]] = pole[i];
- this->index = i;
- }
- //1 5
- //10 500
- //100 1000
- //map<int, string> valueMap;
- //string pismenafdafsad = "IVXLCDMPQRSTUWYZEFG";
- //this->arab[0] = pismena[0];
- this->nul = pismena[0];
- bool comp = false;
- int jedn = 1;
- int pat = 5;
- int i = 1;
- while (i < pismena.size()){
- this->arab[jedn] = pismena[i]; // 1 10 100 1000 10000 ...
- //if (i+1 >= pismena.size()){this->arab[pat-jedn] = "WTF"; break;} // kontrola mimo str
- this->arab[pat-jedn] = pismena[i]; this->arab[pat-jedn].push_back(pismena[i+1]); // 4 40 400 4000 40000 ...
- this->arab[pat] = pismena[i+1]; // 5 50 500 5000 50000 ...
- //if (i+2 >= pismena.size()){this->arab[jedn*10-jedn] = "WTF"; break;} // kontrola mimo str
- this->arab[jedn*10-jedn] = pismena[i]; this->arab[jedn*10-jedn].push_back(pismena[i+2]); // 9 90 900 9000 90000 ...
- jedn*=10;
- pat*=10;
- i+=2;
- }
- //this->arab[jedn*10] = "WTF";
- return true;
- }
- MY_LONG OBECNA_RIMSKA_KALKULACKA::konverziaRimskych(const string &rimskeCislo) {
- MY_LONG res = 0;
- for (unsigned int i = 0; i < rimskeCislo.size() - 1; ++i)
- {
- if (this->rim[rimskeCislo[i]] < this->rim[rimskeCislo[i+1]])
- res -= this->rim[rimskeCislo[i]];
- else
- res += this->rim[rimskeCislo[i]];
- }
- res += this->rim[rimskeCislo[rimskeCislo.size()-1]];
- return res;
- }
- string OBECNA_RIMSKA_KALKULACKA::konvertNaRimske(MY_LONG cislo)
- {
- if (cislo == 0) return this->nul;
- //1 5
- //10 500
- //100 1000
- // vysledok
- string romanResult = "";
- map<int, string>::reverse_iterator it;
- int posledne_prechodne;
- for (it = this->arab.rbegin(); it != this->arab.rend(); it++)
- {
- //if current number is greater than current key in list
- //add the value corresponded with key to result
- //then subtract the equivalent int value from current number
- int poc = 0;
- int last = 0;
- while (cislo >= it->first)
- {
- //if (it->second == "WTF") return CISLO_MIMO;
- //if (it->first == 1 && poc >= 2) return CISLO_MIMO;
- //else if(it->first == last && poc >= 1) return CISLO_MIMO;
- //if (it->first == last && it->first % 2 != 0) poc ++;
- //else poc = 0;
- romanResult = romanResult + it->second;
- cislo = cislo - it->first;
- last = it->first;
- }
- }
- return romanResult;
- }
- //3. uloha
- string OBECNA_RIMSKA_KALKULACKA::maximum() {
- return "";
- MY_LONG pole[] = {0, 1, 5, 10, 50, 100, 500, 1000, 5000, 10000, 50000, 100000, 500000, 1000000, 5000000, 10000000, 50000000, 100000000, 500000000, 1000000000};
- MY_LONG maxValue;
- // oOStrStream << pole[this->index];
- unsigned int index = this->rim.size();
- stringstream ss;
- ss << pole[index];
- string hodnota = ss.str();
- // string hodnota = oOStrStream.str();
- char ch = hodnota[0];
- if (ch == '5') {
- maxValue =
- 2 - pole[index-1] *2;
- } else {
- maxValue = pole[index] * 4 - 1;
- }
- return konvertNaRimske(maxValue);
- }
- MY_LONG OBECNA_RIMSKA_KALKULACKA::maximumInt() {
- MY_LONG pole[] = {1, 5, 10, 50, 100, 500, 1000, 5000, 10000, 50000, 100000, 500000, 1000000, 5000000, 10000000, 50000000, 100000000, 500000000, 1000000000};
- MY_LONG maxValue;
- // oOStrStream << pole[this->index];
- unsigned int index = this->rim.size();
- stringstream ss;
- ss << pole[index];
- string hodnota = ss.str();
- // string hodnota = oOStrStream.str();
- char ch = hodnota[0];
- if (ch == '5') {
- maxValue =
- 2 - pole[index-1] *2;
- } else {
- maxValue = pole[index] * 4 - 1;
- }
- return maxValue;
- }
- string OBECNA_RIMSKA_KALKULACKA::minimum() {
- return '-' + maximum();
- }
- //4. uloha
- void OBECNA_RIMSKA_KALKULACKA::zakazNulu() {
- }
- void OBECNA_RIMSKA_KALKULACKA::povolNulu() {
- }
- //5. uloha
- int OBECNA_RIMSKA_KALKULACKA::pocetCislic() {
- return DUMMY_INT;
- }
- string OBECNA_RIMSKA_KALKULACKA::zoznamCislic() {
- return DUMMY_STRING;
- }
- bool OBECNA_RIMSKA_KALKULACKA::rozsirZoznamCislic(const string novePismena) {
- return DUMMY_BOOL;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement