我该怎么做呢?我试过用for循环遍历字母表for (char c = 'a'; c <= 'z'; c++)
然后在循环中运行一个prepend/append函数,把c添加到字符串中,但是这个函数不起作用,并且输出很长的结果,它把整个字母表添加到目标单词中,或者只是一遍又一遍地添加相同的字母。
例句:这个单词是“apple”,apple,bapple,capple...等等
还有苹果苹果苹果
这是一个更大的哈希表拼写检查项目的一部分。该函数用于建议拼写错误单词的排列。代码如下。isMember函数搜索哈希表,并且工作正常-当单词在哈希表字典中时,它返回1,当单词不在哈希表字典中时,它返回0:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define BUFSIZE 256
//hash function
unsigned long hashStr(char *str, int size){
unsigned long total = 0;
for (int i = 0; i < strlen(str); i++){
total = total + str[i];
total = total * 101;
}
return total % size;
}
//define node and hash table types
typedef struct node {
char *value;
struct node *next;
} node;
typedef struct {
int size;
node **table;
} table;
//constructors for node and hash table types
node* Node(char *value, node *next){
//allocate space for node
node *newnode = malloc(sizeof(node));
newnode->value = malloc(sizeof(char) * (strlen(value) + 1));
//insert value and next
strcpy(newnode->value, value);
newnode->next = next;
//return node
return newnode;
}
table* Table(int size){
//allocate space for table
table *newtable = malloc(sizeof(table));
//allocate space for number of nodes
newtable->size = size;
newtable->table = malloc(sizeof(node *) * size);
//cycle through each table index and have it point to null
for (int i = 0; i < size; i++){
newtable->table[i] = NULL;
}
return newtable;
}
//insert to hash table
void insert(table *hashtable, char* str){
//define the position to which the string should hash
unsigned long index = hashStr(str, hashtable->size);
//create pointer to point to that index
node *ptr = hashtable->table[index];
//while the node is not equal to null
while (ptr != NULL) {
//if the node already exists don't add it
if(strcmp(ptr->value, str) == 0){
return;
}
//else continue searching until it's null
else {
ptr=ptr->next;
}
}
//if it's not a duplicate, add to hash table at the end of linked list for index
hashtable->table[index] = Node(str, hashtable->table[index]);
}
//isMember of hash table
int isMember(table *hashtable, char* str){
//get the index of the hashed word
int index = hashStr(str, hashtable->size);
//set a new node pointer to point to that index of the hash table
node *ptr = hashtable->table[index];
//while the node pointer is not equal to null
while (ptr!= NULL) {
//if the value is equal
if (strcmp(ptr->value, str) == 0)
return 1;
else
//proceed
ptr = ptr->next;
}
return 0;
}
//delete from hash table
void delete(table *hashtable, char* str){
//hash the string to delete
int position = hashStr(str, hashtable->size);
//create pointer ptr to index where it is
node *ptr = hashtable->table[position];
//create a pointer to a pointer prev to the pointer to the ht position
node **prev = &hashtable->table[position];
//search the linked list at the index for the value and delete when found
while(ptr != NULL){
if (strcmp(ptr->value, str) == 0) {
*prev = ptr->next;
free(ptr);
return;
}
else {
prev = &ptr->next;
ptr = ptr->next;
}
}
}
char* prepend(char *str, char c){
size_t i = strlen(str);
do
{
str[i+1] = str[i];
--i;
} while (i > 0);
str[0] = c;
return str;
}
char* postpend(char *str, char c){
char newstr[BUFSIZE];
int len = strlen(str);
strcpy(newstr, str);
printf("%s\n", newstr);
newstr[len] = c;
printf("postpend: %s\n", newstr);
return newstr;
}
char* removeLast(char* str){
int len = strlen(str);
str[len - 1] = '\0';
return str;
}
char* removeFirst(char* str){
str = str + 1;
return str;
}
void suggest(table *hashtable, char* str){
//find words with inverted adjacent letters
//find words with a missing letter at beginning or end
if (isMember(hashtable, removeFirst(str)) == 1){
//append misspelling to suggestions linked list
}
if (isMember(hashtable, removeLast(str)) == 1){
//append misspelling to suggestions linked list
}
/*//find words with an extra letter at beginning or end
for (int i = 0; i < 26; i++){
if (isMember(hashtable, prepend(str, 'a' + i)) == 1) {
//append misspelling to suggestions linked list
}
}
for (char c = 'a'; c <= 'z'; c++){
if (isMember(hashtable, strncat(str, (char *)c, 1) == 1)) {
//append misspelling to suggestions linked list
}
}*/
}
void printHashTable(table *hashtable){
for (int i = 0; i < hashtable->size; i++) {
printf("Row %d: [", i);
node *ptr = hashtable->table[i];
while(ptr != NULL){
printf(" %s", ptr->value);
ptr = ptr->next;
}
printf(" ]\n");
}
}
int main(int argc, char **argv)
{
char *dictionaryFilePath = argv[1]; //this keeps the path to the dictionary file file
char *inputFilePath = argv[2]; //this keeps the path to the input text file
char *check = argv[3]; // this keeps the flag to whether we should insert mistyped words into dictionary or ignore
int numOfWords=0; //this variable will tell us how much memory to allocate
int insertToDictionary;
if(strcmp(check,"add")==0)
insertToDictionary = 1;
else
insertToDictionary = 0;
////////////////////////////////////////////////////////////////////
//read dictionary file
FILE *fp = fopen(dictionaryFilePath, "r");
char *line = NULL; //variable to be used for line counting
size_t lineBuffSize = 0; //variable to be used for line counting
size_t lineSize; //variable to be used for line counting
//check if the file is accessible, just to make sure...
if(fp == NULL)
{
fprintf(stderr, "Error opening file\n");
exit(1);
}
//First, let's count number of words in the dictionary.
//This will help us know how much memory to allocate for our hash table
while((lineSize = getline(&line,&lineBuffSize,fp)) !=-1)
numOfWords++;
//Printing line count for debugging purposes.
//You can remove this part from your submission.
//printf("%d\n",numOfWords);
//HINT: You can initialize your hash table here, since you know the size of the dictionary
table *Dictionary = Table(numOfWords / 30);
//printf("size: %d", Dictionary->size);
//printHashTable(Dictionary);
//rewind file pointer to the beginning of the file, to be able to read it line by line.
fseek(fp, 0, SEEK_SET);
char wrd[BUFSIZE];
for (int i = 0; i < numOfWords; i++)
{
fscanf(fp, "%s \n", wrd);
//You can print the words for Debug purposes, just to make sure you are loading the dictionary as intended
//printf("%d: %s\n", i, wrd);
//HINT: here is a good place to insert the words into your hash table
insert(Dictionary, wrd);
//printf("added word\n");
}
fclose(fp);
//print check
//printHashTable(Dictionary);
////////////////////////////////////////////////////////////////////
//read the input text file word by word
fp = fopen(inputFilePath, "r");
//check if the file is accessible, just to make sure...
if(fp == NULL)
{
fprintf(stderr, "Error opening file\n");
return -1;
}
//HINT: You can use a flag to indicate if there is a misspleed word or not, which is initially set to 1
int noTypo=1;
//read a line from the input file
while((lineSize = getline(&line,&lineBuffSize,fp)) !=-1)
{
char *word;
//These are the delimiters you are expected to check for. Nothing else is needed here.
const char delimiter[]= " ,.:;!\n";
//split the buffer by delimiters to read a single word
word = strtok(line, delimiter);
//read the line word by word
while(word!=NULL)
{
// You can print the words of the input file for Debug purposes, just to make sure you are loading the input text as intended
printf("%s\n", word);
// HINT: Since this nested while loop will keep reading the input text word by word, here is a good place to check for misspelled words
//if the word is not in the dictionary
if (isMember(Dictionary, word) == 0){
noTypo = 0;
//print the misspelled word
printf("Misspelled word: %s\n", word);
//suggest other words
suggest(Dictionary, word);
//if the user typed add
if (insertToDictionary == 1){
//add the word to the dictionary
insert(Dictionary, word);
printf("inserted misspelled word");
}
}
// INPUT/OUTPUT SPECS: use the following line for printing suggestions, each of which will be separated by a comma and whitespace.
//printf("Suggestions: "); //the suggested words should follow
word = strtok(NULL,delimiter);
}
}
fclose(fp);
if(noTypo==1)
printf("No typo!\n");
// DON'T FORGET to free the memory that you allocated
return 0;
}
任何帮助将不胜感激!
1条答案
按热度按时间0md85ypi1#
为了生成目标字符串的多个版本,使用"工作缓冲区"。下面是一个仅使用两个单词并将前缀/后缀范围限制为仅'a'到'e'的演示。(考虑到没有英文单词以'q'结尾,因此可以节省许多机器周期。)