C ++ классы - самый частый объект в массиве - PullRequest
0 голосов
/ 25 апреля 2018

Я реализовал 3 класса: местоположение, адрес, маршрут. Класс Address содержит объект Location, а класс Route содержит массив объектов Address. В основной функции я создал массив объектов Route. То, что я хочу сделать, - это найти наиболее часто встречающиеся 5 адресов в массиве Route. Я думаю, что я должен использовать частотный вектор, но я не уверен, как реализация должна быть сделана. Я был бы очень признателен, если бы кто-то мог дать мне решение Ниже приведен код:

#include <iostream>
#include <string.h>
using namespace std;

class Location
{
    double lat, lon;

    char *emi;
public:
    Location(double = 0, double = 0, char* = NULL);
    virtual ~Location();
    Location& operator= (const Location &);
    Location(const Location&);
    friend ostream& operator<< (ostream&, const Location &);
    void operator! ();
    void print1() const;
    char* getem()
    {
        return emi;
    }
protected:
private:
};
Location::Location(double lat, double lon, char *emi)
{
    this->lat = lat;
    this->lon = lon;
    if (emi != NULL)
    {
        this->emi = new char[strlen(emi) + 1];
        strcpy(this->emi, emi);
    }

}
Location&Location::operator= (const Location &l)
{
    if (this != &l)
    {
        this->lon = l.lon;
        this->lat = l.lat;
        if (l.emi != NULL)
        {
            this->emi = new char[strlen(l.emi) + 1];
            strcpy(this->emi, l.emi);
        }
    }
    return *this;
}
Location::Location(const Location &la)
{
    lat = la.lat;
    lon = la.lon;
    if (la.emi != NULL)
    {
        emi = new char[strlen(la.emi) + 1];
        strcpy(emi, la.emi);
    }
}
Location::~Location()
{
    if (emi != NULL)
        delete[]emi;
}
void Location::operator! ()
{
    if (!(strcmp(this->emi, "north")))
    {
        delete[]this->emi;
        this->emi = new char[strlen("south") + 1];
        strcpy(this->emi, "south");
    }
    else
    {
        delete[]this->emi;
        this->emi = new char[strlen("north") + 1];
        strcpy(this->emi, "north");
    }
}
void Location::print1() const
{
    cout << "lon: " << this->lon << endl;
    cout << "lat: " << this->lat << endl;
    cout << "emi: " << this->emi << endl;
    cout << endl;
}

ostream& operator<< (ostream &os, const Location &l)
{
    os << "lon: " << l.lon << endl;
    os << "lat: " << l.lat << endl;
    os << "emi: " << l.emi << endl;
    os << endl;
    return os;
}
class Address
{

    char *desc;
    Location l;
    char *country;
    public`:
        Address(char *, const Location &, char *);
    virtual ~Address();
    friend ostream& operator<< (ostream&, const Address &);
    void print();
    bool em();
    char *getDesc()
    {
        return desc;
    };

protected:
private:
};
Address::Address(char *desc, const Location &loc1, char *country)
{
    if (desc != NULL)
    {
        this->desc = new char[strlen(desc) + 1];
        strcpy(this->desc, desc);
    }
    if (country != NULL)
    {
        this->country = new char[strlen(country) + 1];
        strcpy(this->country, country);
    }
    this->l = loc1;
}
Address::~Address()
{
    if (country != NULL)
        delete[]country;
    if (desc != NULL)
        delete[]desc;
}
ostream& operator<< (ostream &os, const Address&a)
{
    os << "desc: " << a.desc << endl;
    os << "country: " << a.country << endl;
    a.l.print1();
    return os;
}
void Address::print()
{
    cout << "desc: " << desc << endl;
    cout << "country: " << country << endl;
    this->l.print1();
}
bool Address::em()
{
    return (!(strcmp(l.getem(), "south")));
}

class Route
{
    Address **r;
    int dim_max;
    int dim_curr;
public:
    Route(int = 9);
    void print2();
    void add(char *, double, double, char *, char*);
    virtual ~Route();
    int lRoute();

protected:
private:
};
Route::Route(int d)
{
    this->dim_max = d;
    dim_curr = 0;
    r = new Address *[dim_max];
}
void Route::add(char *d, double l, double l2, char *em, char *t)
{
    r[dim_curr] = new Address(d, Location(l, l2, em), t);
    dim_curr++;
}
Route::~Route()
{
    for (int i = 0; i < dim_curr; i++)
        delete r[i];
    delete[]r;
}
void Route::print2()
{
    int i;
    for (i = 0; i < dim_curr; i++)
        r[i]->print();
}
int Route::lRoute()
{
    return dim_curr;
}

int main()
{

    Route **sirR;
    sirR = new Route *[5];
    sirR[0] = new Route(3);
    sirR[1] = new Route(3);
    sirR[2] = new Route(2);
    sirR[3] = new Route(4);
    sirR[4] = new Route(2);
    sirR[0]->add(" Address 1", 23.43, 21.43, "south", "country1");
    sirR[0]->add("Address 2", 23.431, 21.443, "south", "country2");
    sirR[0]->add("Address 3", 43.23, 13.42, "north", "country3");
    sirR[1]->add("Address 4", 13.431, 123.432, "south", "country4");
    sirR[1]->add("Address 5", 324.123, 43.13, "north", "country5");
    sirR[1]->add("Address 6", 43.123, 43.12, "south", "country 6");
    sirR[2]->add("Address 7", 23.31, 321.32, "north", "country 7");
    sirR[2]->add("Address 8", 43.12, 43.12, "south", "country 8");
    sirR[3]->add("Address 9", 23.42, 64.21, "north", "country 9");
    sirR[3]->add("Address 10", 64.23, 75.21, "south", "country 10");
    sirR[3]->add("Address 11", 75.13, 75.124, "north", "country 11");
    sirR[3]->add("Address 12", 75.12, 54.342, "south", "country 12");
    sirR[4]->add("Address 13", 543.245, 34.24, "north", "country 13");
    sirR[4]->add("Address 14", 54.123, 84.12, "south", "country 14");
    sirR[4]->print2();
    return 0;
}

P.S .: Я не использую строки, потому что учитель сказал мне использовать char.

1 Ответ

0 голосов
/ 25 апреля 2018

Я покажу вам, как использовать стандартную карту для получения количества адресов. Затем вы можете найти пятерку лучших из них. Это вытащит некоторые проблемы с дизайном и способами убрать код.

Попробуйте использовать const char * в конструкторах ваших объектов, а не просто char *. На самом деле, подумайте, почему вам сказали использовать char * вместо const char * - сначала убедитесь, что вы знаете разницу.

Кроме того,

Route **sirR;
sirR = new Route *[5];
sirR = new Route *[5];
sirR[0] = new Route(3);
sirR[1] = new Route(3);
sirR[2] = new Route(2);
sirR[3] = new Route(4);
sirR[4] = new Route(2);

может быть просто

Route sirR[5];

конечное использование

sirR[0].add(" Address 1", 23.43, 21.43, "south", "country1");

вместо

sirR[0]->add(" Address 1", 23.43, 21.43, "south", "country1");

и т. Д. - в нынешнем виде вы не delete массив, который вы new изд.


Так как единственный способ получить информацию из массива маршрутов - это распечатать стандартно.

Вам нужно подумать о том, что делает адреса равными. Классу нужен оператор равенства или другой способ сравнения адресов.

Чтобы использовать std::map, нам нужно определить оператор меньше чем. Это поможет вам начать, если вы добавите его внутрь Address:

bool operator < (const Address & lhs) const
{
    return strcmp(desc, lhs.desc) < 0;
}

Он не использует все поля - вы можете подумать, как его расширить.

Если теперь мы добавим заголовок карты

#include <map>

мы можем использовать карту. Это не лучший или единственный способ сделать это, но он покажет проблемы, с которыми мы пытаемся выяснить адреса.

Ваши адреса указываются в маршрутах, когда вы звоните add, поэтому мы можем отслеживать их там, если все маршруты видят одну и ту же карту.

class Route
{
    static std::map<Address, size_t> frequency; //<- keep track
    Address **r;
    int dim_max;
    int dim_curr;
public:
    Route(int = 9);
    void print2();
    void add(const char *, double, double, const char *, const char*);
    virtual ~Route();
    int lRoute();
    std::map<Address, size_t> frequencies() //<- so we can find use these in main
    {
        return frequency;
    }

protected:
private:
};
std::map<Address, size_t> Route::frequency;//<-- define the static data member

Это обходной путь, когда нельзя запрашивать адреса после того, как они идут по маршруту.

Теперь, используя этот хак, функция add может заполнить карту:

void Route::add(const char *d, double l, double l2, const char *em, const char *t)
{
    r[dim_curr] = new Address(d, Location(l, l2, em), t);
    ++frequency[*r[dim_curr]]; //count addresses
    dim_curr++;
}

Каждый раз, когда вы делаете адрес, он учитывается.

В конце main, перед возвратом 0, вы можете добавить код, чтобы увидеть все значения:

for(auto & items : sirR[0].frequencies())
{
    std::cout << items.first << ' ' << items.second << '\n';
}

Для ваших данных все они не нужны. Для других данных вы могли бы подсчитать несколько лучших. Я явно не сделал это для вас.

Поскольку ваш код стоит, вы не можете видеть адреса в маршрутах. Вы можете только распечатать их. Вам нужно изменить свой код, чтобы иметь к ним доступ.

Если вы избегаете стандартных структур данных и создаете свои собственные в качестве учебного упражнения, вы можете иметь массив имен и соответствующий массив счетчиков и выполнять поиск по именам каждый раз, когда добавляете новый адрес и увеличиваете количество совпадений. .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...