0

私は、18 x 18 の文字のマトリックスをスキャンし、任意の方向に隠された単語を見つける単語検索プロジェクトに取り組んでいます。

ファイルからマトリックスを読み取り、コンソールに出力することに成功しました。ワードサーチは文字の最初の行を正しくスキャンします。

しかし、5 行または 6 行下にある単語を検索するように要求しても、それは実行されません。

また、「roosevelt」という単語を探していて、X=5,Y=4 から始まるとします。単語検索で最初の行に文字 "r" が見つかった場合、検索は停止し、"roosevelt" の最初の文字のみが見つかったと表示されます。

マトリックスが終了するか、単語全体が見つかるまで、プログラムがマトリックス全体を検索し続けるようにする方法がわかりません。

これが私のコードです:

(ソース コードと単語マトリックス ファイルが用意されたドロップボックス リンクもあります): https://www.dropbox.com/s/g5z3frtezjoj2vr/WordSearch.zip

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <ctype.h> //Used for the'toupper' function



int main(void){

 int N=0,M=0,a,X,Y,i,length;
    char array[18][18], string[50];

 FILE *wsch;
 wsch = fopen("wrdsearch.txt","r");


/* Above defines the 18X18 array in which to fit the wordsearch
   as well as a search string of length 50 (more than enough to search for words within      the wordsearch) */
printf("WORDSEARCH SOLVER - PRESS CTRL-C TO QUIT\n\n");

  if(!wsch) 
  {
    printf("Error! File did not open.\n");
    return 1;
  }

    for (Y=0; Y<18 ;Y++)
    {
        for(X=0;X<18;X++)
        {
            fscanf(wsch,"%c\n",&array[Y][X]); //Inputting each character into array
            array[Y][X]=toupper(array[Y][X]);
        }
    }
     printf("   ");
   for (X=0;X<18;X++)
    {
        if(X<=9){
        printf("%d ", X);

        }
        else{
        printf("%d", X);

        }
    }

   printf("\n______________________________________\n");
   fclose(wsch);
    for (Y=0;Y<18;Y++)
    {
        if(Y<=9){
        printf("%d |", Y);
        }
        else{
        printf("%d|", Y);
        }
        for (X=0;X<18;X++)
        { 
            printf("%c ",array[Y][X]); //Printing output to screen
        }
        printf("\n");
    }
    printf("\nPlease enter the word to be searched:\n");
    fgets(string,50,stdin); //Using the fgets function to read in the string from keyboard - prevents buffer overflow
    for(i=0;string[i]!='\0';i++)
    {
        string[i]=toupper(string[i]); //Converts string all into uppercase to prevent errors
    }
    length=strlen(string);
    for (Y=0;Y<18;Y++)
    {
        for(X=0;X<18;X++)
        {

            if(array[Y][X]==(string[0]))
            {
        printf("\nLetter 1 of %sis found at %d,%d\n",string,X,Y);
    //Success in finding first letter of string - Now trY in other directions
    if (array[--Y][X]==string[1])
    {
        //Success in finding in Y+ direction
        printf("Letter 2 of %sis found at %d,%d",string,X,Y);
        for (a=2;a<length;a++)
        {
            if (array[--Y][X]==string[a])
                printf("\nLetter %d of %sis found at %d,%d",a+1,string,X,Y);
        }
        printf("\n\nWord found in Y+ direction");
        break;
    }
    else if (array[Y][++X]==string[1])
    {
        //Success in finding in Y+X+ direction
        printf("Letter 2 of %sis found at %d,%d",string,X,Y);
        for (a=2;a<length;a++)
        {
            if (array[--Y][++X]==string[a])
                printf("\nLetter %d of %sis found at %d,%d",a+1,string,X,Y);


        }
        printf("\n\nWord found in Y+X+ direction");
        break;
    }
    else if (array[++Y][X]==string[1])
    {
        //Success in finding in X+ direction
        printf("Letter 2 of %sis found at %d,%d",string,X,Y);
        for (a=2;a<length;a++)
        {
            if (array[Y][++X]==string[a])
                printf("\nLetter %d of %sis found at %d,%d",a+1,string,X,Y);
        }
        printf("\n\nWord found in X+ direction");
        break;
    }
    else if (array[++Y][X]==string[1])
    {
        //Success in finding in X+Y- direction
        printf("Letter 2 of %sis found at %d,%d",string,X,Y);
        for (a=2;a<length;a++)
        {
            if (array[++Y][++X]==string[a])
                printf("\nLetter %d of %sis found at %d,%d",a+1,string,X,Y);
        }
        printf("\n\nWord found in X+Y- direction");
        break;
    }
    else if (array[Y][--X]==string[1])
    {
        //Success in finding in Y- direction
        printf("Letter 2 of %sis found at %d,%d",string,X,Y);
        for (a=2;a<length;a++)
        {
            if (array[++Y][X]==string[a])
                printf("\nLetter %d of %sis found at %d,%d",a+1,string,X,Y);
        }
        printf("\n\nWord found in Y- direction");
    //    break;
    }
    else if (array[Y][--X]==string[1])
    {
        //Success in finding in X-Y- direction
        printf("Letter 2 of %sis found at %d,%d",string,X,Y);
        for (a=2;a<length;a++)
        {
            if (array[++Y][--X]==string[a])
                printf("\nLetter %d of %sis found at %d,%d",a+1,string,X,Y);
        }
        printf("\n\nWord found in X-Y- direction");
   //     break;
    }
    else if (array[--Y][X]==string[1])
    {
        //Success in finding in X- direction
        printf("Letter 2 of %sis found at %d,%d",string,X,Y);
        for (a=2;a<length;a++)
        {
            if (array[Y][--X]==string[a])
                printf("\nLetter %d of %sis found at %d,%d",a+1,string,X,Y);
        }
        printf("\n\nWord found in X- direction");
   //     break;
    }
    else if (array[--Y][X]==string[1])
    {
        //Success in finding in X-Y+ direction
        printf("Letter 2 of %sis found at %d,%d",string,X,Y);
        for (a=2;a<length;a++)
        {
            if (array[--Y][--X]==string[a])
                printf("\nLetter %d of %sis found at %d,%d",a+1,string,X,Y);
        }
        printf("\n\nWord found in X-Y+ direction");
   //     break;
    }
  }
    else
    {



    }

        }
       printf("\n%d|%d\n", X,Y);
       break;
    }

//End of file opening correctly process

printf("\n");
system("pause");
return 0;
}

データファイル:

M N O S L I W E R E L Y T L E A G N
A H O O V E R T A Y L O R V E N N A
D F D R O O S E V E L T O N O M I M
I N T P M H I E G D I L O O C O D U
S O N L I J Q A D A M S S R N N R R
O X L O G E F F M O I R E E G R A T
N I B T S O R A O R M O V A W O H N
F N H U R R B C R N L R E G B E W E
R O S D C O E A E I O N L A U A J R
K W U N L H H F N I O S T N S W A U
E R B A J B A C F S S M N H H R D B
N E W L O T O N K E C E I H T H A N
N T H E H L A C A K J N N H O I M A
E R G V N C A F I N G H U H A J S V
D A R E S J C N T T A R N B O Y A E
Y C A L O D L N O S I R R A H W E O
N E N C N E T N N O T N I L C O E S
D A T Y Y P O L K G A R F I E L D R
4

1 に答える 1

3

問題の 1 つは、次の場所に が不適切に配置されていることですbreak;

        }
       printf("\n%d|%d\n", X,Y);
       break;
    }

//End of file opening correctly process

これにより、1 回の反復後に外側のループが終了します。ただし、それを取り除くことは万能薬ではありません。

もう 1 つの問題は、空のelse { }句です。その中に入れると、それはかなり実行されますprintf("Ooops\n");

配列の添え字が正のままであることを確認するのに十分な注意を払っていないようです。また、スキャンコードで X と Y を再度設定せずに編集しているように見えるため、外側の検索ループを汚します。2 つの未使用の変数 M と N があり、代わりに使用することを考えていた可能性があります。しかし、どうにかして X と Y を踏みにじるのをやめなければなりません。

もう 1 つの問題は、ユーザーからの入力を確認していないことです ( if (fgets(string, sizeof(string), stdin) == 0) return 0;EOF を検出して終了するため)。もう 1 つの問題は、入力文字列の末尾から改行を削除していないことです。

それらを処理し、検索対象の単語をエコーするようにコードを変更しました。入力hooverした出力には次のものが含まれていました。

Please enter the word to be searched:
Searching for: [HOOVER]
Oops!
Oops!
Oops!
Oops!
Oops!
Oops!
Oops!
Oops!
Oops!
Oops!
Oops!
Oops!
Oops!
Oops!
Oops!
Oops!
Oops!
Oops!

18|0
Oops!

Letter 1 of HOOVERis found at 1,1
Letter 2 of HOOVERis found at 2,0

Word found in Y+X+ direction
6|-4
Oops!
Oops!
Oops!

その後、非常に退屈になり、継続的に繰り返されました(これbreak;は、上部に記載されているものを削除した後です.

そのようなモノリシックにすべてのコードを配置するのではなく、実際にいくつかの関数を作成する必要がありますmain()search_from_here()文字列、配列、および開始する X、Y 座標が指定された を使用できます。単語が見つからない場合は 0 を返し、見つかった場合は 1 を返します。


このコードは使用できませんが、機能しているようです。必要に応じてforループ内で変数を宣言するなど、基本的な C99 機能を使用します。

#include <ctype.h>
#include <stdio.h>
#include <string.h>

static int prompt_for(char *buffer, size_t buflen);
static int search_direction(char array[18][18], char *string, int length, int X, int Y, int dx, int dy);
static int search_from(char array[18][18], char *string, int length, int X, int Y);

int main(void)
{
    int X, Y, length;
    char array[18][18], string[50];

    printf("WORDSEARCH SOLVER - PRESS CTRL-C TO QUIT\n\n");

    FILE *wsch = fopen("wrdsearch.txt", "r");

    if (!wsch)
    {
        printf("Error! File did not open.\n");
        return 1;
    }
    for (Y = 0; Y < 18; Y++)
    {
        for (X = 0; X < 18; X++)
        {
            fscanf(wsch, " %c", &array[Y][X]);
            array[Y][X] = toupper(array[Y][X]);
        }
    }
    fclose(wsch);

    printf("   ");
    for (X = 0; X < 18; X++)
        printf("%-2d", X);
    printf("\n______________________________________\n");
    for (Y = 0; Y < 18; Y++)
    {
        printf("%-2d|", Y);
        for (X = 0; X < 18; X++)
            printf("%c ", array[Y][X]);
        printf("\n");
    }

    while ((length = prompt_for(string, sizeof(string))) != EOF)
    {
        printf("Searching for: [%s]\n", string);

        int count = 0;
        for (Y = 0; Y < 18; Y++)
        {
            for (X = 0; X < 18; X++)
            {
                if (array[Y][X] == (string[0]) && search_from(array, string, length, X, Y))
                    count++;
            }
        }

        printf("Found %s %d times\n", string, count);
    }

    printf("\n");
    return 0;
}

static int prompt_for(char *buffer, size_t buflen)
{
    printf("\nPlease enter the word to be searched: ");
    if (fgets(buffer, buflen, stdin) == 0)
        return EOF;
    size_t length = strlen(buffer);
    if (buffer[length-1] == '\n')
        buffer[--length] = '\0';
    if (length == 0)
        return EOF;
    for (size_t i = 0; i < length; i++)
        buffer[i] = toupper(buffer[i]);
    return length;
}

static int search_from(char array[18][18], char *string, int length, int X, int Y)
{
    struct yx { int dy; int dx; } directions[] =
    {
        { +1, 0 }, { -1, 0 }, { +1, +1 }, { -1, +1 },
        { 0, +1 }, { 0, -1 }, { -1, -1 }, { +1, -1 },
    };
    enum { num_directions = sizeof(directions) / sizeof(directions[0]) };
    int count = 0;

    for (int i = 0; i < num_directions; i++)
    {
        if (search_direction(array, string, length, X, Y, directions[i].dx, directions[i].dy))
            count++;
    }
    return count;
}

static int search_direction(char array[18][18], char *string, int length, int X, int Y, int dx, int dy)
{
    for (int i = 1; i < length; i++)
    {
        int x = X + i * dx;
        int y = Y + i * dy;
        if (x < 0 || x >= 18 || y < 0 || y >= 18)
            return 0;
        if (array[y][x] != string[i])
            return 0;
    }

    printf("Found word %s starting at (%d,%d) to (%d,%d)\n",
           string, Y, X, Y + (length - 1) * dy, X + (length - 1) * dx);
    /* Validating search! */
    char *pad = "";
    for (int i = 0; i < length; i++)
    {
        int x = X + i * dx;
        int y = Y + i * dy;
        printf("%s%c (%d,%d)", pad, array[y][x], y, x);
        pad = ", ";
    }
    putchar('\n');

    return 1;
}

米国大統領の姓の(完全な)リストを考えると、次のようになります。

adams
arthur
buchanan
bush
carter
cleveland
clinton
coolidge
eisenhower
fillmore
ford
garfield
grant
harding
harrison
hayes
hoover
jackson
jefferson
johnson
kennedy
lincoln
madison
mckinley
monroe
nixon
obama
pierce
polk
reagan
roosevelt
taft
taylor
truman
tyler
vanburen
washington
wilson

として実行するとws < presidents、エコーされるまで名前が画面に表示されないため、すべての名前が少なくとも 1 回は検出されます。

WORDSEARCH SOLVER - PRESS CTRL-C TO QUIT

   0 1 2 3 4 5 6 7 8 9 1011121314151617
______________________________________
0 |M N O S L I W E R E L Y T L E A G N 
1 |A H O O V E R T A Y L O R V E N N A 
2 |D F D R O O S E V E L T O N O M I M 
3 |I N T P M H I E G D I L O O C O D U 
4 |S O N L I J Q A D A M S S R N N R R 
5 |O X L O G E F F M O I R E E G R A T 
6 |N I B T S O R A O R M O V A W O H N 
7 |F N H U R R B C R N L R E G B E W E 
8 |R O S D C O E A E I O N L A U A J R 
9 |K W U N L H H F N I O S T N S W A U 
10|E R B A J B A C F S S M N H H R D B 
11|N E W L O T O N K E C E I H T H A N 
12|N T H E H L A C A K J N N H O I M A 
13|E R G V N C A F I N G H U H A J S V 
14|D A R E S J C N T T A R N B O Y A E 
15|Y C A L O D L N O S I R R A H W E O 
16|N E N C N E T N N O T N I L C O E S 
17|D A T Y Y P O L K G A R F I E L D R 

Please enter the word to be searched: Searching for: [ADAMS]
Found word ADAMS starting at (4,7) to (4,11)
A (4,7), D (4,8), A (4,9), M (4,10), S (4,11)
Found word ADAMS starting at (9,16) to (13,16)
A (9,16), D (10,16), A (11,16), M (12,16), S (13,16)
Found ADAMS 2 times

Please enter the word to be searched: Searching for: [ARTHUR]
Found word ARTHUR starting at (9,16) to (14,11)
A (9,16), R (10,15), T (11,14), H (12,13), U (13,12), R (14,11)
Found ARTHUR 1 times

Please enter the word to be searched: Searching for: [BUCHANAN]
Found word BUCHANAN starting at (6,2) to (13,9)
B (6,2), U (7,3), C (8,4), H (9,5), A (10,6), N (11,7), A (12,8), N (13,9)
Found BUCHANAN 1 times

Please enter the word to be searched: Searching for: [BUSH]
Found word BUSH starting at (7,14) to (10,14)
B (7,14), U (8,14), S (9,14), H (10,14)
Found word BUSH starting at (10,2) to (7,2)
B (10,2), U (9,2), S (8,2), H (7,2)
Found BUSH 2 times

Please enter the word to be searched: Searching for: [CARTER]
Found word CARTER starting at (15,1) to (10,1)
C (15,1), A (14,1), R (13,1), T (12,1), E (11,1), R (10,1)
Found CARTER 1 times

Please enter the word to be searched: Searching for: [CLEVELAND]
Found word CLEVELAND starting at (16,3) to (8,3)
C (16,3), L (15,3), E (14,3), V (13,3), E (12,3), L (11,3), A (10,3), N (9,3), D (8,3)
Found CLEVELAND 1 times

Please enter the word to be searched: Searching for: [CLINTON]
Found word CLINTON starting at (16,14) to (16,8)
C (16,14), L (16,13), I (16,12), N (16,11), T (16,10), O (16,9), N (16,8)
Found CLINTON 1 times

Please enter the word to be searched: Searching for: [COOLIDGE]
Found word COOLIDGE starting at (3,14) to (3,7)
C (3,14), O (3,13), O (3,12), L (3,11), I (3,10), D (3,9), G (3,8), E (3,7)
Found COOLIDGE 1 times

Please enter the word to be searched: Searching for: [EISENHOWER]
Found word EISENHOWER starting at (8,8) to (17,17)
E (8,8), I (9,9), S (10,10), E (11,11), N (12,12), H (13,13), O (14,14), W (15,15), E (16,16), R (17,17)
Found EISENHOWER 1 times

Please enter the word to be searched: Searching for: [FILLMORE]
Found word FILLMORE starting at (7,0) to (0,7)
F (7,0), I (6,1), L (5,2), L (4,3), M (3,4), O (2,5), R (1,6), E (0,7)
Found FILLMORE 1 times

Please enter the word to be searched: Searching for: [FORD]
Found word FORD starting at (5,6) to (8,3)
F (5,6), O (6,5), R (7,4), D (8,3)
Found FORD 1 times

Please enter the word to be searched: Searching for: [GARFIELD]
Found word GARFIELD starting at (17,9) to (17,16)
G (17,9), A (17,10), R (17,11), F (17,12), I (17,13), E (17,14), L (17,15), D (17,16)
Found GARFIELD 1 times

Please enter the word to be searched: Searching for: [GRANT]
Found word GRANT starting at (13,2) to (17,2)
G (13,2), R (14,2), A (15,2), N (16,2), T (17,2)
Found GRANT 1 times

Please enter the word to be searched: Searching for: [HARDING]
Found word HARDING starting at (6,16) to (0,16)
H (6,16), A (5,16), R (4,16), D (3,16), I (2,16), N (1,16), G (0,16)
Found HARDING 1 times

Please enter the word to be searched: Searching for: [HARRISON]
Found word HARRISON starting at (9,6) to (2,13)
H (9,6), A (8,7), R (7,8), R (6,9), I (5,10), S (4,11), O (3,12), N (2,13)
Found word HARRISON starting at (15,14) to (15,7)
H (15,14), A (15,13), R (15,12), R (15,11), I (15,10), S (15,9), O (15,8), N (15,7)
Found HARRISON 2 times

Please enter the word to be searched: Searching for: [HAYES]
Found word HAYES starting at (12,13) to (16,17)
H (12,13), A (13,14), Y (14,15), E (15,16), S (16,17)
Found HAYES 1 times

Please enter the word to be searched: Searching for: [HOOVER]
Found word HOOVER starting at (1,1) to (1,6)
H (1,1), O (1,2), O (1,3), V (1,4), E (1,5), R (1,6)
Found HOOVER 1 times

Please enter the word to be searched: Searching for: [JACKSON]
Found word JACKSON starting at (14,5) to (8,11)
J (14,5), A (13,6), C (12,7), K (11,8), S (10,9), O (9,10), N (8,11)
Found JACKSON 1 times

Please enter the word to be searched: Searching for: [JEFFERSON]
Found word JEFFERSON starting at (12,10) to (4,2)
J (12,10), E (11,9), F (10,8), F (9,7), E (8,6), R (7,5), S (6,4), O (5,3), N (4,2)
Found JEFFERSON 1 times

Please enter the word to be searched: Searching for: [JOHNSON]
Found word JOHNSON starting at (10,4) to (16,4)
J (10,4), O (11,4), H (12,4), N (13,4), S (14,4), O (15,4), N (16,4)
Found word JOHNSON starting at (13,15) to (7,9)
J (13,15), O (12,14), H (11,13), N (10,12), S (9,11), O (8,10), N (7,9)
Found JOHNSON 2 times

Please enter the word to be searched: Searching for: [KENNEDY]
Found word KENNEDY starting at (9,0) to (15,0)
K (9,0), E (10,0), N (11,0), N (12,0), E (13,0), D (14,0), Y (15,0)
Found KENNEDY 1 times

Please enter the word to be searched: Searching for: [LINCOLN]
Found word LINCOLN starting at (7,10) to (13,4)
L (7,10), I (8,9), N (9,8), C (10,7), O (11,6), L (12,5), N (13,4)
Found LINCOLN 1 times

Please enter the word to be searched: Searching for: [MADISON]
Found word MADISON starting at (0,0) to (6,0)
M (0,0), A (1,0), D (2,0), I (3,0), S (4,0), O (5,0), N (6,0)
Found MADISON 1 times

Please enter the word to be searched: Searching for: [MCKINLEY]
Found word MCKINLEY starting at (10,11) to (17,4)
M (10,11), C (11,10), K (12,9), I (13,8), N (14,7), L (15,6), E (16,5), Y (17,4)
Found MCKINLEY 1 times

Please enter the word to be searched: Searching for: [MONROE]
Found word MONROE starting at (2,15) to (7,15)
M (2,15), O (3,15), N (4,15), R (5,15), O (6,15), E (7,15)
Found MONROE 1 times

Please enter the word to be searched: Searching for: [NIXON]
Found word NIXON starting at (7,1) to (3,1)
N (7,1), I (6,1), X (5,1), O (4,1), N (3,1)
Found NIXON 1 times

Please enter the word to be searched: Searching for: [OBAMA]
Found word OBAMA starting at (8,5) to (4,9)
O (8,5), B (7,6), A (6,7), M (5,8), A (4,9)
Found OBAMA 1 times

Please enter the word to be searched: Searching for: [PIERCE]
Found word PIERCE starting at (3,3) to (8,8)
P (3,3), I (4,4), E (5,5), R (6,6), C (7,7), E (8,8)
Found PIERCE 1 times

Please enter the word to be searched: Searching for: [POLK]
Found word POLK starting at (17,5) to (17,8)
P (17,5), O (17,6), L (17,7), K (17,8)
Found POLK 1 times

Please enter the word to be searched: Searching for: [REAGAN]
Found word REAGAN starting at (4,13) to (9,13)
R (4,13), E (5,13), A (6,13), G (7,13), A (8,13), N (9,13)
Found REAGAN 1 times

Please enter the word to be searched: Searching for: [ROOSEVELT]
Found word ROOSEVELT starting at (1,12) to (9,12)
R (1,12), O (2,12), O (3,12), S (4,12), E (5,12), V (6,12), E (7,12), L (8,12), T (9,12)
Found word ROOSEVELT starting at (2,3) to (2,11)
R (2,3), O (2,4), O (2,5), S (2,6), E (2,7), V (2,8), E (2,9), L (2,10), T (2,11)
Found ROOSEVELT 2 times

Please enter the word to be searched: Searching for: [TAFT]
Found word TAFT starting at (11,5) to (14,8)
T (11,5), A (12,6), F (13,7), T (14,8)
Found TAFT 1 times

Please enter the word to be searched: Searching for: [TAYLOR]
Found word TAYLOR starting at (1,7) to (1,12)
T (1,7), A (1,8), Y (1,9), L (1,10), O (1,11), R (1,12)
Found TAYLOR 1 times

Please enter the word to be searched: Searching for: [TRUMAN]
Found word TRUMAN starting at (5,17) to (0,17)
T (5,17), R (4,17), U (3,17), M (2,17), A (1,17), N (0,17)
Found TRUMAN 1 times

Please enter the word to be searched: Searching for: [TYLER]
Found word TYLER starting at (0,12) to (0,8)
T (0,12), Y (0,11), L (0,10), E (0,9), R (0,8)
Found TYLER 1 times

Please enter the word to be searched: Searching for: [VANBUREN]
Found word VANBUREN starting at (13,17) to (6,17)
V (13,17), A (12,17), N (11,17), B (10,17), U (9,17), R (8,17), E (7,17), N (6,17)
Found VANBUREN 1 times

Please enter the word to be searched: Searching for: [WASHINGTON]
Found word WASHINGTON starting at (7,16) to (16,7)
W (7,16), A (8,15), S (9,14), H (10,13), I (11,12), N (12,11), G (13,10), T (14,9), O (15,8), N (16,7)
Found WASHINGTON 1 times

Please enter the word to be searched: Searching for: [WILSON]
Found word WILSON starting at (0,6) to (0,1)
W (0,6), I (0,5), L (0,4), S (0,3), O (0,2), N (0,1)
Found WILSON 1 times

Please enter the word to be searched: 
于 2013-12-01T21:57:57.943 に答える