4

I want to write program that reads command from user, when d is entered a taxi is entered ,it prompts to enter driver_id and stores taxi in in queue (queue can have maximum n taxi), when command c is entered by customer it assigns the earliest taxi in the queue to the customer.

I'm trying to solve it using struct member function so that our code looks good, but although I have initialized n=4, it is only able to store 2 taxi, and shows me that the queue is full for the 3rd entry, which should not happen. Please review my approach.

Program run as such:

PS C:\Users; if ($?) { g++struct_taxi};; if ($?) { .\struct_taxi}

enter command:d

enter driverid:122

enter command:d

enter driverid:124

enter command:d

enter driverid:126

Q is full    

Code:

#include<iostream>
using namespace std;
const int n=4;
struct Queue{
int elements[n],nwaiting,front;
void initialize(){
    nwaiting=0;
    front=0;

}
bool insert(int v){
    if(nwaiting>=n)
        return false;
    elements[(front+nwaiting)%n]=v;
    nwaiting++;
    return true;
}
bool remove(int &v){
    if(nwaiting==0)
        return false;
    else{
        v=elements[front];
        front=(front+1)%n;
        nwaiting--;
        return true;
    }
    
}
};
int main(){
Queue q;
q.initialize();
while(true){
cout<<"enter command:";
char c;cin>>c;
if(c=='d'){
    cout<<"enter driverid:";
    int driverid;cin>>driverid;
    if(!q.insert(driverid)){
        cout<<"Q is full\n";}
    else{
        q.insert(driverid);
    }


}
else if(c=='c'){
    int driverid;
    if(!q.remove(driverid)){
        cout<<"No taxi available.\n";
    }
    else
        //q.remove(driverid); 
        cout<<"assigning:"<<" "<<driverid<<endl;
             
}
}
}
silverfox
  • 1,568
  • 10
  • 27
def __init__
  • 1,092
  • 6
  • 17
  • 1
    Instead of having an "initialize" method in your struct, you should implement this: [C++ Constructors](https://en.cppreference.com/w/cpp/language/constructor). It might also be a good idea to look into the STL library, as there are classes in there that could implement much of what you're trying to for you, such as the [std::vector](https://en.cppreference.com/w/cpp/container/vector) or [std::queue](https://en.cppreference.com/w/cpp/container/queue). – Luiz Jun 08 '21 at 13:15
  • @luiz thank you sir, just learned constructor today, will be implementing it hereafter, will read all recommended concepts suggested by you. – def __init__ Jun 08 '21 at 13:21

1 Answers1

1

The problem is that when you check the condition if(!q.insert(driverid)), you've already insert that driver into the system. Then the else statement insert it another time with q.insert(driverid);

So the solution is to simply remove the else statement.

#include<iostream>
using namespace std;
const int n=4;

struct Queue
{
    int elements[n],nwaiting,front;
    void initialize()
    {
        nwaiting=0;
        front=0;

    }
    bool insert(int v)
    {
        if(nwaiting>=n) {return false;}
        elements[(front+nwaiting)%n]=v;
        nwaiting++;
        return true;
    }
    bool remove(int &v)
    {
        if(nwaiting==0)
            return false;
        else
        {
            v=elements[front];
            front=(front+1)%n;
            nwaiting--;
            return true;
        }

    }
};
int main()
{
    Queue q;
    q.initialize();
    while(true)
    {
        cout<<"enter command:";
        char c;
        cin>>c;
        if(c=='d')
        {
            cout<<"enter driverid:";
            int driverid;
            cin>>driverid;
            if(!q.insert(driverid))
            {
                cout<<"Q is full\n";
            }
        }
        else if(c=='c')
        {
            int driverid;
            if(!q.remove(driverid))
            {
                cout<<"No taxi available.\n";
            }
            else {cout<<"assigning:"<<" "<<driverid<<endl;}
        }
    }
}

Result:

enter command:d
enter driverid:121
enter command:d
enter driverid:122
enter command:d
enter driverid:123
enter command:d
enter driverid:124
enter command:d
enter driverid:125
Q is full

An easier way obviously is to use std::queue, a data structure used for situation exactly like this, and as it came with the same functionality of your Queue struct, the code would be much shorter:

#include <iostream>
#include <queue>
using namespace std;
const int maxn=2;



int main()
{   queue<int> q;
    while(true)
    {
        cout << "Enter command : "; char c; cin >> c;
        if (c == 'd') //if inserting new driver
        {
            cout << "Enter driver's ID : "; int id; cin >> id; //input id
            if (q.size() == maxn) {cout << "Queue is full\n";} //if size of queue is equal to maxn, no insert
            else {q.push(id);} //else insert
        }
        else if (c == 'c')
        {
            if (q.empty()) {cout << "No driver available\n";} //if no driver, no assigning
            else
            {
                int curDriver = q.front(); //take drive in front of queue
                q.pop(); //take the driver id out of queue
                cout << "Assigned driver : " << curDriver << "\n";
            }
        }
    }
}

Result:

Enter command : d
Enter driver's ID : 123
Enter command : d
Enter driver's ID : 124
Enter command : d
Enter driver's ID : 125
Queue is full
Enter command : c
Assigned driver : 123
Enter command : c
Assigned driver : 124
Enter command : c
No driver available
Enter command :

Also, it's not recommended to use keywords like front, remove, etc... for variable names. And check out Why is "using namespace std;" considered bad practice?

def __init__
  • 1,092
  • 6
  • 17
silverfox
  • 1,568
  • 10
  • 27
  • 1
    @Rajakr I've just modified my answer to utilize `std::queue`. If you need shorter and cleaner code, maybe use that instead of declaring your own struct. – silverfox Jun 08 '21 at 13:16
  • Thanks brother for adding another piece of code, i know some data structure but never used stack,quequ...i am noob so limited to array, got to learn queue application from your code – def __init__ Jun 08 '21 at 13:59