如何才能纠正我的输出以符合预期?

huangapple go评论55阅读模式
英文:

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 &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;string.h&gt;
#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, &quot;r&quot;);
if (fp == NULL) {
perror(&quot;Error opening dictionary file&quot;);
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 &gt; 0 &amp;&amp; word[len - 1] == &#39;\n&#39;) {
word[len - 1] = &#39;\0&#39;;  // remove newline
}
if (len &gt; 1 &amp;&amp; len &lt;= 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, &quot;r&quot;);
if (fp == NULL) {
perror(&quot;Error opening jumbles file&quot;);
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 &gt; 0 &amp;&amp; word[len - 1] == &#39;\n&#39;) {
word[len - 1] = &#39;\0&#39;;  // remove newline
}
if (len &gt; 1 &amp;&amp; len &lt;= MAX_WORD_LEN) {
strcpy(jumbles[jumbles_size++], word);
}
}
fclose(fp);
}
void unscramble() {
char sorted[MAX_WORD_LEN + 1];
for (int i = 0; i &lt; jumbles_size; i++) {
strcpy(sorted, jumbles[i]);
sort_chars(sorted);
printf(&quot;%s: &quot;, jumbles[i]);
int count = 0;
for (int j = 0; j &lt; dict_size &amp;&amp; count &lt; 10; j++) {
if (strcmp(sorted, dict[j]) == 0) {
printf(&quot;%s &quot;, dict[j]);
count++;
}
}
if (count == 0) {
printf(&quot;NO MATCHES&quot;);
}
printf(&quot;\n&quot;);
}
}
int main(int argc, char *argv[]) {
if (argc != 3) {
printf(&quot;Usage: %s &lt;dictionary&gt; &lt;jumbles&gt;\n&quot;, 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(&quot;Jumbled.txt&quot;, &quot;w&quot;);
fputs(&quot;Hello\n&quot;, outf);
fputs(&quot;Wassup\n&quot;, outf);
fputs(&quot;Rigga\n&quot;, outf);
fputs(&quot;Boyka\n&quot;, outf);
fputs(&quot;Popeye\n&quot;, outf);
fclose(outf);
outf = fopen(&quot;dictionary.txt&quot;, &quot;w&quot;);
fputs(&quot;olleH\n&quot;, outf);
fputs(&quot;Yello\n&quot;, outf);
fputs(&quot;elloH\n&quot;, outf);
fputs(&quot;lloeH\n&quot;, outf);
fputs(&quot;aggiR\n&quot;, outf);
fputs(&quot;ggiRa\n&quot;, outf);
fputs(&quot;giRag\n&quot;, outf);
fputs(&quot;yokaB\n&quot;, outf);
fputs(&quot;Bakoy\n&quot;, outf);
fputs(&quot;kaBoy\n&quot;, outf);
fputs(&quot;eyePop\n&quot;, outf);
fputs(&quot;poePye\n&quot;, outf);
fclose(outf);

huangapple
  • 本文由 发表于 2023年2月19日 16:53:48
  • 转载请务必保留本文链接:https://go.coder-hub.com/75498986.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定