从答案的数量可以看出,有多种方法可以完成这项任务。对于国家或事件(但不是两者),您需要的一个元素是一个简单的查找表,其中包含国家条目或事件条目,以允许您区分 results 中的值是国家名称还是事件名称.一个简单的国家/地区查找(这里是全局的,但也可以是函数范围),例如以下工作:
char *countries[] = { "Canada", "India", "New Mexico" }; /* countries lookup */
您可以采取的另一个捷径是识别结果中的指针具有定义的函数范围,因此无需复制或分配内存来保存它们——它们已经存在于只读内存中。
另一个有用的结构元素是记录与国家相关的事件,例如eventcnt。每次在国家/地区下添加事件时,该值都会增加。您可以使用类似于以下的国家/事件结构:
typedef struct {
char *country;
char *event[MAXE];
int eventcnt;
} host;
(MAXE 是一个简单的常量,表示所涉及的最大事件,允许您对结构数组使用自动存储。(可以轻松更改为根据需要分配/重新分配存储)
然后,您需要简单地循环遍历 results 数组一次,了解事件总是跟随在它们之前的国家。使用多个嵌套循环可将您遍历results 的次数保持为一次。本质上,您循环遍历results 中的每个指针,确定它是否指向国家/地区名称,如果它是国家/地区名称,则将其添加为您的host.country 值之一,或者跳过它如果是(无需更新指针以指向最后一次出现的国家/地区名称)
由于涉及嵌套循环,一个简单的goto 提供了您需要确定何时处理country 名称或何时处理event 名称的所有控制,并允许您采取所需的操作每个案例。
然后,只需打印/使用您想要的结果,这些结果现在包含在结构数组中,hidx(主机索引)包含所涉及的唯一主机总数。
将各个部分放在一起,您可以执行类似以下的操作:
#include <stdio.h>
#include <string.h>
/* constants max(countries, events) */
enum { MAXC = 8, MAXE = 16 };
char *countries[] = { "Canada", "India", "New Mexico" }; /* countries lookup */
typedef struct {
char *country;
char *event[MAXE];
int eventcnt;
} host;
int main (void) {
char *results[] = { "Canada", "Cycling", "Canada", "Swimming",
"India", "Swimming", "New Mexico", "Cycling",
"New Mexico", "Cycling", "New Mexico", "Swimming"};
host hosts[MAXC] = {{ .country = NULL }};
int hidx = 0, i, j, country_count, current = 0, nelements;
country_count = sizeof countries/sizeof *countries;
nelements = sizeof results / sizeof *results;
for (i = 0 ; i < nelements; i++) { /* for each element */
for (j = 0; j < country_count; j++) { /* check if country */
if (strcmp (results[i], countries[j]) == 0) { /* if so */
int k;
for (k = 0; k < hidx && /* check if already assigned */
strcmp (hosts[k].country, countries[j]); k++) {}
if (!hosts[k].country) { /* if not, assign ptr, increment */
hosts[hidx++].country = results[i];
current = hidx - 1;;
}
goto nextc; /* skip event adding */
}
} /* results[i] is not a country, check if event exists for host */
if (hosts[current].eventcnt < MAXE) { /* if it doesn't, add it */
int k;
for (k = 0; k < hosts[current].eventcnt; k++)
if (strcmp (results[i], hosts[current].event[k]) == 0)
goto nextc; /* already exists for host, skip add */
hosts[current].event[hosts[current].eventcnt++] = results[i];
}
nextc:;
}
for (i = 0; i < hidx; i++) { /* output countries & events for each */
printf (" %s\n", hosts[i].country);
for (j = 0; j < hosts[i].eventcnt; j++)
printf (" %s\n", hosts[i].event[j]);
}
return 0;
}
使用/输出示例
$ ./bin/events
Canada
Cycling
Swimming
India
Swimming
New Mexico
Cycling
Swimming
查看所有答案。包含很多优点。如果您有任何问题,请告诉我。