C++类——数组中出现频率最高的对象

标签 c++ class object

我实现了 3 个类:位置、地址、路线。 Address 类包含一个 Location 对象,而 Route 类包含一个 Address 对象数组。在主函数中,我创建了一个 Route 对象数组。我想做的是找到 Route 数组中出现频率最高的 5 个地址。我想我应该使用频率 vector ,但我不确定应该如何实现。如果有人能给我一个解决方案,我将不胜感激 下面是代码:

#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。

最佳答案

我将向您展示如何使用标准 map 来获取地址计数。 然后你可以找到其中的前五名。 它将找出一些设计问题和剥离代码的方法。

考虑在对象的构造函数中使用 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");

等等 - 就目前而言,您不会删除新建编辑的数组。


目前,从路由数组中获取信息的唯一方法是打印到标准输出。

您需要考虑是什么使地址相等。 该类需要一个等于运算符或其他比较地址的方法。

为了使用std::map,我们需要定义一个小于运算符。 如果您将它添加到 Address 中,这将帮助您开始:

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

它没有使用所有字段 - 您可以考虑如何扩展它。

如果我们现在包含 map 标题

#include <map>

我们可以使用 map 。 这不是执行此操作的最佳或唯一方法,但它会显示我们在尝试找出地址时遇到的问题。

当您调用 add 时,您的地址会在 route 生成,因此如果所有路线都可以看到相同的 map ,我们可以在那里跟踪它们。

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

这是解决在进入路线后无法查询地址的 hack。

现在,使用这个 hack,add 函数可以填充 map :

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';
}

对于您的数据,它们都是独一无二的。 对于其他数据,您可以计算前几名。 我没有明确地为您完成此操作。

就您的代码而言,您看不到 route 的地址。 您只能打印它们。 您需要更改代码才能访问这些内容。

如果您避免使用标准数据结构并将自己的数据结构作为学习练习,您可以拥有一个名称数组和一个匹配的计数数组,并在每次添加新地址并增加匹配计数时扫描名称.

关于C++类——数组中出现频率最高的对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50022419/

相关文章:

c# - 如何为类 C 语言创建 Visual Studio 语法突出显示

c++如何将文件解析为结构 vector

c++ - 由非常量变量定义的大小数组

C++ 如何格式化指向类数组的指针?

java - 确定任务是否较早,同时只知道日期是否较早以及时间是否较早

c++ - 为什么在 C++ 中将派生类对象传递给具有基类参数的函数时应该传递引用而不是值?

java从另一个类调用方法

C# 获取类实例名称

javascript - Jquery 多维数组或对象

javascript - 我有一个带有数据属性的 JSON 文件,其中包含包含有关冠军信息的对象。如何获得具有特定KEY属性的冠军?