尝试到循环通过字母表和append/prepend到字符串在c

vx6bjr1n  于 2023-03-01  发布在  其他
关注(0)|答案(1)|浏览(111)

我该怎么做呢?我试过用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;
}

任何帮助将不胜感激!

0md85ypi

0md85ypi1#

为了生成目标字符串的多个版本,使用"工作缓冲区"。下面是一个仅使用两个单词并将前缀/后缀范围限制为仅'a'到'e'的演示。(考虑到没有英文单词以'q'结尾,因此可以节省许多机器周期。)

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

int main( void ) {
    char *words[] = { "foo", "bar" };

    for( int i = 0; i < 2; i++ )
        for( char c = 'a'; c <= 'e'; c++ ) { // only 'a' to 'e' for demo
            char wrk[ 100 ]; // NB: a working buffer...

            sprintf( wrk, "%c%s", c, words[i] );

            printf( "'%s' & ", wrk ); // output to demo

            sprintf( wrk, "%s%c", words[i], c );

            printf( "'%s'\n", wrk ); // output to demo
        }

    return 0;
}
'afoo' & 'fooa'
'bfoo' & 'foob'
'cfoo' & 'fooc'
'dfoo' & 'food'
'efoo' & 'fooe'
'abar' & 'bara'
'bbar' & 'barb'
'cbar' & 'barc'
'dbar' & 'bard'
'ebar' & 'bare'

相关问题