trước khi tôi hỏi bất cứ điều gì, chỉ cần cho mọi người biết rằng đây là cho vui và tôi đã đăng tất cả mã của tôi mà tôi có cho đến nay; sẽ đăng bài nhiều hơn khi mọi thứ được cố định/triển khai), xin lỗi vì bài đăng dài!Thực hiện một bộ giải scrabble
Tôi có hai câu hỏi ở đây và tôi sẽ đăng tất cả mã của tôi bên dưới.
- Tôi không thể tìm ra lý do tại sao khi nhập hơn 12 chữ cái với một số chữ cái giống nhau, tôi nhận được nhiều bản sao như int 'được chấp nhận' của tôi được đặt ra để tránh trùng lặp (hoạt động cho hầu hết các phần);
- cho đầu vào tối đa 26 chữ cái và bảng nxn (có một số chữ cái đã điền sẵn), xuất tất cả các từ có thể phù hợp với các điểm hợp lệ. Bất kỳ lời khuyên nào về cách thực hiện điều này (bảng sẽ là một mảng 2 byte 1 byte trong mỗi chữ cái 1)
Ngay bây giờ Đây chỉ là chương trình dựa trên văn bản chấp nhận tối đa 26 chữ cái và đầu ra tất cả các từ có giá trị từ 200K từ + từ điển được đăng ở đây:
http://www.calvin.edu/~rpruim/scrabble/ospd3.txt
chương trình C dưới đây đòi hỏi sự từ điển để được cắt thành 26 file chứa tất cả các từ bắt đầu bằng mỗi chữ cái trong mỗi tập tin (tất cả một từ nào trong tệp 'a' vv ...) perl được đăng dưới đây để làm như vậy.
Lời Finder (c):
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define NUM_CHARS 26
#define MAX_WORD_LEN 20
#define WORDS_PER_LINE 12
/* Character link structure */
typedef struct char_link
{
struct char_link **cl; /* All of this links possible next characters */
short eow; /* END OF WORD (means this is the last letter of a valid word */
} CHARLINK;
/* Global found word count, used for printing '\n' char. */
unsigned short gwc = 0;
CHARLINK * _init_link(CHARLINK **link)
{
short i;
(*link)->cl = (CHARLINK **) malloc(NUM_CHARS * sizeof(CHARLINK *));
for (i = 0; i < NUM_CHARS; i++)
(*link)->cl[i] = NULL;
(*link)->eow = 0;
return (*link);
}
void _build_char_link(CHARLINK *link)
{
FILE *fp;
char *ptr, file[2];
CHARLINK *current_link = NULL;
char line_buffer[MAX_WORD_LEN];
unsigned short size = 0;
static short letter_index = 0;
int current_letter = 0;
sprintf(file, "%c", letter_index + 'a');
current_link = _init_link(&link);
if (fp = fopen(file, "r"))
{
while (fgets(line_buffer, MAX_WORD_LEN, fp) > 0)
{
/* Skip letter_index */
ptr = line_buffer + 1;
while(*ptr && (*ptr != '\n' && *ptr != '\r'))
{
current_letter = (int)(*ptr - 'a');
/* Create and jump to new link */
if (!current_link->cl[current_letter])
{
current_link->cl[current_letter] = (CHARLINK *) malloc (sizeof(CHARLINK));
current_link = _init_link(¤t_link->cl[current_letter]);
}
/* Jump to existing link */
else
current_link = current_link->cl[current_letter];
ptr++;
}
current_link->eow = 1;
/* Reset our current_link pointer to the letter_index link */
current_link = link;
}
fclose(fp);
}
else
printf("Warning: Couldn't import words for letter: %s\n", file);
letter_index++;
}
void _draw_tree(CHARLINK *link, short letter, short depth)
{
short i, tmp;
if (!depth)
{
printf("Data for letter %c\n", letter + 'a');
printf("%c\n", letter + 'a');
}
for (i = 0; i < NUM_CHARS; i++)
{
if (link->cl[i])
{
tmp = depth;
while (tmp-- >= 0)
printf("\t");
printf("%c(%d)\n", i + 'a', link->cl[i]->eow);
_draw_tree(link->cl[i], letter, depth + 1);
}
}
}
void _get_possible_words(CHARLINK *link, char *prefix, char *letters, unsigned int input_len, unsigned int depth)
{
short i, len, j;
unsigned int attempted = 0x00000000;
if (link->eow)
{
printf("\t%s", prefix);
if (++gwc == WORDS_PER_LINE)
{
printf("\n");
gwc = 0;
}
}
len = strlen(prefix);
for (i = 0; i < input_len; i++)
{
if (letters[i])
{
j = (1 << (letters[i] - 'a'));
if (!(j & attempted) && link->cl[letters[i] - 'a'])
{
prefix[len] = letters[i];
letters[i] = '\0';
_get_possible_words(link->cl[prefix[len] - 'a'], prefix, letters, input_len, depth + 1);
letters[i] = prefix[len];
prefix[len] = '\0';
}
attempted |= j;
}
}
}
int main(int argc, char *argv[])
{
short i;
/* 26 link structures for a-z */
CHARLINK root_nodes[NUM_CHARS];
printf("Building structures ");
for (i = 0; i < NUM_CHARS; i++)
{
_build_char_link(&root_nodes[i]);
printf(". ");
}
printf("Done!\n");
/* Debug, what do our trees look like? */
//for (i = 0; i < NUM_CHARS; i++)
// _draw_tree(&root_nodes[i], i, 0);
for(;;)
{
short input_len = 0;
unsigned int j = 0, attempted = 0x00000000;
char input[26] = {0};
char letters[26] = {0};
char prefix[26] = {0};
printf("Enter letters ('0' to exit): ");
gets(input); /* Yay buffer overflow */
if (input[0] == '0') break;
sprintf(letters, "%s", input);
input_len = strlen(input);
for (i = 0; i < input_len; i++)
{
j = (1 << (input[i] - 'a'));
if (!(j & attempted))
{
prefix[0] = input[i];
letters[i] = '\0';
_get_possible_words(&root_nodes[prefix[0] - 'a'], prefix, letters, input_len, 1);
letters[i] = input[i];
attempted |= j;
}
}
printf("\n");
}
return 255;
}
file được chia nhỏ (perl):
#!/usr/bin/perl
open(FH, "< words.txt");
my %w = map { $_ => {} } 'a'..'z';
while (<FH>)
{
s/\s+$//;
$w{lc $1}->{lc $_} = 1 if /^(\w)/;
}
foreach my $l (keys %w)
{
open (OUT, "> $l");
foreach my $a (keys %{$w{$l}})
{
print OUT "$a\n";
}
close OUT;
}
Nếu đây là ý tưởng thú vị của bạn, tại sao bạn không dính vào việc cố gắng tìm ra nó cho chính mình? –
tại sao không ai đăng câu hỏi ở đây tự tìm ra? Nếu bạn không muốn nhìn nó thì không. – user318747
Vì bạn đã gọi ra tràn bộ đệm, và vì bạn đang có một số "thú vị": P thay vì nhắc đến * fgets * Tôi sẽ chỉ cho bạn bài viết này về Học C++ như một Ngôn ngữ Mới (mà những người theo dõi Thẻ C trên SO không thích, nhưng whateva): http://www2.research.att.com/~bs/new_learning.pdf – HostileFork