Advertisement
Guest User

Untitled

a guest
Jun 30th, 2015
207
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 16.60 KB | None | 0 0
  1. #include <iostream>
  2. #include <sstream>
  3. #include <string>
  4. #include <map>
  5.  
  6. using namespace std;
  7.  
  8. //#include "riesenie.h"
  9.  
  10. #if !defined( _RIESENIE_H_ )
  11. #define _RIESENIE_H_
  12. #ifdef _WIN32
  13. typedef __int64 MY_LONG;
  14. #endif
  15. #ifndef _WIN32
  16. typedef long long MY_LONG;
  17. #endif
  18.  
  19. class RIMSKA_KALKULACKA {
  20. protected:
  21.  
  22. virtual MY_LONG konverziaRimskych(const string &rimskeCislo);
  23. virtual string konvertNaRimske(MY_LONG cislo);
  24.  
  25. int kalkulackaArabska(char oper, MY_LONG op1, MY_LONG op2);
  26.  
  27. public:
  28. virtual string kalkulackaRimska(const string &vyraz);
  29. RIMSKA_KALKULACKA(const string &pismena = "OIVXLCDMPQRSTUWYZEFG");
  30.  
  31. string pismena;
  32. private:
  33.  
  34. };
  35. class OBECNA_RIMSKA_KALKULACKA : public RIMSKA_KALKULACKA {
  36. public:
  37. //2. uloha
  38. bool nastavCislice(const string pismena);
  39. MY_LONG konverziaRimskych(const string &rimskeCislo);
  40. string konvertNaRimske(MY_LONG cislo);
  41. string kalkulackaRimska(const string &vyraz);
  42. MY_LONG maximumInt();
  43. //3. uloha
  44. string maximum();
  45. string minimum();
  46. //4. uloha
  47. void zakazNulu();
  48. void povolNulu();
  49. //5. uloha
  50. int pocetCislic();
  51. string zoznamCislic();
  52. bool rozsirZoznamCislic(const string novePismena);
  53. private:
  54. int index;
  55. MY_LONG nasl;
  56. string nul;
  57. bool nula;
  58. map<char, int> rim;
  59. map<int, std::string> arab;
  60. };
  61. const string CISLO_MIMO = "Cislo mimo povolenych hodnot";
  62. const string ZLY_VYRAZ = "Zly vstupny vyraz";
  63.  
  64. const bool DUMMY_BOOL = false;
  65. const int DUMMY_INT = 0;
  66. const string DUMMY_STRING = "";
  67.  
  68. #endif
  69.  
  70. string RIMSKA_KALKULACKA::kalkulackaRimska(const string &vyr) {
  71. string vystup;
  72. string cis1 = "";
  73. string cis2 = "";
  74.  
  75. string povoleneZnaky = "OIVXLCDMPQRSTUWYZEFG";
  76. string povoleneZnamienka = "*-+/&|><=";
  77. string ret = "";
  78.  
  79. // odstranenie medzier
  80. for (unsigned int i = 0; i < vyr.length(); i++) {
  81. if (vyr[i] != ' ') ret += vyr[i];
  82. }
  83.  
  84. // rozdelenie na cisla + znamienko, zatial nevieme ci spravne
  85. bool naslo = false;
  86. char znamienko = 'N';
  87. int index;
  88. for (unsigned int i = 1; i < ret.length(); i++) {
  89. for (unsigned int j = 0; j < povoleneZnamienka.length(); j++) {
  90. if (ret[i] == povoleneZnamienka[j]) {
  91. naslo = true;
  92. znamienko = ret[i];
  93. index = i;
  94. break;
  95. }
  96. }
  97. if (naslo) break;
  98. }
  99. if (znamienko == 'N') return ZLY_VYRAZ; // nenaslo znamienko, zly vyraz
  100. int cis1Z = 1;
  101. int cis2Z = 1;
  102. cis1 = ret.substr(0, index);
  103. cis2 = ret.substr(index+1);
  104.  
  105. // teraz zistime ci su zaporne a spravne zadane
  106. if (cis1[0] == '-') {
  107. cis1Z *= -1;
  108. cis1 = cis1.substr(1);
  109. }
  110. if (cis2[0] == '-') {
  111. cis2Z *= -1;
  112. cis2 = cis2.substr(1);
  113. }
  114.  
  115. // skontroluj spravnost cisiel
  116. for (unsigned int i = 0; i < cis1.length(); i++) {
  117. naslo = false;
  118. for (unsigned int j = 0; j < povoleneZnaky.length(); j++) {
  119. if (cis1[i] == povoleneZnaky[j]) {
  120. naslo = true;
  121. break;
  122. }
  123.  
  124. }
  125. if (naslo == false) return ZLY_VYRAZ;
  126. }
  127. for (unsigned int i = 0; i < cis2.length(); i++) {
  128. naslo = false;
  129. for (unsigned int j = 0; j < povoleneZnaky.length(); j++) {
  130. if (cis2[i] == povoleneZnaky[j]) {
  131. naslo = true;
  132. break;
  133. }
  134.  
  135. }
  136. if (naslo == false) return ZLY_VYRAZ;
  137. }
  138.  
  139. // delenie nulou
  140. if (cis2 == "O" && znamienko == '/') return CISLO_MIMO;
  141. if (cis1 == "" || cis2 == "") return ZLY_VYRAZ;
  142.  
  143. MY_LONG rim1 = konverziaRimskych(cis1);
  144. MY_LONG rim2 = konverziaRimskych(cis2);
  145. string rim11 = konvertNaRimske(rim1);
  146. string rim22 = konvertNaRimske(rim2);
  147.  
  148. if (rim11 != cis1 || rim22 != cis2) return ZLY_VYRAZ; // VYLEPSIT
  149.  
  150. int cisloArabske = kalkulackaArabska(znamienko, rim1*cis1Z, rim2*cis2Z); //
  151. if (cisloArabske < 0) {
  152. cisloArabske *= -1;
  153. vystup = konvertNaRimske(cisloArabske);
  154. return "-"+vystup;
  155. }
  156.  
  157. vystup = konvertNaRimske(cisloArabske);
  158.  
  159. // cout << "" << vystup << "\n";
  160.  
  161. return vystup;
  162. }
  163. MY_LONG RIMSKA_KALKULACKA::konverziaRimskych(const string &rimskeCislo) {
  164.  
  165. // const char* s = rimskeCislo.c_str();
  166. // int x = 0; // result
  167. //
  168. // int j, m = 0; // max used digit
  169. // const char* p = s, *q; while (*p) ++p;
  170. // for (--p; p >= s; p--) for (q = "IVXLCDMPQRSTUWYZEFG", j = 0; *q; q++, j++) if (*p == *q)
  171. // x += ((j >= m) ? m = j, 1 : -1) * (1 + j % 4 / 2 * 9) * (1 + j / 4 * 99) * (1 + j % 2 * 4);
  172. // return x;
  173.  
  174. map<char, int> roman;
  175. roman['G'] = 1000000000;
  176. roman['F'] = 500000000;
  177. roman['E'] = 100000000;
  178. roman['Z'] = 50000000;
  179. roman['Y'] = 10000000;
  180. roman['W'] = 5000000;
  181. roman['U'] = 1000000;
  182. roman['T'] = 500000;
  183. roman['S'] = 100000;
  184. roman['R'] = 50000;
  185. roman['Q'] = 10000;
  186. roman['P'] = 5000;
  187. roman['M'] = 1000;
  188. roman['D'] = 500;
  189. roman['C'] = 100;
  190. roman['L'] = 50;
  191. roman['X'] = 10;
  192. roman['V'] = 5;
  193. roman['I'] = 1;
  194. roman['O'] = 0;
  195.  
  196. MY_LONG res = 0;
  197. for (unsigned int i = 0; i < rimskeCislo.size() - 1; ++i)
  198. {
  199. if (roman[rimskeCislo[i]] < roman[rimskeCislo[i+1]])
  200. res -= roman[rimskeCislo[i]];
  201. else
  202. res += roman[rimskeCislo[i]];
  203. }
  204. res += roman[rimskeCislo[rimskeCislo.size()-1]];
  205.  
  206. return res;
  207. }
  208.  
  209. string RIMSKA_KALKULACKA::konvertNaRimske(MY_LONG cislo)
  210. {
  211. if (cislo == 0) return "O";
  212. //1 5
  213. //10 500
  214. //100 1000
  215. map<int, string> valueMap;
  216. string pismena = "IVXLCDMPQRSTUWYZEFG";
  217. valueMap[1] = "I";
  218. valueMap[4] = "IV";
  219. valueMap[5] = "V";
  220. valueMap[9] = "IX";
  221. valueMap[10] = "X";
  222. valueMap[40] = "XL";
  223. valueMap[50] = "L";
  224. valueMap[90] = "XC";
  225. valueMap[100] = "C";
  226. valueMap[400] = "CD";
  227. valueMap[500] = "D";
  228. valueMap[900] = "CM";
  229. valueMap[1000] = "M";
  230. valueMap[4000] = "MP";
  231. valueMap[5000] = "P";
  232. valueMap[9000] = "MQ";
  233. valueMap[10000] = "Q";
  234. valueMap[40000] = "QR";
  235. valueMap[50000] = "R";
  236. valueMap[90000] = "QS";
  237. valueMap[100000] = "S";
  238. valueMap[400000] = "ST";
  239. valueMap[500000] = "T";
  240. valueMap[900000] = "SU";
  241. valueMap[1000000] = "U";
  242. valueMap[4000000] = "UW";
  243. valueMap[5000000] = "W";
  244. valueMap[9000000] = "UY";
  245. valueMap[10000000] = "Y";
  246. valueMap[40000000] = "YZ";
  247. valueMap[50000000] = "Z";
  248. valueMap[90000000] = "YE";
  249. valueMap[100000000] = "E";
  250. valueMap[400000000] = "EF";
  251. valueMap[500000000] = "F";
  252. valueMap[900000000] = "EG";
  253. valueMap[1000000000] = "G";
  254.  
  255. // vysledok
  256. string romanResult = "";
  257.  
  258. map<int, string>::reverse_iterator it;
  259.  
  260. for (it = valueMap.rbegin(); it != valueMap.rend(); it++)
  261. {
  262. //if current number is greater than current key in list
  263. //add the value corresponded with key to result
  264. //then subtract the equivalent int value from current number
  265. while (cislo >= it->first)
  266. {
  267. romanResult = romanResult + it->second;
  268. cislo = cislo - it->first;
  269. }
  270. }
  271.  
  272. return romanResult;
  273. }
  274.  
  275. int RIMSKA_KALKULACKA::kalkulackaArabska(char oper, MY_LONG op1, MY_LONG op2) {
  276. switch(oper){
  277. case '+': return op1 + op2;
  278. case '-': return op1 - op2;
  279. case '*': return op1 * op2;
  280. case '/': return op1 / op2;
  281. case '>': {
  282. if (op1 > op2)
  283. return 1;
  284. else return 0;
  285. }
  286. case '<': {
  287. if (op1 < op2)
  288. return 1;
  289. else
  290. return 0;
  291. }
  292. case '=': {
  293. if (op1 == op2)
  294. return 1;
  295. else return 0;
  296. }
  297. case '&': {
  298. if (op1 == 0 || op2 == 0) return 0;
  299. else return 1;
  300. }
  301. case '|': {
  302. if (op1 == 0 && op2 == 0) return 0;
  303. }
  304. default: return 1;
  305. };
  306. }
  307.  
  308. RIMSKA_KALKULACKA::RIMSKA_KALKULACKA(const string &pismena) {
  309. this->pismena = pismena;
  310. }
  311. //2. uloha
  312. string OBECNA_RIMSKA_KALKULACKA::kalkulackaRimska(const string &vyr) {
  313. string vystup;
  314. string cis1 = "";
  315. string cis2 = "";
  316.  
  317. string povoleneZnaky = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
  318. string povoleneZnamienka = "*-+/&|><=";
  319. string ret = "";
  320.  
  321. // odstranenie medzier
  322. for (unsigned int i = 0; i < vyr.length(); i++) {
  323. if (vyr[i] != ' ') ret += vyr[i];
  324. }
  325.  
  326. // rozdelenie na cisla + znamienko, zatial nevieme ci spravne
  327. bool naslo = false;
  328. char znamienko = 'N';
  329. int index;
  330. for (unsigned int i = 1; i < ret.length(); i++) {
  331. for (unsigned int j = 0; j < povoleneZnamienka.length(); j++) {
  332. if (ret[i] == povoleneZnamienka[j]) {
  333. naslo = true;
  334. znamienko = ret[i];
  335. index = i;
  336. break;
  337. }
  338. }
  339. if (naslo) break;
  340. }
  341. if (znamienko == 'N') return ZLY_VYRAZ; // nenaslo znamienko, zly vyraz
  342. int cis1Z = 1;
  343. int cis2Z = 1;
  344. cis1 = ret.substr(0, index);
  345. cis2 = ret.substr(index+1);
  346.  
  347.  
  348. // teraz zistime ci su zaporne a spravne zadane
  349. if (cis1[0] == '-') {
  350. cis1Z *= -1;
  351. cis1 = cis1.substr(1);
  352. }
  353. if (cis2[0] == '-') {
  354. cis2Z *= -1;
  355. cis2 = cis2.substr(1);
  356. }
  357.  
  358. // skontroluj spravnost cisiel
  359. for (unsigned int i = 0; i < cis1.length(); i++) {
  360. naslo = false;
  361. for (unsigned int j = 0; j < povoleneZnaky.length(); j++) {
  362. if (cis1[i] == povoleneZnaky[j]) {
  363. naslo = true;
  364. break;
  365. }
  366.  
  367. }
  368. if (naslo == false) return ZLY_VYRAZ;
  369. }
  370. for (unsigned int i = 0; i < cis2.length(); i++) {
  371. naslo = false;
  372. for (unsigned int j = 0; j < povoleneZnaky.length(); j++) {
  373. if (cis2[i] == povoleneZnaky[j]) {
  374. naslo = true;
  375. break;
  376. }
  377.  
  378. }
  379. if (naslo == false) return ZLY_VYRAZ;
  380. }
  381.  
  382. // delenie nulou
  383. if (cis2 == this->nul && znamienko == '/') return CISLO_MIMO;
  384. if (cis1 == "" || cis2 == "") return ZLY_VYRAZ;
  385.  
  386. MY_LONG rim1 = konverziaRimskych(cis1);
  387. MY_LONG rim2 = konverziaRimskych(cis2);
  388. string rim11 = konvertNaRimske(rim1);
  389. string rim22 = konvertNaRimske(rim2);
  390.  
  391. if (rim11 != cis1 || rim22 != cis2) return ZLY_VYRAZ; // VYLEPSIT
  392. /*if(vyr == "6 + 7") {
  393. cout << "TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT "<< rim11 + " "<< cis1 + " " <<rim1 << " " << rim22 + " "<< cis2 + " ";
  394. std::cout<<"Vstup: "<<pismena<<std::endl;
  395. std::cout<<"RIM"<<std::endl;
  396. map<char, int>::iterator it;
  397. for (it = this->rim.begin(); it != this->rim.end(); it++)
  398. {
  399. std::cout<<it->first<<" -> "<<it->second<<std::endl;
  400. }
  401. std::cout<<"ARAB"<<endl;
  402. map<int, string>::reverse_iterator rit;
  403.  
  404. for (rit = this->arab.rbegin(); rit != this->arab.rend(); rit++)
  405. {
  406. std::cout<<rit->first<<" -> "<<rit->second<<std::endl;
  407. }
  408. }*/
  409.  
  410. int cisloArabske = kalkulackaArabska(znamienko, rim1*cis1Z, rim2*cis2Z); //
  411. if (cisloArabske < 0) {
  412. cisloArabske *= -1;
  413. vystup = konvertNaRimske(cisloArabske);
  414. if (vystup == CISLO_MIMO) return vystup;
  415. return "-"+vystup;
  416. }
  417. if (cisloArabske > maximumInt())return CISLO_MIMO;
  418. vystup = konvertNaRimske(cisloArabske);
  419. if (cisloArabske == 0) return this->nul;
  420. char last = vystup[0];
  421. int poc = 1;
  422. /*for (int i = 1; i < vystup.size(); i++) {
  423. if (vystup[i] == last) poc++;
  424. else poc = 0;
  425. if (poc > 3) return CISLO_MIMO;
  426. last = vystup[i];
  427. }*/
  428.  
  429. return vystup;
  430. }
  431.  
  432. bool OBECNA_RIMSKA_KALKULACKA::nastavCislice(const string pismena) {
  433. string spravneZnaky = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
  434. if (pismena.size() < 2) return DUMMY_BOOL;
  435. for (int i = 0; i < pismena.size(); i++){
  436. bool ok = false;
  437. for (int j = 0; j < spravneZnaky.size(); j++){
  438. if(pismena[i] == spravneZnaky[j]){ok = true; break;}
  439. }
  440. if (!ok) return DUMMY_BOOL;
  441. }
  442. //poriesenie opakovania
  443. for (int i = 0; i < pismena.size()-1; i++){
  444. for (int j = i+1; j < pismena.size(); j++){
  445. if(pismena[i] == pismena[j]) return DUMMY_BOOL;
  446. }
  447. }
  448. int pole[] = {0, 1, 5, 10, 50, 100, 500, 1000, 5000, 10000, 50000, 100000, 500000, 1000000, 5000000, 10000000, 50000000, 100000000, 500000000, 1000000000};
  449.  
  450. // konverziaRimskych
  451. this->arab.clear();
  452. this->rim.clear();
  453. for(int i = 0; i < pismena.size(); i++){
  454. this->rim[pismena[i]] = pole[i];
  455. this->index = i;
  456. }
  457.  
  458. //1 5
  459. //10 500
  460. //100 1000
  461. //map<int, string> valueMap;
  462. //string pismenafdafsad = "IVXLCDMPQRSTUWYZEFG";
  463. //this->arab[0] = pismena[0];
  464. this->nul = pismena[0];
  465. bool comp = false;
  466. int jedn = 1;
  467. int pat = 5;
  468. int i = 1;
  469. while (i < pismena.size()){
  470. this->arab[jedn] = pismena[i]; // 1 10 100 1000 10000 ...
  471. //if (i+1 >= pismena.size()){this->arab[pat-jedn] = "WTF"; break;} // kontrola mimo str
  472. this->arab[pat-jedn] = pismena[i]; this->arab[pat-jedn].push_back(pismena[i+1]); // 4 40 400 4000 40000 ...
  473. this->arab[pat] = pismena[i+1]; // 5 50 500 5000 50000 ...
  474. //if (i+2 >= pismena.size()){this->arab[jedn*10-jedn] = "WTF"; break;} // kontrola mimo str
  475. this->arab[jedn*10-jedn] = pismena[i]; this->arab[jedn*10-jedn].push_back(pismena[i+2]); // 9 90 900 9000 90000 ...
  476. jedn*=10;
  477. pat*=10;
  478. i+=2;
  479. }
  480. //this->arab[jedn*10] = "WTF";
  481.  
  482.  
  483.  
  484.  
  485.  
  486. return true;
  487. }
  488. MY_LONG OBECNA_RIMSKA_KALKULACKA::konverziaRimskych(const string &rimskeCislo) {
  489.  
  490. MY_LONG res = 0;
  491. for (unsigned int i = 0; i < rimskeCislo.size() - 1; ++i)
  492. {
  493. if (this->rim[rimskeCislo[i]] < this->rim[rimskeCislo[i+1]])
  494. res -= this->rim[rimskeCislo[i]];
  495. else
  496. res += this->rim[rimskeCislo[i]];
  497. }
  498. res += this->rim[rimskeCislo[rimskeCislo.size()-1]];
  499.  
  500. return res;
  501. }
  502.  
  503. string OBECNA_RIMSKA_KALKULACKA::konvertNaRimske(MY_LONG cislo)
  504. {
  505. if (cislo == 0) return this->nul;
  506. //1 5
  507. //10 500
  508. //100 1000
  509.  
  510. // vysledok
  511. string romanResult = "";
  512.  
  513. map<int, string>::reverse_iterator it;
  514. int posledne_prechodne;
  515. for (it = this->arab.rbegin(); it != this->arab.rend(); it++)
  516. {
  517. //if current number is greater than current key in list
  518. //add the value corresponded with key to result
  519. //then subtract the equivalent int value from current number
  520. int poc = 0;
  521. int last = 0;
  522. while (cislo >= it->first)
  523. {
  524. //if (it->second == "WTF") return CISLO_MIMO;
  525. //if (it->first == 1 && poc >= 2) return CISLO_MIMO;
  526. //else if(it->first == last && poc >= 1) return CISLO_MIMO;
  527. //if (it->first == last && it->first % 2 != 0) poc ++;
  528. //else poc = 0;
  529. romanResult = romanResult + it->second;
  530. cislo = cislo - it->first;
  531. last = it->first;
  532. }
  533. }
  534.  
  535. return romanResult;
  536. }
  537. //3. uloha
  538. string OBECNA_RIMSKA_KALKULACKA::maximum() {
  539. return "";
  540. MY_LONG pole[] = {0, 1, 5, 10, 50, 100, 500, 1000, 5000, 10000, 50000, 100000, 500000, 1000000, 5000000, 10000000, 50000000, 100000000, 500000000, 1000000000};
  541. MY_LONG maxValue;
  542. // oOStrStream << pole[this->index];
  543. unsigned int index = this->rim.size();
  544. stringstream ss;
  545. ss << pole[index];
  546. string hodnota = ss.str();
  547.  
  548.  
  549. // string hodnota = oOStrStream.str();
  550. char ch = hodnota[0];
  551. if (ch == '5') {
  552. maxValue =
  553. 2 - pole[index-1] *2;
  554. } else {
  555. maxValue = pole[index] * 4 - 1;
  556. }
  557. return konvertNaRimske(maxValue);
  558.  
  559. }
  560.  
  561. MY_LONG OBECNA_RIMSKA_KALKULACKA::maximumInt() {
  562. MY_LONG pole[] = {1, 5, 10, 50, 100, 500, 1000, 5000, 10000, 50000, 100000, 500000, 1000000, 5000000, 10000000, 50000000, 100000000, 500000000, 1000000000};
  563. MY_LONG maxValue;
  564. // oOStrStream << pole[this->index];
  565. unsigned int index = this->rim.size();
  566. stringstream ss;
  567. ss << pole[index];
  568. string hodnota = ss.str();
  569.  
  570. // string hodnota = oOStrStream.str();
  571. char ch = hodnota[0];
  572. if (ch == '5') {
  573. maxValue =
  574. 2 - pole[index-1] *2;
  575. } else {
  576. maxValue = pole[index] * 4 - 1;
  577. }
  578. return maxValue;
  579.  
  580.  
  581. }
  582.  
  583. string OBECNA_RIMSKA_KALKULACKA::minimum() {
  584. return '-' + maximum();
  585. }
  586. //4. uloha
  587. void OBECNA_RIMSKA_KALKULACKA::zakazNulu() {
  588. }
  589. void OBECNA_RIMSKA_KALKULACKA::povolNulu() {
  590. }
  591. //5. uloha
  592. int OBECNA_RIMSKA_KALKULACKA::pocetCislic() {
  593. return DUMMY_INT;
  594. }
  595. string OBECNA_RIMSKA_KALKULACKA::zoznamCislic() {
  596. return DUMMY_STRING;
  597. }
  598. bool OBECNA_RIMSKA_KALKULACKA::rozsirZoznamCislic(const string novePismena) {
  599. return DUMMY_BOOL;
  600. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement