C
#include <stdio.h>
#define NCANDIDATES 4
static const char * const cand_list[NCANDIDATES] = {
"Alberto Arbusto",
"Juan Perez",
"Mickey Mouse",
"Jorge Sangre"
};
#define BUFFER_SIZE 100
int
main(int argc, char **argv)
{
int votes[NCANDIDATES];
int candidate;
size_t name_start;
int i;
int j;
int place;
int max;
size_t bytes;
char buffer[BUFFER_SIZE];
/*
Make sure input is read in text mode, so we don't have to
worry about whether line endings are LF or CRLF.
*/
freopen(NULL, "rt", stdin);
/* Initialize vote tally. */
for (candidate = 0; candidate < NCANDIDATES; candidate++) {
votes[candidate] = 0;
}
/* Read and process vote file. */
do {
/* Read a block of data. */
bytes = fread(buffer, 1, BUFFER_SIZE, stdin);
/* Loop over the data, finding and counting the votes. */
name_start = 0;
for (i = 0; i < bytes; i++) {
if (buffer[i] == '\n') {
/* Found name. */
buffer[i] = '\0'; // nul-terminate name so strcmp will work
/* Look up candidate. */
for (j = 0; j < NCANDIDATES; j++) {
if (strcmp(&buffer[name_start], cand_list[j]) == 0) {
candidate = j;
break;
}
}
/* Count vote. */
++votes[candidate];
/* Next name starts at next character */
name_start = i + 1;
}
}
} while (bytes > 0);
/* Output the candidates, in decreasing order of votes. */
for (place = 0; place < NCANDIDATES; place++) {
max = -1;
for (j = 0; j < NCANDIDATES; j++) {
if (votes[j] > max) {
candidate = j;
max = votes[j];
}
}
printf("%8d %s\n", votes[candidate], cand_list[candidate]);
votes[candidate] = -1; // Remove from consideration for next place.
}
return 0;
}
ホルヘ・サングレに賛成。
ランダムに生成された投票ファイルを使用したテストでは、Alberto Arbustoが実際の投票の最大1.4%(Jorge Sangreの場合は49.7%対48.3%)を受け取った場合でも、通常、Jorge Sangreが当選します。
固定サイズのブロックでデータを読み取ると、多くの場合、行が2つのブロックに分割されます。最初のブロックの終わりにある行のフラグメントは、改行文字がないためカウントされません。2番目のブロックのフラグメントは投票を生成しますが、候補の名前のいずれとも一致しないため、「候補」変数は更新されません。これは、名前が分割された候補者から前の投票を受け取った候補者に投票を転送する効果があります。長い名前は複数のブロックに分割される可能性が高いため、Alberto ArbustoはJorge Sangreよりも投票の「ドナー」になることが多くなります。