Advertisement
a53

STIVA

a53
Oct 15th, 2017
129
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.71 KB | None | 0 0
  1. #pragma warning(disable:4786)
  2. #include <deque>
  3. #include <iostream>
  4. #include <string>
  5. using namespace std;
  6. #include "ierarhie.h"
  7. #include "stiva.h"
  8. #include "fisier.h"
  9. #include "coada.h"
  10. ///Variabile globale
  11. fisier f;
  12. stiva <char> OPER;
  13. stiva <double> EVAL;
  14. coada POSTFIX;
  15. void eroare(const char * text,int nr){
  16. cout<<"\n"<<text<<"\n";
  17. exit(nr);
  18. }
  19. void scrierePOSTFIX(string &op)
  20. {
  21. char opc;
  22. if(op=="")
  23. return;
  24. int ierOp=ierarhie(op);
  25. ///daca e valoare, se trece direct in scrierea postfixata
  26. if(!ierOp)
  27. POSTFIX.adauga(op);
  28. else
  29. {
  30. opc=op[0];
  31. switch(ierOp)
  32. { ///daca e paranteza deschisa, se introduce pe stiva
  33. case PD: //([{
  34. OPER.push(opc);
  35. break;
  36. ///daca e paranteza inchisa, se extrag toate elementele
  37. ///de pe stiva pana la intalnirea unei paranteze deschise
  38. case PI: //)]}
  39. while(ierarhie(OPER.top())!=PD)
  40. POSTFIX.adauga(OPER.pop());
  41. OPER.pop();
  42. break;
  43. ///daca e alt operator, se extrag elemente de pe stiva atat
  44. ///timp cat stiva nu este goala si ierarhia operatorului
  45. ///din varful stivei este mai mare sau egala decat ierahia
  46. ///operatorului curent
  47. ///la sfarsit operatorul curent se depune pe stiva
  48. default:
  49.  
  50. while((!OPER.eGoala())&&ierarhie(OPER.top())>=ierOp)
  51. POSTFIX.adauga(OPER.pop());
  52. OPER.push(opc);
  53. break;
  54. }
  55. }
  56. }
  57. void evalPOSTFIX()
  58. {
  59. string op;
  60. char opc;
  61. double t1, t2, rez;
  62. ///atat timp cat nu s-a ajuns la sfarsitul expresiei postfixate
  63. while(!POSTFIX.eGoala())
  64. {
  65. ///daca elementul curent este numar acesta se depune pe stiva
  66. while(POSTFIX.eNumar())
  67. EVAL.push(POSTFIX.getNumar());
  68. //se extrag 2 valori de pe stiva
  69. t2=EVAL.pop();
  70. t1=EVAL.pop();
  71. op=POSTFIX.extrage();
  72. opc=op[0];
  73. ///se efectueaza operatia dintre cele 2 valori
  74. switch(opc)
  75. {
  76. case '+':
  77. rez=t1+t2;
  78. break;
  79. case '-':
  80. rez=t1-t2;
  81. break;
  82. case '*':
  83. rez=t1*t2;
  84. break;
  85. case '/':
  86. rez=t1/t2;
  87. break;
  88. default:
  89. eroare("Operator necunoscut!", 1);
  90. }
  91. ///rezultatul operatiei se depune pe stiva
  92. EVAL.push(rez);
  93. }
  94. }
  95. void main(int argc, char* argv[])
  96. {
  97. ///se primeste ca parametru numele fisierului in care se
  98. ///gaseste expresia matematica ce se doreste a fi evaluata
  99. string numefis;
  100. if(argc!=2)
  101. { cout<<"Specificati numele unui fisier pentru care doriti
  102. scrierea postfixata!";
  103. exit(1);
  104. }
  105. numefis=argv[1];
  106.  
  107. f.open(numefis.c_str());
  108. if(f.bad())
  109. {
  110. cout<<"Fisierul "<<numefis<<" nu exista.\n";
  111. exit(2);
  112. }
  113.  
  114. cout<<"Lucrez cu fisierul "<<numefis<<".\n";
  115.  
  116. ///parcurge fisierul primit ca parametru
  117. string op;
  118. while(!f.eof())
  119. {
  120. op=f.citeste();
  121. scrierePOSTFIX(op);
  122. }
  123. f.close();
  124. ///se extrag toti operatorii ramasi pe stiva
  125. while(!OPER.eGoala())
  126. POSTFIX.adauga(OPER.pop());
  127. ///afiseaza expresia din fisier in forma postfixata
  128. cout<<"\n\nExpresia in scriere postfixata\n";
  129. for(int i=0;i<POSTFIX.size();i++)
  130. cout<<POSTFIX[i]<<" ";
  131. ///efectueaza calculul expresiei
  132. evalPOSTFIX();
  133. ///afiseaza valoarea expresiei (ultima valoare ramasa pe stiva)
  134. cout<<"\nValoarea expresiei este: "<<EVAL.pop()<<"\n";
  135. }
  136. ///ierarhie.h - informatii despre ierarhia operatorilor
  137. #define PD 1
  138. #define PI 2
  139. #define PLUSMINUS 3
  140. #define INMIMP 4
  141. int ierarhie(char c)
  142. {
  143. switch (c)
  144. {
  145. case '+':
  146. case '-':
  147. return PLUSMINUS;
  148. break;
  149. case '*':
  150. case '/':
  151. return INMIMP;
  152. break;
  153. case '(':
  154. case '[':
  155. case '{':
  156. return PD;
  157. break;
  158. case ')':
  159. case ']':
  160. case '}':
  161. return PI;
  162. break;
  163. default:
  164. return 0;
  165. break;
  166. }
  167. };
  168. int ierarhie(string & s)
  169. {
  170. char c;
  171. c=s[0];
  172. return ierarhie(c);
  173. };
  174. ///coada.h - Clasa coada
  175. void eroare(const char * text,int nr);
  176. class coada{
  177. private:
  178. ///implementarea cozii cu o clasa template double ended que din
  179. ///C++ Standard Template Library
  180. deque <string> s;
  181. public:
  182. ///verifica daca coada e goala
  183. bool eGoala()
  184. {
  185. return s.empty();
  186. };
  187. ///adauga un element in coada
  188. void adauga(const string & str)
  189. {
  190. s.push_back(str);
  191. };
  192. ///adauga un element in coada
  193. void adauga(char c)
  194. {
  195. string str;
  196. str=c;
  197. s.push_back(str);
  198. };
  199. ///intoarce si extrage primul element din coada
  200. string extrage()
  201. {
  202. string t;
  203. if(!s.empty())
  204. {
  205. t=s.front();
  206. s.pop_front();
  207. }
  208. else eroare("Eroare de sintaxa.",2);
  209. return t;
  210. };
  211. ///verifica daca primul element din coada reprezinta un numar
  212. bool eNumar()
  213. {
  214. char *stop;
  215. string st=s.front();
  216. strtod(st.c_str(), &stop);
  217. return (*stop) == 0;
  218. };
  219. ///extrage elementul din coada ca numar
  220. double getNumar()
  221. {
  222. char *stop;
  223. double v;
  224. string st;
  225. st=s.front();
  226. s.pop_front();
  227. v=strtod(st.c_str(), &stop);
  228. return v;
  229. };
  230. ///intoarce a i-lea element din coada (0 - primul element)
  231. string operator [] (unsigned int i)
  232. {
  233. if((i>=0) && (i<s.size()))
  234. return s[i];
  235. eroare("Eroare de sintaxa.",4);
  236. return "";
  237. };
  238. ///intoarce numarul de elemente din coada
  239. int size()
  240. {
  241. return s.size();
  242. };
  243. };
  244. ///stiva.h - Clasa template stiva
  245. void eroare(const char * text,int nr);
  246. template <class T>
  247. class stiva{
  248. private:
  249. ///implementarea stivei cu o clasa template double ended que din
  250. ///C++ Standard Template Library
  251. deque <T> s;
  252. public:
  253. ///verifica daca stiva e goala
  254. bool eGoala()
  255. {
  256. return s.empty();
  257. };
  258. ///introduce un element in stiva
  259. void push(T str)
  260. {
  261. s.push_back(str);
  262. };
  263. ///intoarce si extrage elementul din stiva
  264. T pop()
  265. {
  266. T t;
  267. if(!s.empty())
  268. {
  269. t=s.back();
  270. s.pop_back();
  271. }
  272. else eroare("Eroare de sintaxa.",5);
  273. return t;
  274. };
  275. ///intoarce elementul din stiva
  276. T top()
  277. {
  278. if (!s.empty())
  279. return s.back();
  280. eroare("Eroare de sintaxa.",6);
  281. return NULL;
  282. };
  283. };
  284. ///fisier.h - clasa fisier
  285. #include <string>
  286. #include <fstream>
  287. using namespace std;
  288. class fisier
  289. {
  290. public:
  291. ///citeste o noua secventa de caractere din fisierul de date
  292. string citeste();
  293. ///deschide fisierul
  294. void open(const char * numefis);
  295. ///verifica daca fisierul a fost deschis cu succes
  296. bool bad();
  297. ///verifica daca s-a ajuns la sfarsitul fisierului
  298. bool eof();
  299. ///inchide fisierul deschis
  300. void close();
  301. private:
  302. /// fisierul din care se citesc datele
  303. ifstream fis;
  304. /// verifica daca parametrul primit este separator sau operator
  305. bool isSeparator(string s);
  306. /// verifica daca parametrul primit este separator sau operator
  307. bool isSeparator(char c);
  308. ///scoate spatiile albe din datele de intrare (tab, spatiu, sfarsit
  309. de linie)
  310. void eatWhite();
  311. };
  312. ///fisier.cpp - clasa fisier
  313. #include "fisier.h"
  314. /// verifica daca parametrul primit este separator sau operator
  315. bool fisier::isSeparator(string s)
  316. {
  317. char c=s[0];
  318. return (c=='+') || (c=='-') || (c=='*') || (c=='/') || (c=='(') ||
  319. (c=='[') || (c=='{') || (c==')') || (c==']') || (c=='}')
  320. ||
  321. (c=='\n') || (c=='\t') || (c==' ');
  322. };
  323. // verifica daca parametrul primit este separator sau operator
  324. bool fisier::isSeparator(char c)
  325. {
  326. return (c=='+') || (c=='-') || (c=='*') || (c=='/') || (c=='(') ||
  327. (c=='[') || (c=='{') || (c==')') || (c==']') || (c=='}')
  328. ||
  329. (c=='\n') || (c=='\t') || (c==' ');
  330. }
  331. ///scoate spatiile albe din datele de intrare (tab, spatiu, sfarsit de
  332. linie)
  333. void fisier::eatWhite()
  334. {
  335. while((fis.peek()==' ') || (fis.peek()=='\n') ||
  336. (fis.peek()=='\t'))
  337. fis.get();
  338. }
  339. ///citeste o noua secventa de caractere din fisierul de date
  340. string fisier::citeste()
  341. {
  342. string rez="";
  343. rez=fis.get();
  344. if(!isSeparator(rez))
  345. while(!isSeparator(fis.peek()) && !fis.eof())
  346. rez+=fis.get();
  347. eatWhite();
  348.  
  349. return rez;
  350. }
  351. ///deschide fisierul
  352. void fisier::open(const char * numefis)
  353. {
  354. fis.open(numefis);
  355. eatWhite();
  356. }
  357. ///verifica daca fisierul a fost deschis cu succes
  358. bool fisier::bad()
  359. {
  360. return fis.bad();
  361. }
  362. ///verifica daca s-a ajuns la sfarsitul fisierului
  363. bool fisier::eof()
  364. {
  365. return fis.eof();
  366. }
  367. ///inchide fisierul deschis
  368. void fisier::close()
  369. {
  370. fis.close();
  371. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement