2014-12-02 55 views
1

所以我有一個程序的全部功能,可以將英文翻譯成豬拉丁文。在逆向翻譯中,我有大約80%的功能。豬拉丁語翻譯 - 反向翻譯錯誤

我有兩個問題:

首先從豬拉丁語翻譯回英文的時候,它增加了在第一個輸入字的結尾有些胡言亂語它運行到比7個字符長。對於該短語中的任何其他單詞,它都不會再執行此操作,只有在從Pig Latin轉換爲英文時纔會執行此操作。

第二個更多是一個邏輯問題。我想不出如何檢查英文單詞以T開頭並以元音結尾的情況。例如:time翻譯成P.L.將是imetay。然而,雖然不是一個真正的單詞,eim也可以翻譯爲P.L.中的imetay。如果沒有檢查原始英語短語,怎麼可以判斷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; 
 
}

+0

我喜歡你的問題。答案實際上是相當重要的。有趣的是,拉丁不是雙射。 – 2014-12-02 23:40:34

+0

在main中,case 4測試'input'但後來使用'trans'我認爲它應該測試'trans'然後使用'trans' – user3629249 2014-12-03 03:11:19

+0

有很多調用malloc,但只有'parse'是free'd。順便說一句:來自malloc的返回值應該總是被測試以驗證操作是否成功。 – user3629249 2014-12-03 03:12:30

回答

1

當我瞭解的Pig Latin, 'EIM' 不會被譯爲imetay,但imeway。這似乎反映了here,但我肯定不會在此聲明教學優勢,所以我不確定這是否有幫助。

一對夫婦的其他東西,可能是有用的:

  • 我相信cld2latest release檢測豬拉丁 - 也許你會發現一些有用的代碼存在。

  • 對於像這樣的事情的非技術方面,我強烈建議wordreference.com論壇。不知道他們是否有專門針對Pig Latin的板子,所以可以試試「僅限英語」。

令人敬畏的項目!