Основным решением c является добавление массива, в котором хранятся прошлые слова, а затем поиск по нему каждый раз, когда запрашивается слово, чтобы узнать, является ли оно повторным словом. Сначала я отправлю репост всего кода, который вы разместили: в будущем, когда вы обновите свое сообщение, пожалуйста, не приводите в пример полный пример. Вы правильно сделали, вставив весь код, потому что я хочу затронуть кое-что. Все изменения сделаны в main()
. Решением является базовый c круговой массив, который попирает прошлые записи после того, как он достиг своего предела.
#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
первоначально объявляется как массив указателей, а затем приводится к указателю на указатель ( s), но инициализируется строковыми литералами. Этот последний пункт вызывает проблемы. Я решил go по строкам побайтно, чтобы сделать результат более читабельным, я очистил вывод, заменив нулевые терминаторы пробелом, чтобы его можно было увидеть как одну строку:
one two two three three four four five five six six
Подожди, что? Почему слова повторяются? Это когда вы знаете, что-то просто не правильно. Честно говоря, я не знаю точно, почему это происходит, но это действительно чертовски. Проблема в том, что вы объявляете массив указателей, но инициализируете его строковыми литералами. На мой взгляд, C не должен позволять компиляции, но это так. Кажется, что происходит то, что он размещает строковые литералы где-то еще в памяти и дает вам указатель там, что означает, что разница между адресами огромна. Один пример - 0x0059 (...) против 0x7fff (...). Таким образом, каждый элемент dictionary
является указателем на один из них.
Теперь, то, что вы делаете в checkDictionary()
с итерацией for l oop, перебирающей указатель как массив, не рекомендуется, так как Вы не можете сделать это вообще, и пусть это будет правильно. Что происходит, так это то, что каждое приращение индекса перемещает доступ к памяти на 8 байт (в 64-разрядных системах, которые, как я предполагаю, вы используете. Я даже не хочу думать о том, как это будет работать в 32-разрядных системах). ). Если dictionary
был инициализирован так, как я думаю, вы хотели, чтобы это было с каждым словом в памяти без повторений, это не сработало бы, так как слова были бы пропущены. Однако, как это было бы с «удачей», повторы структурированы так, чтобы они не мешали, и способ, которым вы выполняете итерацию, в итоге работает. Но это не правильно, и такого рода вещи в конечном итоге гарантированно взорвутся чрезвычайно раздражающими сбоями и ужасными ошибками.
Исправление состоит в том, чтобы просто сделать dictionary
a char**
или char[][]
такими, как вы сделал с матрицей. В первом случае вам придется вводить c каждого слова, но также можно динамически добавлять его, тогда как во втором вам нужно будет указывать каждый символ, и в итоге вы будете использовать больше памяти в качестве каждой записи. должен быть гомогенизирован с самым большим строковым литералом.