1

因此,我拥有将英语翻译成 Pig Latin 的程序的全部功能。我有大约 80% 的反向翻译功能。

我有两个问题:

首先,当从 Pig Latin 翻译回英语时,它会在第一个超过 7 个字符的输入单词的末尾添加一些乱码。它不会对短语中的任何其他单词再次执行此操作,并且仅在从 Pig Latin 转换为英语时才会执行此操作。

第二个是更多的逻辑问题。我想不出如何检查英语单词以 T 开头并以元音结尾的情况。例如:time翻译成 PL 将是imetay. 然而,虽然不是一个实际的单词,eim但也可以imetay在 PL 中翻译为 不检查原始英语短语,如何判断imetay应该是time还是eim

那里留下了一些调试行来显示反向翻译中的乱码会发生什么。

//Matthew Gerton
//Project 3 - Pig latin translator
//11/26/14

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

//structures for Node and Queue
typedef struct node
{
    char word[20];
    struct node * link;
}node;

typedef struct queue
{
    node * front;
    node * rear;
} queue;
queue *input = NULL, *trans = NULL;

//method prototypes
void break_and_translate(char * phrase, int z);
queue * buildPhrase(queue * abcd, char data[20]);
node * translate(node * data);
node * translateBack(node * nextWord);
void displayP(node * abcd);
int isWordSep(char a);
int isVowel(char a);


//main function drives switch statement method for entering, translating, displaying and clearing the queues
int main()
{
    int ch, ch2;

    char dummy;
    char * phrase;
    do
    {
        printf("\n\n1.\tInput phrase\n2.\tTranslate phrase\n3.\tDisplay phrase\n4.\tDisplay Translation\n5.\tClear current phrase and translation\n6.\tExit\n");
        printf("\nEnter your choice: ");
        scanf("%d", &ch);
        scanf("%c", &dummy);

        switch(ch)
         {

             //mallocs memory for the input phrase and scans the input phrase.   breaks the phrase into a queue and translates it.
             //then frees the memory for the phrase.
             case 1:
                phrase = (char *)malloc(1024 * sizeof(char));
                printf("Input the phrase to be translated.\n");
                gets(phrase);
                if(phrase==NULL)
                    printf("Sorry, cant read the phrase. Try again.");
                else
                  printf("Phrase recieved!!!!\n");

              break;

             //calls the method to translate the input stored in phrase
             case 2:
                printf("Are you tanslating from:\n1. English into pig latin\n2. Pig latin to english\n");
                scanf("%d", &ch2);
                scanf("%c", &dummy);
                break_and_translate(phrase, ch2);
                if(input ==NULL || trans ==NULL)
                {
                    printf("Translation uncessful. Rerun the program and try again!\n");
                    exit(0);
                }
                else
                    printf("Translation sucessfull!!!!\n");
             break;

             //Display the input phrase.
             case 3:
                if(phrase==NULL)
                    printf("No phrase entered.  Please enter a phrase to translate\n");
                else
                    printf("%s\n", phrase);
             break;

             //Display the translated phrase
             case 4:
                if(input==NULL)
                    printf("Translation has not been prepared yet.\nPlease either enter a phrase to translate, or translate the current phrase.\n");
                else
                    displayP(trans->front);
             break;

             //sets the queues back to null and frees the memory allocated to the phrase.
             case 5:
                 if(input ==NULL && trans ==NULL)
                 {
                     if(phrase == NULL)
                        printf("\nNothing to reset yet!  Enter and translate a phrase!\n");
                     else
                        printf("No tanslation yet, clearing the input phrase.\n");
                  }
                input = trans = NULL;
                free(phrase);
                phrase = NULL;
                printf("Reset sucessfull!!!!\n");
              break;

             //exit
             case 6:
                printf("Goodbye!!!!\n");
                 exit(0);

            default:
                 printf("\n\nInvalid choice. Please try again...\n");
         }
    } while(1);

    return (ch);
}

//initializes memory for a new queue
queue * new_queue()
{
    queue *s = (queue *)malloc(sizeof(queue));
    s->front = NULL;
    s->rear = NULL;
    return s;
}

//takes a queue input and string and adds a node the rear of the queue containing that string
//returns a pointer to the queue;
queue * buildPhrase(queue * abcd, char data[20])
{
    if(abcd==NULL)
    {
        abcd=new_queue();
    }
    if(abcd->rear == NULL)
    {
        abcd ->rear = (node *)malloc(sizeof(node));
        strcpy(abcd->rear->word, data);
        abcd -> rear->link = NULL;
        abcd ->front = abcd ->rear;
    }
    else
    {
        abcd ->rear->link = (node *)malloc(sizeof(node));
        abcd ->rear = abcd ->rear->link;
        strcpy(abcd->rear->word, data);
        abcd ->rear->link = NULL;
    }
    return abcd;
}

//Takes a node as an input.  Allocates memory for a new node for the latin word
//Takes the first letter from the input nodes word, moves shifts everyting left one char into the latin word
//Checks to see if the first letter was a capital letter.  If so, adds the lowecase char to the end and capitalizes the first
//Then checks to see if the first char was a vowel or capital vowel.  if so, adds t to the end of the latin word. then adds 'a' and 'y' regardless
//then returns the node for the latin translation.
node * translate(node * nextWord)
{
    char a; int b, c=0;
    a=nextWord ->word[0];
    node * latin = (node *)malloc(sizeof(node));

    if(isWordSep(a)==0)
    {
        for(b=1; b<strlen(nextWord->word); b++)
        {
            latin->word[b-1] = nextWord->word[b];
            c=b;
        }
        if((a>=65) && (a<= 91))
        {
            latin->word[0] = (latin->word[0]-32);
            latin->word[c++] = (a+32);
        }
        else
            latin->word[c++] = a;

        if(isVowel(a)==1)
        {
            latin->word[c++]='t';
        }
        latin->word[c++]='a';
        latin->word[c++]='y';
    }
    return latin;
}

//takes the input phrase as a parameter.  goes through the phrase until a "whitespace char" is found
//when one is found allocates memory for 2 node pointers, coppies the word up until that point to one pointer
//passes that pointer to the trsanslate method, translates it an returns it as the second pointer.  It then adds the punctuation
//to the end of each word then passes each node to the build queue method.  Then frees the memory for the nodes and resets the word array
void break_and_translate(char * phrase, int z)
{
    int space =0, b=0, c=0;
    char end, word[20];
    memset(word, '\0', strlen(word));
    end = phrase[0];

    while(end != '\0')
    {
        end = phrase[b];
        printf("END: %c\n", end);
        if(isWordSep(end)==0)
        {
            word[space]= end;
            space++;
            printf("WORD: %s\nstrlen WORD: %d\n", word, strlen(word));
        }
        else
        {

            node * temp = (node *)malloc(sizeof(node));
            node * temp2 = (node *)malloc(sizeof(node));

            strcpy(temp->word, word);
            if(z==1)
                temp2 = translate(temp);
            else
                temp2 = translateBack(temp);
            c = strlen(temp2->word);
            temp2->word[c]= word[space] = end;
            strcpy(temp->word, word);
           // printf("\n%s temp word\n%s temp2 word\n", temp->word, temp2->word);
            input = buildPhrase(input, temp->word);
            trans = buildPhrase(trans, temp2->word);
            memset(word, '\0', strlen(word));
            free(temp);
            free(temp2);
            space=0;
            printf("WORD: %s\n", word);
        }
        b++;
    }
}

//takes a pointer to the head of a queue and prints each word of each node.
void displayP(node * abcd)
{
    int a = 0;
    node *ptr =  (node *) malloc(sizeof(node));
    ptr = abcd;
    printf("\n");
    while(ptr != NULL)
    {
        printf("%s",ptr->word);
        a++;
        ptr = ptr->link;
    }
    free(ptr);
}
node * translateBack(node * nextWord)
{
    char a, x, y, z; int b, c=0, d;
    node * latinBack = (node *)malloc(sizeof(node));
    strcpy(latinBack->word, nextWord->word);
    z = latinBack->word[0];
    d = strlen(latinBack ->word);
    if(isWordSep(z)==0)
    {
        a=latinBack ->word[d-3];
        if((isVowel(a)==0)&&(a!='t'))
        {
            latinBack->word[d-2] = latinBack->word[d];
        }
        else if(a=='t')
        {
            x = nextWord ->word[d-4];
            y = nextWord ->word[d-5];
            if((isVowel(x)==1)&&(isVowel(y)==1))
            {
                latinBack->word[d-3] = latinBack->word[d];
                latinBack->word[d-2] = '\0';
                a=x;
            }
            else
                 latinBack->word[d-2] = latinBack->word[d];
        }
        latinBack->word[d-1] = '\0';
        latinBack->word[d] = '\0';
        for(b=strlen(latinBack->word); b>0; b--)
            latinBack->word[b] = latinBack->word[b-1];
        latinBack->word[0] = a;
        latinBack->word[strlen(latinBack->word)-1]='\0';
        z=latinBack->word[1];
        if((z>=65) && (z<= 91))
        {
            latinBack->word[0]= (latinBack->word[0]-32);
            latinBack->word[1]= (latinBack->word[1]+32);
        }
    }
    return latinBack;
}
int isWordSep(char a)
{
    if ((a==' ')||(a=='.')||(a==',')||(a=='!')||(a==';')||(a=='?')||(a=='\n')||(a=='\0'))
    return 1;
    else
    return 0;
}
int isVowel(char a)
{
    if((a == 'a')||(a=='e')||(a=='i')||(a=='o')||(a=='u')||(a == 'A')||(a=='E')||(a=='I')||(a=='O')||(a=='U'))
    return 1;
    else
    return 0;
}

4

1 回答 1

1

在我学习 Pig Latin 时,'eim' 不会被翻译为 imetay,而是 imeway。这似乎反映在这里,但我当然不会在这里断言教学优越性,所以我不确定这是否有帮助。

其他一些可能有用的东西:

  • 我相信最新版本cld2可以检测到 Pig Latin——也许你会在那里找到一些有用的代码。

  • 对于此类事情的非技术方面,我强烈推荐 wordreference.com 论坛。不知道他们是否有专门针对 Pig Latin 的板,所以不妨试试“仅限英语”的板。

很棒的项目!

于 2014-12-02T23:50:49.267 回答