英文:
How can I correct my output to what is intended?
问题
I have a code called unscramble
that takes two files, Jumbled.txt
and dictionary.txt
and finds if any words contain the same characters in both the files or not, for instance, here is a sample input for
Jumbled.txt:
Hello
Wassup
Rigga
Boyka
Popeye
dictionary.txt:
olleH
Yello
elloH
lloeH
aggiR
ggiRa
giRag
yokaB
Bakoy
kaBoy
eyePop
poePye
and the expected output of the code above is:
Hello: olleH elloH lloeH
Wassup: NO MATCHES
Rigga: aggiR ggiRa giRag
Boyka: yokaB Bakoy kaBoy
Popeye: eyePop poePye
Here is my code that attempts to solve it:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_WORD_LEN 50
#define MAX_DICT_WORDS 500000
#define MAX_JUMBLES 10000
char dict[MAX_DICT_WORDS][MAX_WORD_LEN + 1];
int dict_size;
char jumbles[MAX_JUMBLES][MAX_WORD_LEN + 1];
int jumbles_size;
int compare_chars(const void *a, const void *b) {
return *(char *)a - *(char *)b;
}
void sort_chars(char *s) {
qsort(s, strlen(s), sizeof(char), compare_chars);
}
int compare_words(const void *a, const void *b) {
return strcmp((char *)a, (char *)b);
}
void load_dict(const char *filename) {
FILE *fp = fopen(filename, "r");
if (fp == NULL) {
perror("Error opening dictionary file");
exit(1);
}
dict_size = 0;
char word[MAX_WORD_LEN + 1];
while (fgets(word, MAX_WORD_LEN + 1, fp) != NULL) {
int len = strlen(word);
if (len > 0 && word[len - 1] == '\n') {
word[len - 1] = '\0'; // remove newline
}
if (len > 1 && len <= MAX_WORD_LEN) {
strcpy(dict[dict_size++], word);
}
}
fclose(fp);
qsort(dict, dict_size, sizeof(dict[0]), compare_words);
}
void load_jumbles(const char *filename) {
FILE *fp = fopen(filename, "r");
if (fp == NULL) {
perror("Error opening jumbles file");
exit(1);
}
jumbles_size = 0;
char word[MAX_WORD_LEN + 1];
while (fgets(word, MAX_WORD_LEN + 1, fp) != NULL) {
int len = strlen(word);
if (len > 0 && word[len - 1] == '\n') {
word[len - 1] = '\0'; // remove newline
}
if (len > 1 && len <= MAX_WORD_LEN) {
strcpy(jumbles[jumbles_size++], word);
}
}
fclose(fp);
}
void unscramble() {
char sorted[MAX_WORD_LEN + 1];
for (int i = 0; i < jumbles_size; i++) {
strcpy(sorted, jumbles[i]);
sort_chars(sorted);
printf("%s: ", jumbles[i]);
int count = 0;
for (int j = 0; j < dict_size && count < 10; j++) {
if (strcmp(sorted, dict[j]) == 0) {
printf("%s ", dict[j]);
count++;
}
}
if (count == 0) {
printf("NO MATCHES");
}
printf("\n");
}
}
int main(int argc, char *argv[]) {
if (argc != 3) {
printf("Usage: %s <dictionary> <jumbles>\n", argv[0]);
return 1;
}
load_dict(argv[1]);
load_jumbles(argv[2]);
unscramble();
return 0;
}
However, when I do ./unscramble dictionary.txt Jumbled.txt
, this is what I get:
xxxxxxxxx@LAPTOPxxxxxxxx:~$ ./unscramble dictionary.txt Jumbled.txt
lloeHH
: NO MATCHES
giRagR
kaBoyB
poePyep
I've been trying to debug this and change up my code but nothing is working, what is the problem here?
英文:
I have a code called unscramble
that takes two files, Jumbled.txt
and dictionary.txt
and finds if any words contain the same characters in both the files or not, for instance, here is a sample input for
Jumbled.txt:
Hello
Wassup
Rigga
Boyka
Popeye
dictionary.txt:
olleH
Yello
elloH
lloeH
aggiR
ggiRa
giRag
yokaB
Bakoy
kaBoy
eyePop
poePye
and the expected output of the code above is:
Hello: olleH elloH lloeH
Wassup: NO MATCHES
Rigga: aggiR ggiRa giRag
Boyka: yokaB Bakoy kaBoy
Popeye: eyePop poePye
Here is my code that attempts to solve it:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_WORD_LEN 50
#define MAX_DICT_WORDS 500000
#define MAX_JUMBLES 10000
char dict[MAX_DICT_WORDS][MAX_WORD_LEN + 1];
int dict_size;
char jumbles[MAX_JUMBLES][MAX_WORD_LEN + 1];
int jumbles_size;
int compare_chars(const void *a, const void *b) {
return *(char *)a - *(char *)b;
}
void sort_chars(char *s) {
qsort(s, strlen(s), sizeof(char), compare_chars);
}
int compare_words(const void *a, const void *b) {
return strcmp((char *)a, (char *)b);
}
void load_dict(const char *filename) {
FILE *fp = fopen(filename, "r");
if (fp == NULL) {
perror("Error opening dictionary file");
exit(1);
}
dict_size = 0;
char word[MAX_WORD_LEN + 1];
while (fgets(word, MAX_WORD_LEN + 1, fp) != NULL) {
int len = strlen(word);
if (len > 0 && word[len - 1] == '\n') {
word[len - 1] = '\0'; // remove newline
}
if (len > 1 && len <= MAX_WORD_LEN) {
strcpy(dict[dict_size++], word);
}
}
fclose(fp);
qsort(dict, dict_size, sizeof(dict[0]), compare_words);
}
void load_jumbles(const char *filename) {
FILE *fp = fopen(filename, "r");
if (fp == NULL) {
perror("Error opening jumbles file");
exit(1);
}
jumbles_size = 0;
char word[MAX_WORD_LEN + 1];
while (fgets(word, MAX_WORD_LEN + 1, fp) != NULL) {
int len = strlen(word);
if (len > 0 && word[len - 1] == '\n') {
word[len - 1] = '\0'; // remove newline
}
if (len > 1 && len <= MAX_WORD_LEN) {
strcpy(jumbles[jumbles_size++], word);
}
}
fclose(fp);
}
void unscramble() {
char sorted[MAX_WORD_LEN + 1];
for (int i = 0; i < jumbles_size; i++) {
strcpy(sorted, jumbles[i]);
sort_chars(sorted);
printf("%s: ", jumbles[i]);
int count = 0;
for (int j = 0; j < dict_size && count < 10; j++) {
if (strcmp(sorted, dict[j]) == 0) {
printf("%s ", dict[j]);
count++;
}
}
if (count == 0) {
printf("NO MATCHES");
}
printf("\n");
}
}
int main(int argc, char *argv[]) {
if (argc != 3) {
printf("Usage: %s <dictionary> <jumbles>\n", argv[0]);
return 1;
}
load_dict(argv[1]);
load_jumbles(argv[2]);
unscramble();
return 0;
}
However, when I do ./unscramble dictionary.txt Jumbled.txt
, this is what I get:
xxxxxxxxx@LAPTOPxxxxxxxx:~$ ./unscramble dictionary.txt Jumbled.txt
lloeHH
: NO MATCHES
giRagR
kaBoyB
poePyep
I've been trying to debug this and change up my code but nothing is working, what is the problem here?
答案1
得分: 1
启用所有编译器警告
修复所有警告。
排序字典
单词的字典集是经过排序的。如果期望保持原始文件顺序,则不要对字典进行排序。
// 不期望
Hello: olleH elloH lloeH
// 期望
Hello: elloH lloeH olleH
鉴于 OP 的期望输出,无需对单词进行排序
未排序的单词
代码依赖于每个单词的字母被排序,然而字典中单词的字母并未排序。在传递给 strcmp(sorted, dict[j])
之前形成一个排序的字符串。
代码不应多次对字母或单词进行排序
只进行一次排序并保存结果。
高级:当 char
值为负时排序出现问题。
字符串应该按照 unsigned char
进行排序。这是 strcmp()
的工作方式。
// return *(char*) a - *(char*) b;
return *(unsigned char*) a - *(unsigned char*) b;
采用建议的测试代码
FILE *outf = fopen("Jumbled.txt", "w");
fputs("Hello\n", outf);
fputs("Wassup\n", outf);
fputs("Rigga\n", outf);
fputs("Boyka\n", outf);
fputs("Popeye\n", outf);
fclose(outf);
outf = fopen("dictionary.txt", "w");
fputs("olleH\n", outf);
fputs("Yello\n", outf);
fputs("elloH\n", outf);
fputs("lloeH\n", outf);
fputs("aggiR\n", outf);
fputs("ggiRa\n", outf);
fputs("giRag\n", outf);
fputs("yokaB\n", outf);
fputs("Bakoy\n", outf);
fputs("kaBoy\n", outf);
fputs("eyePop\n", outf);
fputs("poePye\n", outf);
fclose(outf);
英文:
At least these errors:
Enable all compiler warnings
Fix all warnings.
Sorted dictionary
The dictionary set of words are sorted. If original file order expected, do not sort the dictionary.
// Do not expect
Hello: olleH elloH lloeH
// Expect
Hello: elloH lloeH olleH
Given OP's expected output, there is no need to sort the words
Unsorted words
Code relies on each individual word's letter are sorted, yet individual letters in the dictionary words are not sorted. Form a sorted string before passing to strcmp(sorted, dict[j])
.
Code should not sort letters or words more than once
Do it once and save results.
Advanced: Sorting amiss when a char
value is negative.
String should be sorted as unsigned char
. That is what strcmp()
does.
// return *(char*) a - *(char*) b;
return *(unsigned char*) a - *(unsigned char*) b;
Following test code suggested
FILE *outf = fopen("Jumbled.txt", "w");
fputs("Hello\n", outf);
fputs("Wassup\n", outf);
fputs("Rigga\n", outf);
fputs("Boyka\n", outf);
fputs("Popeye\n", outf);
fclose(outf);
outf = fopen("dictionary.txt", "w");
fputs("olleH\n", outf);
fputs("Yello\n", outf);
fputs("elloH\n", outf);
fputs("lloeH\n", outf);
fputs("aggiR\n", outf);
fputs("ggiRa\n", outf);
fputs("giRag\n", outf);
fputs("yokaB\n", outf);
fputs("Bakoy\n", outf);
fputs("kaBoy\n", outf);
fputs("eyePop\n", outf);
fputs("poePye\n", outf);
fclose(outf);
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论