我是C编程的新手,我正在尝试完成这个随机配对程序,但我遇到了启动它的问题。基本上,程序需要从文本文件中读取3个字母的团队名称,将它们放入一个数组中,然后将团队随机地相互配对。有两轮,在第二轮,没有任何重赛。此外,来自同一所学校的团队不能互相对抗。来自同一所学校的团队在文本文件中共享相同的第一个字符和行。任何人都可以帮我解决这个问题吗? :)这是名为provisions.txt的文本文件:
Ab abak ab abg 巴巴巴巴 驾驶室 按dab duck dab 安倍晋三 Fab挂 加布 是中心 磅 展望 的 红色实验室 在Ma Mba妈妈 不,Nab
到目前为止我的代码是:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <math.h>
int main()
{
// Read characters from text file into array
FILE *file = fopen("provision.txt", "r");
char teamList[115];
char teams[32][4]; // Holds team names
int i;
for(i = 0; i < 32; i++){
fscanf(file, "%s", teams[i]);
}
for(i = 0; i < 32; i++){
printf("%s \n", teams[i]); // Test to make sure teams are read in
}
// Clean up
fclose(file);
return 0;
}
如果可能的话,我想将这两轮的输出存储在名为round1_pairings.txt和round2_pairings.txt的文本文件中。
该程序试图解决一些微妙的问题,如随机选择偏差,退出死胡同匹配尝试等。由于其他学校的团队不足,无法保证在给定轮次无法配对的情况下终止,更有可能发生在更高数量的轮次(不太可能只有两轮和许多学校)。
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#define NAMELEN 3
#define ROUNDS 2
#define RETRIES 10 // max attempts before restarting matching
#define STR_HELPER(x) #x // http://stackoverflow.com/a/5459929/4323
#define STR(x) STR_HELPER(x)
#define NAMEPRINTF "%" STR(NAMELEN) "s"
typedef char team_t[NAMELEN + 1];
typedef struct
{
team_t team;
team_t opponents[ROUNDS];
} pairing_t;
// the first round is round=0
// when round>0, prior round matches will be prevented from recurring
void make_matches(pairing_t* pairings, size_t count, size_t round)
{
// clip random() range to avoid bias toward first teams
long randmax = LONG_MAX - LONG_MAX % count - 1;
begin:
for(size_t ii = 0; ii < count; ++ii) {
if(pairings[ii].opponents[round][0]) continue; // already paired
//printf("matching: %s\n", pairings[ii].team);
unsigned retry = 0;
while(retry < RETRIES) {
long rand = random();
if (rand > randmax) continue; // avoid bias
pairing_t *opp = &pairings[rand % count];
if(opp->team[0] == pairings[ii].team[0]) { // same school
++retry;
continue;
}
if(opp->opponents[round][0]) continue; // already paired
size_t prior;
for(prior = 0; prior < round; ++prior) {
if(!memcmp(opp->team, pairings[ii].opponents[prior], sizeof(team_t))) {
break;
}
}
if(prior != round) continue; // duplicate pairing
//printf("match made: %s %s\n", opp->team, pairings[ii].team);
memcpy(pairings[ii].opponents[round], opp->team, sizeof(team_t));
memcpy(opp->opponents[round], pairings[ii].team, sizeof(team_t));
break;
}
if(retry == RETRIES) { // matching failed, start again
for(size_t ii = 0; ii < count; ++ii) {
memset(pairings[ii].opponents[round], 0, sizeof(team_t));
}
goto begin;
}
}
}
int main(void)
{
srandom(time(NULL));
FILE *file = fopen("provision.txt", "r");
size_t capacity = 15; // arbitrary initial size
pairing_t *pairings = calloc(capacity, sizeof(pairing_t));
if(!pairings) abort();
size_t count = 0;
while(fscanf(file, NAMEPRINTF, pairings[count].team) != EOF) {
//printf("%s\n", pairings[count].team);
++count;
if(count >= capacity) { // expand array
capacity *= 2;
pairings = realloc(pairings, capacity * sizeof(pairing_t));
if(!pairings) abort();
memset(&pairings[count], 0, (capacity - count) * sizeof(pairing_t));
}
}
for(size_t round = 0; round < ROUNDS; ++round) {
make_matches(pairings, count, round);
}
for(size_t ii = 0; ii < count; ++ii) {
printf("%s %s %s\n", pairings[ii].team, pairings[ii].opponents[0], pairings[ii].opponents[1]);
}
free(pairings);
fclose(file);
return 0;
}
输出是一个简单的表格,有三列:球队比赛,他们的第一个对手,以及他们的第二个对手。我相信你可以根据需要弄清楚如何将它们写成单独的文件。