首页 > 解决方案 > 检查一个单词是否已经猜到或输入

问题描述

我正在尝试用 C 语言制作一个单词搜索游戏,用户将猜测/输入一个单词,程序将检查该单词是否存在且有效。

如何检查用户输入的单词是否已经打印/输入?如果要比较什么变量,或者我是否需要为此创建一个函数,我真的很困惑。

char guessed[], 是一个全局数组。

 bool isAdded(char *token){
        int i = 0;
        while(guessed[i] != NULL){
            if(strcmp(guessed[i], token) == 0){
                return true;
            }
            i++;
        }
    return false;
}

主要的

while (1) {
   printf("\n[GM: Find a word]> ");
   if (!fgets(word, sizeof word, stdin)) {
    break;
       }
   word[strcspn(word, "\n")] = '\0';

   if (isAdded(word)) {
       printf("[GM: Word already guessed]");
   } else { 

    if (ifExist(matrix, word) && checkDictionary(dictionary, dict_len, word)) {
        printf("[GM: Found it]\n");
       } 
       else if (ifExist(matrix, word)) {
        printf("[GM: It's not in the dictionary]\n");
       }
       else if (strcmp(word, "quit") == 0) {
        break;
       } else {
        printf("[GM: Not found, please try again]\n");
       }
       }
    }
} 

标签: cwordsearchboggle

解决方案


最基本的解决方案是添加一个数组来存储过去的单词,然后每次查询一个单词时都通过它进行搜索,看它是否是重复的单词。我将重新发布您首先发布的整个代码:将来,当您更新您的帖子时,请不要核对完整的示例。您通过粘贴整个代码做了正确的事情,因为我想谈一谈。所有更改都在main(). 解决方案是一个基本的圆形数组,它在达到其上限后践踏过去的条目。

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <time.h>
#include <stdbool.h>

#define SIZE 10 // row and column size
#define MAX 40  // word size

// Function to check if a word exists in the board 
// starting from the first match in the board 
// index: index till which pattern is matched 
// i, j: current position in 2D array 
bool adjacentSearch(char matrix[SIZE][SIZE], const char *find, int i, int j, int index) {
    // pattern matched
    if (find[index] == '\0')
        return true;

    // out of bounds
    if (i < 0 || j < 0 || i >= SIZE || j >= SIZE || matrix[i][j] != find[index])
        return false;

    // marking this cell as visited 
    matrix[i][j] = '*';

    // finding subpattern in 4 directions 
    bool found = (adjacentSearch(matrix, find, i + 1, j, index + 1) ||
        adjacentSearch(matrix, find, i - 1, j, index + 1) ||
        adjacentSearch(matrix, find, i, j - 1, index + 1) ||
        adjacentSearch(matrix, find, i, j + 1, index + 1));

    // marking this cell 
    // as unvisited again 
    matrix[i][j] = find[index];
    return found;
}

// Function to check if the word exists in the board or not 
bool ifExist(char matrix[SIZE][SIZE], const char *find) {
    int len = strlen(find);

    // if total characters in matrix is 
    // less then pattern length 
    if (len > SIZE * SIZE)
        return false;

    // traverse in the board 
    for (int i = 0; i < SIZE; i++) {
        for (int j = 0; j < SIZE; j++) {
            if (adjacentSearch(matrix, find, i, j, 0)) {
                return true;
            }
        }
    }
    return false;
}

// Function to check if the word is in the dictionary 
int checkDictionary(char **arr, int len, char *target) {
    for (int i = 0; i < len; i++) {
        if (strncmp(arr[i], target, strlen(target)) == 0) {
            return true;
        }
    }
    return false;
}

// Prints the board
void printBoard(char matrix[SIZE][SIZE]) {
    for (int i = 0; i < SIZE; i++) {
        for (int j = 0; j < SIZE; j++) {
            printf(" %c ", matrix[i][j]);
        }
        printf("\n");
    }
}

void asdf(char* a) {
    int k = 2;
    return;
}

// Driver code
int main() {
    char previous[SIZE][MAX];
    int  indexOfPrevious = 0;
    char *dictionary[] = {"one", "two", "three", "four", "five", "six"};
    int dict_len = sizeof dictionary / sizeof dictionary[0];
    asdf(dictionary[0]);
    char word[MAX], matrix[SIZE][SIZE] = {{'r', 'h', 'y', 't', 'h', 'm', 'y', 'o', 'n', 'e'},
    {'j', 'e', 'p', 'u', 'o', 'o', 'f', 'u', 'o', 'l'},
    {'r', 'e', 'n', 'd', 'e', 'o', 'i', 'e', 'l', 'c'},
    {'o', 'p', 'e', 'e', 't', 'h', 'r', 'e', 'e', 'j'},
    {'d', 'y', 'l', 'v', 'p', 'p', 'h', 'e', 't', 'p'},
    {'h', 'e', 's', 'i', 'x', 'o', 'u', 'n', 'w', 'e'},
    {'f', 'v', 'm', 'f', 'o', 'x', 'd', 'k', 'o', 'v'},
    {'f', 'o', 'r', 'o', 's', 't', 'u', 'e', 'o', 'i'},
    {'g', 'a', 'l', 'g', 'o', 'w', 'b', 'y', 'p', 'a'},
    {'h', 'e', 'l', 'l', 'o', 'f', 'o', 'u', 'r', 'd'}};

    printBoard(matrix);

    while (1) {
        Start:
        printf("\n[GM: Find a word]> ");
        if (!fgets(word, sizeof word, stdin)) {
            break;
        }
        word[strcspn(word, "\n")] = '\0';
        if (strcmp(word, "quit") == 0) {
            break;
        }
        int repeatEntry = 0;
        for (int i = 0; i < indexOfPrevious; i++) {
            int Result = strncmp(previous[i], word, MAX);
            if (!Result) {
                repeatEntry |= 1;
                // Insert what you want to do if a word is re-entered here
            }
        }
        if (!repeatEntry) {
            indexOfPrevious %= SIZE;
            memcpy(previous[indexOfPrevious++], word, MAX);
        }

        if (ifExist(matrix, word) && checkDictionary(dictionary, dict_len, word)) {
            printf("[GM: Found it]\n");
        } else if (ifExist(matrix, word)) {
            printf("[GM: It's not in the dictionary]\n");
        }
        else {
            printf("[GM: Not found, please try again]\n");
        }
    }
    return 0;
}

现在谈谈你犯的一个错误,它与你提出的问题无关,但在代码正确性方面非常重要。违规代码是

char *dictionary[] = {"one", "two", "three", "four", "five", "six"};

结合

int checkDictionary(char **arr, int len, char *target) {
    for (int i = 0; i < len; i++) {
        if (strncmp(arr[i], target, strlen(target)) == 0) {
            return true;
        }
    }
    return false;
}

简单解释,变量dictionary最初声明为指针数组,然后转换为指向指针的指针,但使用字符串字面量进行初始化。最后一点会导致问题。我决定逐个字节地遍历字符串,因此为了使结果更具可读性,我通过用空格替换空终止符来清理输出,以便可以将其视为一个字符串:

one two two three three four four five five six six

等等,什么?为什么重复的话?这是当您知道某些事情不正确的时候。老实说,我不知道为什么会发生这种情况,但这真的很糟糕。问题是您正在声明一个指针数组,但使用字符串文字对其进行初始化。在我看来,C 根本不应该允许它编译,但它确实允许。看起来发生的事情是它在内存中的其他地方分配字符串文字并在那里给你一个指针,这意味着地址之间的差异是巨大的。一个例子是 0x0059(...) 与 0x7fff(...)。所以每个元素dictionary都是指向其中之一的指针。

现在,checkDictionary()不建议您使用 for 循环将指针作为数组进行迭代,因为您通常不能这样做并且它是正确的。发生的情况是索引的每个增量都会将内存访问移动 8 个字节(在 64 位系统上,我假设您正在使用它。我什至不想考虑这将如何在 32 位中工作)。IFdictionary的初始化方式我认为您希望它在内存中一个接一个地与每个单词一起使用,没有重复,这是行不通的,因为单词会被跳过。然而,正如“幸运”所拥有的那样,重复是结构化的,因此它们不会干扰,并且你迭代的方式最终会起作用。但这是不对的,而且这种事情最终肯定会因极其烦人的崩溃和可怕的错误而崩溃。

解决方法是只做dictionary一个char**char[][]像你对矩阵所做的那样。在前一种情况下,您必须对每个单词进行 malloc,但也可以动态添加,而在后一种情况下,您必须指定每个字符,并且最终会使用更多内存,因为每个条目都必须均质化为最大的字符串文字。


推荐阅读