如何集成前缀检查器以根据读取的文件查找完整的单词
How can I integrate a prefix checker to find complete words based on file read
问题:我可以搜索文件并根据用户输入的数字打印单词(短信号码转换),购买我应该也可以仅根据输入的部分数字查找完整的单词,因此... 72
将 return pa、ra、sa 和 sc... 在我的文件中查找单词,例如 party
、radio
、sandwich
和 scanner
。
我试过使用前缀函数,但无法正确集成它们。 startsWith
函数就是一个例子。
单词基于数字键盘,例如:Lettered Phone Keypad
代码:
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
const char numbered_letters[10][5] = {"", "", "abc", "def", "ghi", "jkl",
"mno", "pqrs", "tuv", "wxyz"};
bool startsWith(const char *pre, const char *str) {
size_t lenpre = strlen(pre),
lenstr = strlen(str);
return lenstr < lenpre ? false : strncmp(pre, str, lenpre) == 0;
}
void isEqual(char input[]) {
int i = 0;
//input[strlen(input)] = 0;
startsWith(input, input);
printf("check: %s\n", input);
//creating file
FILE *fp = fopen("words_alpha.txt", "r");
char str[32]; /* Handles largest possible string in the list which is: dichlorodiphenyltrichloroethane*/
//fseek(fp, 0, SEEK_SET);
if (fp == NULL) {
printf("Error! No file!\n");
} else {
//printf("Enter a number to be converted into a word-list");
//scanf("%s", str);
while (!feof(fp)) {
fscanf(fp, "%s", str);
i = strncmp(input, str, 32);
if (i == 0) {
printf("HIT: %s \n", input);
break;
} else {
printf("");
}
//if (strncmp(str, "hello", 32 ) == 0) { /*if strncmp finds the word and returns true, print */
// printf("%s\n", str);
}
//printf("%s\n", str);
//compareNums(num);
}
fclose(fp);
}
void printWordsUtil(int number[], int curr_digit, char output[], int n) {
// Base case, if current output word is prepared
int i;
if (curr_digit == n) {
//printf("%s ", output);
isEqual(output);
return;
}
// Try all possible characters for current digit in number[]
// and recur for remaining digits
for (i = 0; i < strlen(numbered_letters[number[curr_digit]]); i++) {
output[curr_digit] = numbered_letters[number[curr_digit]][i];
printWordsUtil(number, curr_digit + 1, output, n);/* recursive call */
if (number[curr_digit] == 0 || number[curr_digit] == 1)
return;
}
}
// A wrapper over printWordsUtil(). It creates an output array and
// calls printWordsUtil()
void printWords(int number[], int n) {
char result[n + 1];
result[n] = '[=10=]';
printWordsUtil(number, 0, result, n);
}
//Driver program
int main(void) {
int number[] = {4, 3, 9};
int n = sizeof(number) / sizeof(number[0]);
printWords(number, n);
return 0;
}
使用的文件: Words Alpha (A file with over 420k words)
感谢您提供的任何指导!
有一些错误。
你的前缀功能没问题。您替换的 strncmp
不是。
您有一个 break
命中停止在 第一个 单词匹配上,因此没有显示后续匹配项。
命中时您打印的是前缀字符串而不是单词字符串。
我已经用错误注释了你的代码并修复了它们[请原谅不必要的样式清理]:
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
const char numbered_letters[10][5] = { "", "", "abc", "def", "ghi", "jkl",
"mno", "pqrs", "tuv", "wxyz"
};
bool
startsWith(const char *pre, const char *str)
{
size_t lenpre = strlen(pre),
lenstr = strlen(str);
return lenstr < lenpre ? false : strncmp(pre, str, lenpre) == 0;
}
void
isEqual(char input[])
{
int i = 0;
int ilen = strlen(input);
// input[strlen(input)] = 0;
// NOTE/BUG: this is extraneous
#if 0
startsWith(input, input);
#endif
printf("check: '%s'\n", input);
// creating file
FILE *fp = fopen("words_alpha.txt", "r");
// NOTE/BUG: this needs to be one more to contain the nul terminater
#if 0
/* Handles largest possible string in the list which is:
dichlorodiphenyltrichloroethane */
char str[32];
#else
char str[33];
#endif
// fseek(fp, 0, SEEK_SET);
if (fp == NULL) {
printf("Error! No file!\n");
}
else {
// printf("Enter a number to be converted into a word-list");
// scanf("%s", str);
// NOTE/BUG: although feof works here, it is considered _bad_ practice
#if 0
while (!feof(fp)) {
fscanf(fp, "%s", str);
#else
while (1) {
if (fscanf(fp, "%s", str) != 1)
break;
#endif
// NOTE/BUG: this is broken
#if 0
i = strncmp(input, str, 32) == 0;
#endif
// NOTE: this works and is simpler than startsWith (which also works)
#if 0
i = strncmp(input, str, ilen) == 0;
#endif
#if 1
i = startsWith(input, str);
#endif
if (i) {
// NOTE/BUG: we want the actual word to be printed and not just the prefix
#if 0
printf("HIT: %s\n", input);
#else
printf("HIT: %s\n", str);
#endif
// NOTE/BUG: this break stops on the _first_ word match in the list but we
// want all of them
#if 0
break;
#endif
}
else {
//printf("");
}
// if (strncmp(str, "hello", 32 ) == 0) { /*if strncmp finds the word and returns true, print */
// printf("%s\n", str);
}
// printf("%s\n", str);
// compareNums(num);
}
fclose(fp);
}
void
printWordsUtil(int numbers[], int curr_digit, char output[], int n)
{
// Base case, if current output word is prepared
int i;
if (curr_digit == n) {
// printf("%s ", output);
isEqual(output);
return;
}
// NOTE: did some cleanup to understand what was going on -- [probably] not a
// bug
int numcur = numbers[curr_digit];
const char *letters = numbered_letters[numcur];
int letlen = strlen(letters);
// Try all possible characters for current digit in number[]
// and recur for remaining digits
for (i = 0; i < letlen; ++i) {
output[curr_digit] = letters[i];
printWordsUtil(numbers, curr_digit + 1, output, n); /* recursive call */
if ((numcur == 0) || (numcur == 1))
break;
}
}
// A wrapper over printWordsUtil(). It creates an output array and
// calls printWordsUtil()
void
printWords(int number[], int n)
{
char result[n + 1];
// NOTE/BUG: this will have garbage in elements 0 to (n - 1)
// NOTE/BUG: result is not used otherwise
result[n] = '[=10=]';
printWordsUtil(number, 0, result, n);
}
//Driver program
int
main(void)
{
int number[] = { 4, 3, 9 };
int n = sizeof(number) / sizeof(number[0]);
printWords(number, n);
return 0;
}
问题:我可以搜索文件并根据用户输入的数字打印单词(短信号码转换),购买我应该也可以仅根据输入的部分数字查找完整的单词,因此... 72
将 return pa、ra、sa 和 sc... 在我的文件中查找单词,例如 party
、radio
、sandwich
和 scanner
。
我试过使用前缀函数,但无法正确集成它们。 startsWith
函数就是一个例子。
单词基于数字键盘,例如:Lettered Phone Keypad
代码:
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
const char numbered_letters[10][5] = {"", "", "abc", "def", "ghi", "jkl",
"mno", "pqrs", "tuv", "wxyz"};
bool startsWith(const char *pre, const char *str) {
size_t lenpre = strlen(pre),
lenstr = strlen(str);
return lenstr < lenpre ? false : strncmp(pre, str, lenpre) == 0;
}
void isEqual(char input[]) {
int i = 0;
//input[strlen(input)] = 0;
startsWith(input, input);
printf("check: %s\n", input);
//creating file
FILE *fp = fopen("words_alpha.txt", "r");
char str[32]; /* Handles largest possible string in the list which is: dichlorodiphenyltrichloroethane*/
//fseek(fp, 0, SEEK_SET);
if (fp == NULL) {
printf("Error! No file!\n");
} else {
//printf("Enter a number to be converted into a word-list");
//scanf("%s", str);
while (!feof(fp)) {
fscanf(fp, "%s", str);
i = strncmp(input, str, 32);
if (i == 0) {
printf("HIT: %s \n", input);
break;
} else {
printf("");
}
//if (strncmp(str, "hello", 32 ) == 0) { /*if strncmp finds the word and returns true, print */
// printf("%s\n", str);
}
//printf("%s\n", str);
//compareNums(num);
}
fclose(fp);
}
void printWordsUtil(int number[], int curr_digit, char output[], int n) {
// Base case, if current output word is prepared
int i;
if (curr_digit == n) {
//printf("%s ", output);
isEqual(output);
return;
}
// Try all possible characters for current digit in number[]
// and recur for remaining digits
for (i = 0; i < strlen(numbered_letters[number[curr_digit]]); i++) {
output[curr_digit] = numbered_letters[number[curr_digit]][i];
printWordsUtil(number, curr_digit + 1, output, n);/* recursive call */
if (number[curr_digit] == 0 || number[curr_digit] == 1)
return;
}
}
// A wrapper over printWordsUtil(). It creates an output array and
// calls printWordsUtil()
void printWords(int number[], int n) {
char result[n + 1];
result[n] = '[=10=]';
printWordsUtil(number, 0, result, n);
}
//Driver program
int main(void) {
int number[] = {4, 3, 9};
int n = sizeof(number) / sizeof(number[0]);
printWords(number, n);
return 0;
}
使用的文件: Words Alpha (A file with over 420k words)
感谢您提供的任何指导!
有一些错误。
你的前缀功能没问题。您替换的 strncmp
不是。
您有一个 break
命中停止在 第一个 单词匹配上,因此没有显示后续匹配项。
命中时您打印的是前缀字符串而不是单词字符串。
我已经用错误注释了你的代码并修复了它们[请原谅不必要的样式清理]:
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
const char numbered_letters[10][5] = { "", "", "abc", "def", "ghi", "jkl",
"mno", "pqrs", "tuv", "wxyz"
};
bool
startsWith(const char *pre, const char *str)
{
size_t lenpre = strlen(pre),
lenstr = strlen(str);
return lenstr < lenpre ? false : strncmp(pre, str, lenpre) == 0;
}
void
isEqual(char input[])
{
int i = 0;
int ilen = strlen(input);
// input[strlen(input)] = 0;
// NOTE/BUG: this is extraneous
#if 0
startsWith(input, input);
#endif
printf("check: '%s'\n", input);
// creating file
FILE *fp = fopen("words_alpha.txt", "r");
// NOTE/BUG: this needs to be one more to contain the nul terminater
#if 0
/* Handles largest possible string in the list which is:
dichlorodiphenyltrichloroethane */
char str[32];
#else
char str[33];
#endif
// fseek(fp, 0, SEEK_SET);
if (fp == NULL) {
printf("Error! No file!\n");
}
else {
// printf("Enter a number to be converted into a word-list");
// scanf("%s", str);
// NOTE/BUG: although feof works here, it is considered _bad_ practice
#if 0
while (!feof(fp)) {
fscanf(fp, "%s", str);
#else
while (1) {
if (fscanf(fp, "%s", str) != 1)
break;
#endif
// NOTE/BUG: this is broken
#if 0
i = strncmp(input, str, 32) == 0;
#endif
// NOTE: this works and is simpler than startsWith (which also works)
#if 0
i = strncmp(input, str, ilen) == 0;
#endif
#if 1
i = startsWith(input, str);
#endif
if (i) {
// NOTE/BUG: we want the actual word to be printed and not just the prefix
#if 0
printf("HIT: %s\n", input);
#else
printf("HIT: %s\n", str);
#endif
// NOTE/BUG: this break stops on the _first_ word match in the list but we
// want all of them
#if 0
break;
#endif
}
else {
//printf("");
}
// if (strncmp(str, "hello", 32 ) == 0) { /*if strncmp finds the word and returns true, print */
// printf("%s\n", str);
}
// printf("%s\n", str);
// compareNums(num);
}
fclose(fp);
}
void
printWordsUtil(int numbers[], int curr_digit, char output[], int n)
{
// Base case, if current output word is prepared
int i;
if (curr_digit == n) {
// printf("%s ", output);
isEqual(output);
return;
}
// NOTE: did some cleanup to understand what was going on -- [probably] not a
// bug
int numcur = numbers[curr_digit];
const char *letters = numbered_letters[numcur];
int letlen = strlen(letters);
// Try all possible characters for current digit in number[]
// and recur for remaining digits
for (i = 0; i < letlen; ++i) {
output[curr_digit] = letters[i];
printWordsUtil(numbers, curr_digit + 1, output, n); /* recursive call */
if ((numcur == 0) || (numcur == 1))
break;
}
}
// A wrapper over printWordsUtil(). It creates an output array and
// calls printWordsUtil()
void
printWords(int number[], int n)
{
char result[n + 1];
// NOTE/BUG: this will have garbage in elements 0 to (n - 1)
// NOTE/BUG: result is not used otherwise
result[n] = '[=10=]';
printWordsUtil(number, 0, result, n);
}
//Driver program
int
main(void)
{
int number[] = { 4, 3, 9 };
int n = sizeof(number) / sizeof(number[0]);
printWords(number, n);
return 0;
}