首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C++猪拉丁程序

C++猪拉丁程序
EN

Code Review用户
提问于 2015-05-18 13:06:20
回答 3查看 22.6K关注 0票数 6

我只是想了解一下其他人会如何处理这个问题。我正在学习,并希望对其他技术有所了解。无论你需要什么都要批评。我想学习。我觉得这段代码很草率,逻辑也很混乱。

代码语言:javascript
复制
/*
    Pig Latin
    Write a program that reads a sentence as input and converts
    each word    to “Pig Latin.” In one version, to convert a word to
    Pig-Latin you remove the first letter and place that letter at the
    end of the word. Then you append the string “ay” to the word. Here
    is an example:
        English: I SLEPT MOST OF THE NIGHT
        Pig Latin: IAY LEPTSAY OSTMAY FOAY HETAY IGHTNAY
*/
#include <iostream>
#include <string>
using namespace std;

// takes a string argument and returns the pigLatin equivalent
string pigLatin(string);

int main()
{
    string mySentence; 

    getline(cin, mySentence);
    mySentence = pigLatin(mySentence);
    cout << mySentence << endl;

    return 0;
}

string pigLatin(string word){

    //pigLatWord holds word translated in pig latin.
    //pigLatSentence holds entire translated sentence.
    string pigLatWord, pigLatSentence = "";
    int length = 0, index = 0;

    while (word[index] != '\0'){
        // .find returns -1 if no match is found
        if (word.find(' ', index) != -1){
            length = word.find(' ', index);
            length -= index;//length - index = the number of characters in a word
            pigLatWord = word.substr(index, length);
            pigLatWord.insert(length, "ay");
            pigLatWord.insert(length, 1, word[index]);//first letter is inserted at the end of the string
            pigLatWord.erase(0, 1);// erase first letter in string
            index += length + 1;//adding one moves index from 'space' to first letter in the next word
        }
        else{
            pigLatWord = word.substr(index);
            length = pigLatWord.length();
            pigLatWord.insert(length, "ay");
            pigLatWord.insert(length, 1, word[index]);
            pigLatWord.erase(0, 1);
            index = word.length();
        }

        pigLatSentence += (pigLatWord + " ");
    }
    return pigLatSentence;
}
EN

回答 3

Code Review用户

回答已采纳

发布于 2015-05-18 13:32:08

见@Caridorc first。

使用流的全部功能.

标准流操作符将一次为您读取一个单词。

代码语言:javascript
复制
std::string word;
while(std::cin >> word)
{
     // DO STUFF.
}

以上将读取一个文件。如果你只想读一句话。读取一行,然后使用字符串流。

代码语言:javascript
复制
// Read a line
std::string line;
std::getline(std::cin, line);

// convert line to stream
std::stringstream linestream(line);

// Loop over it one word at a time.
std::string word;
while(linestream >> word)
{
     // Operate on word.
}

干燥您的代码

if语句的双方都在做相同的事情。区别在于处理最后一个单词(一个不以空格结尾)。您应该将公共代码移出if statement之外,只需将非公共代码留在if语句中即可。

代码语言:javascript
复制
    if (<test>)
    {
    }
    else
    {
    }

    // This all seems common across the two if statements.
    pigLatWord = word.substr(index);
    length = pigLatWord.length();
    pigLatWord.insert(length, "ay");
    pigLatWord.insert(length, 1, word[index]);
    pigLatWord.erase(0, 1);
    index = word.length();

需要时

声明.

尽可能地将变量声明放在使用点附近。这样,您就不需要在很远的地方查找它们的类型(这就是代码所在的位置)。它们只有在你需要的时候才会被建造(并尽快被摧毁),这样就可以防止空间的过度使用,如果你不需要它们的话,也不需要花费任何东西。

代码语言:javascript
复制
// These could be moved to the other side of the if.
// As pigWord is only used after the loop (in my new version)
string pigLatWord;

每行声明一个变量.

代码语言:javascript
复制
string pigLatWord, pigLatSentence = "";
int length = 0, index = 0;

人类在阅读代码时需要帮助。别给他们添麻烦。每行声明一个变量。这在以后重构代码时也会有所帮助。您将只移动所需的变量,源代码管理工具将发现对更改进行区分比较容易。

通过const reference.

如果不计划修改const引用传递的输入以防止副本的复制。

代码语言:javascript
复制
string pigLatin(string const& word){
             //        ^^^^^^

设计.

如果我真的要写这个,我会将Pig Latin单词的概念封装在一个类中。然后,您可以将更改本地化到一个命名良好的类中。然后,您可以使用标准例程来帮助阅读/打印。

代码语言:javascript
复制
class PigLatinWord
{
    // STUFF
};

int main()
{
    // Copies std::cin to std::cout converting to PigLatin
    // on the copy to the output stream.
    std::copy(std::istream_iterator<std::string>(std::cin),
              std::istream_iterator<std::string>(),
              std::ostream_iterator<PigLatinWord>(std::cout, " ")
             );
}
票数 14
EN

Code Review用户

发布于 2015-05-18 13:16:04

避免下列情况:

代码语言:javascript
复制
using namespace std;

请参阅:为什么“使用命名空间性病;”被认为是不好的做法?

main放在底部以避免函数存根,如下所示:

代码语言:javascript
复制
string pigLatin(string);

到2015年,您可以省略return 0以避免冗长,编译器将自动添加它。

减少main函数中的详细内容:

不需要重新分配mySentence

代码语言:javascript
复制
int main() {
    string mySentence;
    getline(cin, string mySentence);
    cout << pigLatin(mySentence) << cin;
}

我更喜欢在函数定义的同一行中使用打开大括号,但是像您这样使用它们更常见。

是更加用户友好的

如果用户没有看到任何东西,他们会认为程序正在挂起或数字正在运行,添加一点信息,或者更好地让程序接受命令行args。

不要在争论的名字里撒谎

如果我看到函数:string pigLatin(string word) {,我会假设它翻译成猪拉丁语,哼哼。当给出一个句子时,word会崩溃或出错。但是你的功能可以用一个句子?!

票数 7
EN

Code Review用户

发布于 2015-05-18 13:25:01

  • 不需要使用空引号显式初始化: pigLatSentence = "";默认的std::string构造函数已经为您完成了: pigLatSentence;
  • 由于length存储从STL函数返回的值,因此要为此使用将其键入std::size_tstd::string::size_type
  • 您可以使用std::string::npos而不是-1来处理string对象: if (word.find(‘',index) != std::string::npos)
票数 6
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/91048

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档