C++’da Yığın ve Kuyruk Veri Yapılarının Kullanımına Örnek

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
}

report

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Blog at WordPress.com.

Up ↑