C++ 需要一些关于 Pig Latin 字符串的建议

Posted

技术标签:

【中文标题】C++ 需要一些关于 Pig Latin 字符串的建议【英文标题】:C++ Need some advices with Pig Latin string 【发布时间】:2020-12-22 15:15:13 【问题描述】:

我需要用Pig Latin形式写一个句子,我几乎成功了,除了1个案例,我几乎放弃了 例如 : 如果我的单词以 a\e\o\u\i 开头,这个词看起来就像 easy -> easyway , apple -> appleway

如果它不是以我上面写的字母开头 它看起来像这样:box -> oxbay , king -> ingkay

我成功使用了粗体部分,但在第一部分以 \e\o\u\i 开头的字母开头,我不知道将 w 放在哪里,需要一些帮助

这是我的代码,在此先感谢

#include <iostream>

//Since those are used in ALL function of program, it wont hurt to set it to global
//Else it is considered EVIL to declare global variables
const int maxLine = 100;
char phraseLine[maxLine] =  '\0' ;

void pigLatinString();

using namespace std;


void main()

    // Displayed heading of program
    
    cout << "* You will be prompted to enter a string of *" << endl;
    cout << "* words. The string will be converted into  *" << endl;
    cout << "* Pig Latin and the results displayed.      *" << endl;
    cout << "* Enter as many strings as you would like.  *" << endl;
    

    //prompt the user for a group of words or press enter to quit
    cout << "Please enter a word or group of words. (Press enter to quit)\n";
    cin.getline(phraseLine, 100, '\n');
    cout << endl;

    // This is the main loop. Continue executing until the user hits 'enter' to quit.
    while (phraseLine[0] != '\0')
    

        // Display the word (s) entered by the user
        cout << "You entered the following: " << phraseLine << endl;

        // Display the word (s) in Pig Latin
        cout << "The same phrase in Pig latin is: ";
        pigLatinString();
        cout << endl;

        //prompt the user for a group of words or press enter to quit
        cout << "Please enter a word or group of words. (Press enter to quit)\n";
        cin.getline(phraseLine, 100, '\n');
    
    return;



void pigLatinString() //phraseLine is a cstring for the word,  maxline is max length of line
 //variable declarations
    char tempConsonant[10];
    tempConsonant[0] = '\0';
    int numberOfConsonants = 0;
    char previousCharacter = ' ';
    char currentCharacter = ' ';
    bool isInWord = 0;

    // for loop checking each index to the end of whatever is typed in
    for (int i = 0; i < maxLine; i++)
    

        //checking for the end of the phraseline 
        if (phraseLine[i] == '\0')
        //checking to see if it's in the word
            if (isInWord)
            //checking to see that there wasn't a space ahead of the word and then sending the cstring + ay to the console
                if (previousCharacter != ' ')
                    cout << tempConsonant << "ay" << endl;
            
            return;
        

        // this covers the end of the word condition
        if (isInWord)
        // covers the condition of index [i] being the space at the end of the word
            if (phraseLine[i] == ' ')
            
                // spits out pig latin word, gets you out of the word, flushes the temp consonants array and resets the # of consonants to 0
                cout << tempConsonant << "ay";
                isInWord = 0;
                tempConsonant[0] = '\0';
                numberOfConsonants = 0;
            
            cout << phraseLine[i] ;

        
        else
        //this covers for the first vowel that makes the switch
            if (phraseLine[i] != ' ')
            // sets the c string to what is in the phraseline at the time and makes it capitalized
                char currentCharacter = phraseLine[i];
                currentCharacter = toupper(currentCharacter);

                // this takes care of the condition that currentCharacter is not a vowel
                if ((currentCharacter != 'A') && (currentCharacter != 'E') &&
                    (currentCharacter != 'I') && (currentCharacter != 'O') && (currentCharacter != 'U'))
                    //this sets the array to temporarily hold the consonants for display before the 'ay'
                //this sets the null operator at the end of the c string and looks for the next consonant
                    tempConsonant[numberOfConsonants] = phraseLine[i];
                    tempConsonant[numberOfConsonants + 1] = '\0';
                    numberOfConsonants++;
                
                else
                // this sets the boolean isInWord to true and displays the phraseline
                    isInWord = 1;
                    cout << phraseLine[i];
                
            
            else
            
                cout << phraseLine[i] ;
            
        

        previousCharacter = phraseLine[i];
    
    return;

【问题讨论】:

【参考方案1】:

您需要考虑两个条件。 if您的单词以元音开头,只需在单词末尾添加“way”,else移动第一个字母并在末尾添加“ay”。

使用std::string 代替C 字符串可以使这项任务变得更简单。这是因为您现在不再担心超出长度或丢失空字符。它还允许更轻松地访问标准库算法。

#include <algorithm>
#include <iostream>
#include <string>

std::string make_pig_latin(const std::string& word) 
  std::string vowels("aeiou");
  std::string newWord(word);

  if (newWord.find_first_not_of(vowels) == 0) 
    // Word starts with a consanant
    std::rotate(newWord.begin(), newWord.begin() + 1, newWord.end());
    newWord += "ay";
   else 
    newWord += "way";
  

  return newWord;


int main() 
  std::cout << make_pig_latin("apple") << '\n'
            << make_pig_latin("box") << '\n'
            << make_pig_latin("king") << '\n'
            << make_pig_latin("easy") << '\n';

上面的函数重点介绍了如何构建转化结构。您只需要知道您的单词是否以元音开头,然后采取适当的措施。

输出:

appleway
oxbay
ingkay
easyway

我没有得到你必须关心“电话”之类的词的印象。

查看您的代码,您应该尝试更好地分离您的关注点。 Pig Latin 更容易一次完成一个单词,但是您的 Pig Latin 函数中有字符串拆分代码和许多“非 Pig Latin”代码。您的 main 可以处理获取输入。您可能应该有一个单独的函数来将行分解为单个单词,最好使用std::vector 来保存单词,因为它可以按需增长,并且不必预先知道特定的容量。然后,您遍历您的单词数组并单独翻译它们。根据您的实际要求,您甚至可能不必存储翻译后的单词,只需将它们直接打印到屏幕上即可。

这是相同的程序,但现在它可以分隔单词。注意 pig latin 函数不需要更改(很多,我添加了大写元音只是因为我不想费心转换单词)以便添加添加的功能。

#include <algorithm>
#include <iostream>
#include <iterator>
#include <sstream>
#include <string>
#include <vector>

std::string make_pig_latin(const std::string& word) 
  std::string vowels("aeiouAEIOU");
  std::string newWord(word);

  if (newWord.find_first_not_of(vowels) == 0) 
    // Word starts with a consanant
    std::rotate(newWord.begin(), newWord.begin() + 1, newWord.end());
    newWord += "ay";
   else 
    newWord += "way";
  

  return newWord;


int main() 
  std::string phrase(
      "A sentence where I say words like apple box easy king and ignore "
      "punctuation");

  std::istringstream sin(phrase);
  std::vector<std::string> words(std::istream_iterator<std::string>(sin), );

  for (auto i : words) 
    std::cout << make_pig_latin(i) << ' ';
  

输出:

Away entencesay hereway Iway aysay ordsway ikelay appleway oxbay easyway ingkay andway ignoreway unctuationpay

【讨论】:

我不能使用像 sstd: 这样的动作和算法的东西,因为我没有在课堂上学习它,所以这个解决方案不可用;(这就是为什么我这样做的原因 我知道。仅仅因为您不能直接复制/粘贴我的代码并不意味着您不能将相同的逻辑应用于您的代码。例如,您仍然可以检查您的单词是否以元音开头。这始终是我的学生在早期面临的最大障碍。 这与代码行无关。这是关于获取代码的思考过程。 我已经提供了算法(完成任务所需的步骤)。 这是最难的部分。您可以轻松地确定您的代码在哪里执行相同的操作并进行适当的更改。 istringstream 业务?我将句子分解为单个单词。你有代码。将该代码从您的猪拉丁函数中取出并放入它自己的代码中。如果您访问该网站希望为您完成作业,您会感到失望。你特别问如何在以元音开头的单词上做你的猪拉丁语。我提供了一个骨架。你应该能够拿走你拥有的东西并重新排列它的部分以适应骨架。

以上是关于C++ 需要一些关于 Pig Latin 字符串的建议的主要内容,如果未能解决你的问题,请参考以下文章

PL/SQL 能否可靠地转换为 Pig Latin 或带有 Pig Latin 和 Hive 的 Oozie 管道

在 Pig Latin 中使用 FOREACH 阅读汽车时遇到问题

Pig Latin 中不区分大小写的搜索

使用 Pig latin 从文件中获取最大日期

我可以在 Apache Pig Latin 中将命令拆分为多行吗?

如何优化 PIG latin 中的 group by 语句?