gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-28 04:41:53 25 4
gpt4 key购买 nike

我实现了 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/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com