Lisans’da 2. sınıftayken geliştirdiğimiz ve benim C++’ı anlamamda çok fazla yardımı olan bir ödevi paylaşıyor olacağım bu yazımda. Bir input dosyasından aldığı eşitliği operatorlerin önceliği ve parantezleri de göz önüne alarak stack ve queue yapılarını kullanarak sonucu başka bir dosyaya yazıyor. Aşağıdaki ekte raporumu da paylaşıyorum ancak en önemli kısma gelirsek o da aşağıda yer almakta. 😉
// At this class, the line which includes the equation is broken into peaces like number, operator parameter* stack_operations::stack_operations_(string line){
cout << line; // write the command line to screen cout << "\n"; parameter *ptr; queue <parameter *> stack_k; // queue to take the peaces of command line
for(int i=0;i<line.length();i++){
if(!isdigit(line[i]) && i>=4){ // if the character is not isdigit String *s = new String(); // create a new pointer from String class s->set_value(line[i]); // set down the value
if(line[i]=='(' || line[i]==')') // if character is parantecis, assign -1 as precedence to control s->set_precedence(-1);
if(line[0]=='p'){ // if the operation will be done as precedence switch(line[i]) { case '+': case '-': s->set_precedence(0); // asssign 0 as precedence,if the operator is + or - break; case '*': case '/': s->set_precedence(1); // assign 1 as precedence, if the operator is * or / break; } } else if(line[0]=='o'){ // if the operation will be done as ordered switch(line[i]) { case '+': case '-': case '*': case '/': s->set_precedence(0); // assign 0 for the all operators break; } } ptr = s; // equal the adresses stack_k.push(ptr); // push to queue } else if(isdigit(line[i]) && line[2]=='n'){ // if character is a normal type number int num=i; // this will keep the start of the isdigit characters Integer *in = new Integer(); // create an object from Integer class while(isdigit(line[i])){ // as long as the line includes digits i++; // increase } string operand (line,num,i-num); // cut the line into string operand in->set_value(atoi(operand.c_str())); // set down the number in->set_precedence(2); // to seperate the numbers from ascii values of operators, i assigned them 2 as precedence ptr=in; // equal the adresses stack_k.push(ptr); // push to queue i--; } else if(isdigit(line[i]) && line[2]=='s'){ // if character is speacialType number int num=i; // this will keep the start of the isdigit characters speacialType *sT = new speacialType(); // create an object from speacialType class while(isdigit(line[i])){ // as long as the line includes digits i++; // increase } string operand (line,num,i-num);// cut the line into string operand sT->set_value(atoi(operand.c_str())); // set down the number sT->set_precedence(2);// to seperate the numbers from ascii values of operators, i assigned them 2 as precedence ptr = sT;// equal the adresses stack_k.push(ptr); // push to queue i--; } }
cout<<"\n"; parameter *num = new parameter(); // this value will be return to menu class num = calculator(stack_k, line[0]); // call the calculator function return num; }
// At this class, the ordering for calculation will be done parameter* stack_operations::calculator(queue <parameter *> stack_k, char ch){
stack <String *> operator_r; // stack for operators queue <parameter *> operands; // queue for ordered equation
while(!stack_k.empty()){ // as long as the queue is no empty
if(stack_k.front()->get_precedence()==2){ // If precedence is 2, it means that it is a number operands.push(stack_k.front()); // push to queue stack_k.pop(); // pop from first queue } // if precedence is 0 or 1, it means that it is a operator else if(stack_k.front()->get_precedence()==0 || stack_k.front()->get_precedence()==1){ if(ch=='p'){ // if chose is precedence // if stack of operators is not empty and top of the precedence is equal or more than to coming's one if(!operator_r.empty() && operator_r.top()->get_precedence() >= stack_k.front()->get_precedence() && operator_r.top()->get_value()!=40){ operands.push(operator_r.top()); // the operator which lays top of the operator stack will be push to ordered queue operator_r.pop(); operator_r.push(dynamic_cast <String *> (stack_k.front())); } // if stack of operators is empty or top of the precedence is less than the coming's one else if (operator_r.empty() || operator_r.top()->get_precedence()<stack_k.front()->get_precedence()) operator_r.push(dynamic_cast <String *> (stack_k.front())); // push the coming operator to stack of operators stack_k.pop(); } else if(ch=='o'){ // if chose id ordered // if stack of operators is empty and precedence of top and coming is equal // i controlled it for the parantecis if(!operator_r.empty() && operator_r.top()->get_precedence()==stack_k.front()->get_precedence()){ operands.push(operator_r.top()); // the operator which lays top of the operator stack will be pushed to ordered queue operator_r.pop(); operator_r.push(dynamic_cast <String *> (stack_k.front())); } // if stack of operators is empty or stack of operator is not empty and the top of the precedence is not equal the coming's one // it means that if there is a parantecis at the stack else if (operator_r.empty() || ( !operator_r.empty() && operator_r.top()->get_precedence()!=stack_k.front()->get_precedence())) operator_r.push(dynamic_cast <String *> (stack_k.front())); // push the coming one to stack stack_k.pop(); }
} // if the coming one is a left paranthesis else if(stack_k.front()->get_value()==40 && stack_k.front()->get_precedence()==-1 ){ operator_r.push(dynamic_cast <String *> (stack_k.front())); // push to stack stack_k.pop(); } // if coming one is a right paranthesis else if(stack_k.front()->get_value()==41 && stack_k.front()->get_precedence()==-1){ stack_k.pop();// pop the operators from stack and push to queue until left paranthesis is found while(operator_r.top()->get_value()!=40){ operands.push(operator_r.top()); operator_r.pop(); if(operator_r.top()->get_value()==40)//ardında 2. bi paranetez varsa break; } operator_r.pop(); } }
// if after all the objects are taken from queue and push to the ordered queue, there are still operators on the stack push them to the ordered queue if(!operator_r.empty()){ while(!operator_r.empty()){ operands.push(operator_r.top()); operator_r.pop(); } }
stack <parameter *> temp; // define this to make the the operations
while(!operands.empty()){ // as long as the operands is not empty //it taken is a number if(operands.front()->get_precedence()==2){ temp.push(operands.front()); // push to the stack operands.pop(); } // if taken is an operator, pop the last two taken from stack, do the operation and push the result to stack else if(operands.front()->get_precedence()==0 || operands.front()->get_precedence()==1){ parameter *p1 = new parameter(); // for the second taken from stack parameter *p2 = new parameter(); // for the first taken from stack p2 = temp.top(); temp.pop(); p1 = temp.top(); temp.pop();
// i used inheritence here
parameter *p3 = new parameter(); // for result // if operator is * if(operands.front()->get_value() == 42 ){ p3 = p1->operator*(p2); } // if operator is + else if(operands.front()->get_value() == 43){ p3 = p1->operator+(p2); } // if the operator is - else if(operands.front()->get_value() == 45){ p3 =p1->operator-(p2) ; } // if the operator is / else if(operands.front()->get_value() == 47){ try{ if(p1->get_value()==0 && p2->get_value()==0) // for the exception 0/0 throw ZeroByZeroException(); else if(p2->get_value()==0) // for the exception number/0 throw DivideByZeroException(); else p3 = p1->operator/(p2); } catch(ZeroByZeroException zz){ parameter *p = new parameter(); p->set_value(0); p->set_precedence(-2); // to control the exception and not to return a wrong value temp.push(p); cout<<zz.what(); break; } catch(DivideByZeroException z){ parameter *p = new parameter(); p->set_value(0); p->set_precedence(-2); // to control the exception and not to return a wrong value temp.push(p); cout<<z.what(); break; } } operands.pop(); temp.push(p3); } }
return temp.top(); // return result
}
Leave a Reply