无法弄清楚如何基于另一个结构的某个部分创建结构数组
Cant figure out how to create an structure array based on a certain part of another structure
inb4 问题是 - 在我的国家我们有城市,然后城市在更大的事物中,有点像美国的州,所以对于这个任务,我将城市称为城市,而那些更大的事物是州,例如有城市 A、B 和 C。A 和 B 处于状态 X,C 处于状态 Y。
我正在通过做几年前的考试来准备我的考试,有这个任务,它要求你输出到一个文件结构,它由州的名称组成,然后是居住在州最小城市的人数,然后是居住在该州的总人数。一开始,你会得到一个信息文件。第一个数字是该计划必须处理的城市数量,我们称之为k。然后有很多台词,看起来像这样:
例如CITYNAME STATE NUMBEROFPPL
:
Buffalo New York 300000
这是我的信息文件的样子:
15
Vilnius Vilniaus 541278
Dusetos Utenos 4211
Alytus Alytaus 69859
Druskininkai Alytaus 16890
Ignalina Utenos 6307
Kavarskas Utenos 753
Lazdijai Alytaus 5027
Simnas Alytaus 1940
Trakai Vilniaus 5504
Utena Utenos 33086
Veisiejai Alytaus 1673
Vievis Vilniaus 5246
Lentvaris Vilniaus 11832
Visaginas Utenos 28438
Zarasai Utenos 8001
我可以轻松读取文件,我构造了一个结构数组,称为 City,所以它看起来像这样:
City A[102] // Thats the maximum number of cities
在结构中,它看起来像:
struct City
{ string name;
string state;
int peoplelivinginit;
}
现在问题来了 - 我需要找到给定城市中有多少个不同的州,并为它们构建一系列结构(结构如下:
string nameofthestate;
string citiesinstate[102];
int overallnumberofpeopleinstate;
int peoplelivinginthesmallestcityofthestate;
)
我不知道我如何找到结构数组中有多少种不同的状态,我尝试对它们进行排序,然后删除重复项,但这听起来很麻烦,而且我也未能使用 sort,因为我们还没有学会如何使用它,我不认为这就是我们应该如何完成这项任务。
请告诉我如何找到有多少以及有哪些不同的州,我想我可以从那里开始。
这是我到目前为止所做的:
#include <iostream>
#include <iomanip>
#include <fstream>
#include <algorithm>
using namespace std;
struct City
{
string name;
string state;
int n; //number of people in the city
};
void Read (City A[], int & k)
{
ifstream fd;
fd.open("Info.txt");
fd >> k;
for (int i = 0; i < k; i++)
{
fd.ignore();
char namee[21];
fd.get(namee, 21);
A[i].name = namee;
char statee[14];
fd.get(statee, 14);
A[i].state = statee;
fd >> A[i].n;
}
fd.close();
}
int main()
{
City A[102];
int k;
Read (A, k);
City B[102] = A;
for (int i = 0; i < k; i++)
{
cout << B[i].name << " " << B[i].state << " " << B[i].n << endl;
}
return 0;
}
编辑::: 这是最终结果应该是什么样子:
3
Utenos 753 80796
Alytaus 1673 95389
Vilniaus 5246 563860
编辑2:谢谢你的所有答案。我注意到你们中的大多数人都建议使用向量、map、bool 等,但我甚至还没有听说过这些东西,因为我刚刚高中毕业,我的 IT 期末考试是今天。我很高兴地说,我肯定通过了,可能会有大约 85-95%,所以它真的很好。由于我打算在大学学习计算机科学,我将检查您提到的内容,因为我将来可能需要它们。
你有城市,你有关于它的信息,以及概念状态,你只知道名称和它包含城市的知识。
你的城市结构在我看来是合理的。
状态可以是类似
std::map<std::string, std::vector<City>> states;
这是字符串(将是每个州的名称)到城市列表的有序映射。一个州的城市列表可以像访问数组一样访问州["州名"],除了您可以使用州名称而不是数字。
bool Read (std::map<std::string, std::vector<City>> & states)
{
int k;
ifstream fd("Info.txt");
if (!(fd >> k))
{
//bad file. do something.
return false;
}
for (int i = 0; i < k; i++)
{
std::string name;
std::string state;
int population;
if (fd >> name >> state >> population)
{
City city(name, state, population);
states[state].push_back(city);
}
else
{
//bad file. do something.
return false;
}
}
return true;
}
在此功能结束时,所有城市都已分配给对象。每个城市对象都已放入按州组织的列表中。
查找状态的数量很容易:states.size()
.
查找维尔纽斯的城市数量: states["Vilniaus"].size()
纽斯的人口总和:
int sum = 0;
for(City city: states["Vilniaus"])
{
sum += city.n;
}
最小人数类似:
int min = std::numeric_limits<int>::max(); // or just use some arbitrary huge number
for(City city: states["Vilniaus"])
{
if (city.n < min)
{
min = city.n;
}
}
获取州列表有点棘手,因为地图存储std::pair
,std::pair
州名称和城市分组:
for (auto state: states)
{
string statename = state.first; // City is at state.second
// do something with statename
}
看看你拥有什么和你想要什么通常会有所帮助:
您有一个条目列表,每个条目代表一个城市以及一些相关信息。这可以 - 就像你所做的那样 - 很好地打包到一个结构中:
struct CityEntry {
string name;
string state;
unsigned int inhabitants;
};
您需要一个状态列表,其中包含一些必须从输入中计算的信息。所以你也可以尝试把它放到一个结构中:
struct StateEntry {
string name;
unsigned int total_inhabitants;
unsigned int lowest_inhabitants;
};
但是,还有一个额外的要求:唯一性。您不希望上述结构的多个实例具有相同的名称。因此,事实上,对于每个(州)名称,只有一个相关的信息"包"。这是一个非常常见的模式,所以有一个解决方案:std::map
将状态的每个名称映射到其相关信息:
struct StateInhabitants {
unsigned int total;
unsigned int lowest;
// constructor needed, see full source
};
// ... map<string, StateInhabitants>
这是"我想要的"的代表。接下来,您需要将"我拥有的"转换为"我想要的"。由于您的输入是一个列表,其元素之间没有任何依赖关系,因此您可以简单地迭代它,提取您需要的信息:
vector<CityEntry> cities = read_cities();
map<string, StateInhabitants> state_info;
for (CityEntry const & city : cities) {
// accessing an entry of a map via operator[] creates
// the entry if it isn't there yet.
StateInhabitants & inhabitants = state_info[city.state];
inhabitants.total += city.inhabitants;
inhabitants.lowest = std::min(inhabitants.lowest, city.inhabitants);
}
最后,您可以通过迭代地图来打印结果。
你可能会问为什么我不为每个州存储一个州的城市:在这种情况下,我尝试遵循YAGNI。存储它们会增加复杂性:因为它不是我打算作为解决方案呈现的表示形式,所以我需要另一个步骤才能将该中间表示转换为最终表示。
当然,除非您确实需要每个州的城市列表。
所以,总结一下:看看你有什么,看看你想要什么,包括可能相当隐蔽的需求(比如在这种情况下的独特性)。搜索是否有部分解决方案满足您的要求(std::set
提供唯一性但没有其他信息,std::map
提供两者)。扩展它以实际适合您的问题。
完整的示例代码。
- 使用cpp中的结构和函数的多个学生条目
- 无法添加多个键以映射将结构作为键
- 结构包含在两个头文件中,这两个文件我都不拥有
- 在什么情况下,两个堆栈分配的结构对象的 this 点指向同一个地址?
- 从 cin 获取 c++ 中结构中多个枚举的输入
- 为什么这个结构需要 24 个字节
- 是否可以跨多个源文件构建 constexpr 数据结构?
- 在两个.cpp文件之间定义全局类/结构指针
- 如何创建结构的结构结构,等等嵌套多个结构?
- C++结构成员函数定义如果在结构体外部定义,则它们会有所不同
- 不是在结构体内部工作,而是在结构体外部工作的自定义类实例
- 如何在结构体内部实现指针
- 模板函数转换为结构体内部的函数指针
- 可以引用定义在结构体内部的友元操作符吗?
- 容器在结构体内部崩溃
- 从结构体内部调用成员函数指针所指向的函数
- 不能使用SFML在结构体内部构造vector对象
- 将枚举(在结构体内部声明的)值赋给结构体内部相同枚举类型的变量
- 比较if语句中结构体内部的值
- 在结构体内部定义operator()函数