0

I need help comparing an array that is stored within a class. It has to be a member function and include the parameters set by my professor. I am having trouble calling the function as well as comparing it.

I included this function to show how I was able to compare the company name and return true or false when they were equal. I then looped through to find all the cars in a print function in the list that were of the same brand.

bool AutoVehicleType::isMadeByCompany(string companyName){
       if (companyName.compare(getAutoBrand())==0) 
       return true;
       else return false;
}

void printAllVehiclesMadeBy(AutoVehicleType vehicles[], int 
noOfVehicles,string brand){ 
        for(int i=0; i<noOfVehicles;i++){
            if(vehicles[i].isMadeByCompany(brand)){ 
                vehicles[i].printVehicleInfo();
                cout << endl << "---------------" << endl;
            //loop that prints if vehicles made by the same brand
            }
        }
    }

This is the function that I am trying to make. I need help comparing the function as well as calling the member functions from the class. I am trying to make it similar to the one I made bove but I am having issues since it is an array and dont know how to compare it using the parameter set by my teacher.

bool AutoVehicleType::HaveIdenticalAmenities(AutoVehicleType 
otherVehicles){
if(vehicles[i].amenities==otherVehicles.amenities)
   return true;
else return false;
}

void printVehiclesWithIdenticalAmenities(AutoVehicleType 
vehicles[], int noOfVehicles){
    for (int i = 0; i < noOfVehicles; i++)
    {
        if(vehicles[i].HaveIdenticalAmenities(otherVehicles)) 
        {
            cout<<"Vehicles "<<Vehicles[i].getNumPlate()<<" 
            and "<< otherVehicles[].getNumPlate()<<" Have 
            Identical set of Amenites";
        }
    }
}

I get a lot of undeclared identifier errors when fiddling with these functions becuase I'm guessing I dont know how to call them correctly.

101001
  • 113
  • 9
  • What is `otherVehicles` in the `printVehiclesWithIdenticalAmenities` function? Perhaps the same question but without focusing on the code: you are to print the vehicles whose amenities are identical to what? Before writing a function, you should be able to write out (using no code) what the function is supposed to accomplish. Adding such a description to your question might be useful. – JaMiT Jun 17 '19 at 01:19

2 Answers2

0

You can't compare arrays with == (one of the many reasons not to use arrays). You need to do the comparison by hand, i.e check the array sizes are the same and then compare each element one by one. You've also got some strange confusion about using your vehicles array inside your method. The HaveIdenticalAmenities method just compares one pair of vehicles not two arrays of vehicles.

bool AutoVehicleType::HaveIdenticalAmenities(AutoVehicleType otherVehicle) {
    if (numOfAmenities != otherVehicle.numOfAmenities)
        return false;
    for (int i = 0; i < numOfAmenities; ++i)
        if (amenities[i] != otherVehicle.amenities[i])
            return false;
    return true;
}

numOfAmenities isn't in the code you posted above, but I seem to remember you had that in your previous (now deleted) post.

The way you call the method is confused as well. I'm guessing the intent is to find all pairs of vehicles with identical amenites in the vehicles array? If so then that would be this

for (int i = 0; i < noOfVehicles; i++)
{
    for (int j = i + 1; j < noOfVehicles; j++)
    {
        if (vehicles[i].HaveIdenticalAmenities(vehicles[j])) 
        {
            cout<<"Vehicles "<<vehicles[i].getNumPlate()<<" and "<< 
                vehicles[j].getNumPlate()<<" Have Identical set of Amenites";
        }
    }
}

Completely untested code.

john
  • 85,011
  • 4
  • 57
  • 81
  • Thanks, this is working when comparing the number of amenities to each other. I have to compare the actual amenities to each other though. So if both have a radio and GPS then it prints out. – 101001 Jun 16 '19 at 20:49
  • @MichaelTorres My code does compare the actual amenities `if (amenities[i] != otherVehicle.amenities[i]) return false;` Or are you saying that it should compare the amenities *irrespective of order*? My code doesn't do that. – john Jun 16 '19 at 20:55
0

For the following explanation I have stubbed your classes as follows:

struct Amenities
{
    int x = 0;
    friend bool operator==(const Amenities& amenities1, const Amenities& amenities2)
    {
        // How you compare your Amenities goes here.
        return amenities1.x == amenities2.x;
    }
};

struct AutoVehicleType
{
    std::string GetAutoBrand() const
    {
        return "";
    }

    bool IsMadeByCompany(std::string companyName) const;

    void PrintVehicleInfo() const
    {
    }

    bool HaveIdenticalAmentities(AutoVehicleType otherVehicle) const;

    int GetNumPlate()
    {
        return 1;
    }

    Amenities amenities = {};

};

bool AutoVehicleType::IsMadeByCompany(std::string companyName) const
{
    return (companyName == this->GetAutoBrand());
}

bool AutoVehicleType::HaveIdenticalAmentities(AutoVehicleType otherVehicle) const
{
    return (this->amenities == otherVehicle.amenities);
}

My first suggestion would be to use a std::vector instead of an array, if you choose to do so the following should be a decent approximation of your issue:

void PrintAllVehiclesMadeByBrand(std::vector<AutoVehicleType> vehicles, std::string brand)
{
    for (const auto& vehicle : vehicles)
    {
        if (vehicle.IsMadeByCompany(brand))
        {
            vehicle.PrintVehicleInfo();
        }
    }
}

void PrintVehiclesWithIdenticalAmenities(std::vector<AutoVehicleType> vehicles)
{
    for (size_t x = 0; x < vehicles.size(); x++)
    {
        for (size_t y = x + 1; y < vehicles.size(); y++)
        {
            if (vehicles.at(x).HaveIdenticalAmentities(vehicles.at(y)))
            {
                std::cout << "Vehicles " << vehicles.at(x).GetNumPlate() << " and " << vehicles.at(y).GetNumPlate << " have identical amenities." << std::endl;
            }
        }
    }
}

Where for your issue we simply loop comparing each element of the vector to each element that comes after it.

However, since this is a homework assignment I take it that you might need to use an array (though I really don't suggest it unless this is going on a board somewhere) an implementation might instead look as follows:

template <typename T, size_t N>
void PrintAllVehiclesMadeByBrand(T(&vehicles)[N], std::string brand)
{
    for (size_t x = 0; x < N; x++)
    {
        if (vehicles[x].IsMadeByCompany(brand))
        {
            vehicles[x].PrintVehicleInfo();
        }
    }
}

template <typename T, size_t N>
void PrintVehiclesWithIdenticalAmenities(T(&vehicles)[N])
{
    for (size_t x = 0; x < N; x++)
    {
        for (size_t y = x + 1; y < N; y++)
        {
            if (vehicles[x].HaveIdenticalAmenities(vehicles[y]))
            {
                std::cout << "Vehicles " << vehicles[x].GetNumPlate() << " and " << vehicles[y].GetNumPlate() << " have identical amenities." << std::endl;
            }
        }
    }
}

Where T(&vehicles)[N] is a shortcut for passing the arrays size without having to use a separate parameter (though if you feel uncomfortable using that technique just keep passing the array size as you have been).

In your example you have a otherVehicles, which I presume is the problem you're working on (where to get that from). In the example I provided we're comparing each element against each element ahead of it. Thus if your array has elements of the form:

1 2 3 4 1

It will compare 1 to 2, then 1 to 3, 1 to 4, and 1 to 1 where it will print your statement. Then the loop counter x will increment and it will compare 2 to 3 (we can safely skip comparing 2 to 1 because we already compared 1 to 2 in the previous iterator of x). Thus by the end you will have compared each element to each other.

It seems as though the other problem you might be getting at is how to compare two custom types. For that I suggest looking further into operator overloading: Operator Overloading (Just keep in mind, in the stub I used making the operator as a friend instead of as a member is an idiom).

Edit: This isn't exactly type safe, since Vehicle is an object. So if you choose to use templated arrays a static_assert to check that T is a Vehicle or a trailing return type to implement SFINAE would be prudent.