如何检查一个数组中的特定字符串是否在另一个数组中

时间:2016-02-08 01:19:00

标签: c binary-search

我有一个名为puzzle的数组,它由单词/字母/随机字符串组成,我想检查它是否在另一个名为dictionary的数组中有任何相同的字符串(字典中的字符串按字母顺序列出)

所以我相信我的问题是我的程序中的二进制搜索,我并不完全确定如何使用字符串解决它。我尝试使用一些strcmp(),但我不认为这是要走的路?

当程序运行时,它没有输出。没有比赛,但有。

这是我的二元搜索功能:

int binsearch(char **dictionary, char *puzzle) {
    int start = 1;  //excluded first string of dictionary array bc #
    int end = listlength;
    while (start < end) {
        int mid = (start + end) / 2;
        int temp = strcmp(dictionary[mid], puzzle);
        if (temp < 0) {
            start = mid + 1; //it is in upper half
        } else
        if (temp > 0) {  //check lower half
            end = mid;
        } else
            return 1; //found a match hopefully
    }
    return 0;
}

如果您需要查看

,我的整个代码就在这里
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define listlength 149256
#define maxWordLen 19

char **getWords(int rows, int cols);
void freeArray(char **array, int rows);
char **makeGridArray(int rows, int cols);
int binsearch(char **dictionary, char *puzzle);
void wordSearch(char **dictionary, char **puzzle, int row, int col);
const int DX_SIZE = 8;
const int DX[] = { -1, -1, -1,  0,  0,  1,  1,  1 };
const int DY[] = { -1,  0,  1, -1,  1, -1,  0,  1 };

int main() {

    //read in dictionary
    int i, j, x = 0, numCases, gridRow, gridCol;
    char **words = getWords(listlength, maxWordLen);

    //Get number of cases.
    printf("enter number of cases:\n");
    scanf("%d", &numCases);

    //process each case.
    while (x < numCases) {
        scanf("%d%d", &gridRow, &gridCol);

        //make word search grid
        char **grid = makeGridArray(gridRow + 1, gridCol);

        /* for testing if grid is storing properly
        for (i = 0; i < gridRow + 1; i++) {
            printf("%s\n", grid[i]);
        }
        */

        printf("Words Found Grid #%d:\n", x + 1);
        wordSearch(words, grid, gridRow + 1, gridCol);
        x++;
        freeArray(grid, gridRow + 1);
    }
    freeArray(words, listlength);
}

char **getWords(int rows, int cols) {
    int i;

    //allocate top level of pointers.
    char **words = malloc(sizeof(char*) * rows);

    //allocate each individual array
    for (i = 0; i < rows; i++) {
        words[i] = malloc(sizeof(char) * cols + 1);
    }

    //read dictionary.txt
    FILE *dictionary = fopen("dictionary.txt", "r");
    for (i = 0; i < rows; i++) {
        fgets(words[i], cols + 1,dictionary);
    }
    fclose(dictionary);
    return words;
}

char **makeGridArray(int rows, int cols) {
    //allocate top level of pointers.
    char **grid = malloc(sizeof(char*) * rows);
    int i, j;

    //allocate each individual array
    for (i = 0; i < rows; i++) {
        grid[i] = malloc(sizeof(char) * cols + 1);
    }
    //read in user input grid
    for (i = 0; i < rows; i++) {
        gets(grid[i]);
    }
    return grid;
}

int binsearch(char **dictionary, char *puzzle) {
    int start = 1;  //excluded first string of dictionary array bc #
    int end = listlength;
    while (start < end) {
        int mid = (start + end) / 2;
        int temp = strcmp(dictionary[mid], puzzle);
        if (temp < 0) {
            start = mid + 1; //it is in upper half
        } else
        if (temp > 0) {  //check lower half
            end = mid;
        } else
            return 1; //found a match hopefully
    }
    return 0;
}

void wordSearch(char **dictionary, char **puzzle, int row, int col) {
    int i, X, Y, dir;
    char wordsfound[19] = { '\0' };
    for (X = 0; X < row + 1; X++) {
        for (Y = 0; Y < col; Y++) {
            for (dir = 0; dir < DX_SIZE; dir++) //check every direction
                for (i = 0; i < 19; i++) {
                    //will continue in direction DX,DY starting at x,y
                    int nextX = X + DX[dir] * i;
                    int nextY = Y + DY[dir] * i;
                    if (nextX < 0 || nextX >= row) break; //keep in bounds
                    if (nextY < 0 || nextY >= col) break;
                    //store the string of letters to check
                    wordsfound[i] = (puzzle[nextX][nextY]);
                    if (i > 3) { //minimum word is 4
                        wordsfound[i + 1] = '\0';
                        //if the string of letters is actually a word, print
                        int bin = binsearch(dictionary, wordsfound);
                        if (bin) {
                            printf("%s\n", wordsfound);
                        }
                    }
                }
        }
    }
    return;
}

void freeArray(char **array, int rows) {
    //free arrays
    int i;
    for (i = 0; i < rows; i++) {
        free(array[i]);
    }
    free(array);
}

1 个答案:

答案 0 :(得分:1)

问题出在getwords()函数中:您使用fgets()读取字典中的单词,但忘记删除尾随\n。字典中的所有单词都有一个尾随\n,因此它们都不匹配您的搜索。

以下是更正后的版本:

char **getWords(int rows, int cols) {
    char line[256];
    int i;

    //allocate top level of pointers.
    char **words = malloc(sizeof(char*) * rows);

    //read dictionary.txt
    FILE *dictionary = fopen("dictionary.txt", "r");
    for (i = 0; i < rows; i++) {
        if (!fgets(line, sizeof line, dictionary))
            line[0] = '\0';
        line[strcspn(line, "\n")] = '\0';
        words[i] = strdup(line);
    }
    fclose(dictionary);
    return words;
}

请注意,最好不要依赖已知的魔法列表长度。您还可以在阅读字典时忽略注释和空行。