繁体   English   中英

如何在 C++ 中使用堆栈反转字符串中单词的顺序

[英]How to reverse order of words in a string using stack in C++

我试图在 C++ 中使用 Stack 反转字符串中包含的单词的顺序,但是我在最终输出中的字符串开头得到了空格。

请帮我找出错误并解决它。

这是我的代码:

#include <iostream>
#include <stack>
#include <string>
using namespace std;

int main()
{
    int number;
    cin >> number; // number of strings to reverse

    for(int i = 0; i <= number; i++)
    {
        string str;
        getline(cin, str); // input

        std::stack<std::string> s; //stack
        string str1 = "";

        for(int i = 0; i <= str.length(); i++)
        {
            if(str[i] == ' ' || str[i] == '\0')
            { // add the word whenever it encounters a space
                s.push(str1); //push the string
                str1 = "";
            }
            else
                str1 += str[i];
        }

        while(!s.empty())
        { // output
            cout << s.top(); // simple displaying without space
            cout << " ";
            s.pop();
        }
    }

    cout << '\n';
}

输入:

2
Reverse this String
OOP and DS

输出:

         String this Reverse 
DS and OOP 

预期输出:

String this Reverse
DS and OOP

您已接近解决方案,但您遇到了不直观的行为。 你的问题是,当你cin的数量,按Enter键按下,结束时也采取下列getline ,导致一个空字符串。 所以getline总共给了你 3 个字符串,这显然不是你想要的:你想要 2 个,第一个是“反转这个字符串”,第二个是“OOP 和 DS”,仅此而已。 你所做的是与 3 一起工作,因为一开始有一个“幽灵”。 您在i的循环中使用了“奇怪的”退出条件(通常使用i<number ,但您使用了i<=number ),这让我认为您一定已经注意到,在 2 次迭代中您跳过了“OOP 和 DS” ,并且您尝试解决问题,但您找到了一种解决方法,而不是应用正确的解决方案。

正如其他人所说,您可以添加cin.ignore(10000,'\\n'); 来解决问题。 这样, getline将捕获正确数量的行(即 2)。 然后你要恢复正确的退出条件,也就是

for(int i = 0; i < number; i++)

另一个循环看起来也很可疑:

for(int i = 0; i <= str.length(); i++)

在这里你做了同样的事情(你使用<=而不是< )但结果是没关系,因为你正在读取字符串末尾的一个字符,这会给你你正在检查的终止字符 '\\0'因为,所以没关系。

除此之外,我刚刚移动了cout << endl; 在 for 循环内,在打印了每个还原的行之后。 哦,我已经将内循环的变量从i更改为j :最好避免重复使用相同的名称( i已被外循环使用),因为它们可能会造成混淆(尽管在这种情况下它们运行良好) .

这是最终结果(我还添加了几个cout用于调试,但我留下了评论):

#include <iostream>
#include <stack>
#include <string>
using namespace std;

int main()
{
    int number;
    cin >> number; // number of strings to reverse
    cin.ignore(10000,'\n');

    for(int i = 0; i < number; i++)
    {
        string str;
        getline(cin, str); // input
        //cout << "Debug: i = " << i << ", string = " << str << endl;

        std::stack<std::string> s; //stack
        string str1 = "";

        for(int j = 0; j <= str.length(); j++)
        {
            if(str[j] == ' ' || str[j] == '\0')
            { // add the word whenever it encounters a space
                //cout << "Pushing '" << str1 << "'" << endl;
                s.push(str1); //push the string
                str1 = "";
            }
            else
                str1 += str[j];
        }

        while(!s.empty())
        { // output
            cout << s.top(); // simple displaying without space
            cout << " ";
            s.pop();
        }
        cout << endl;
    }

}

Fabio Turati 拥有比我更好的理由和更好的措辞,所以在这一点上,我只是将其添加为一个更优雅的解决方案,并展示一些解决 OP 将遇到的其他陷阱的解决方案。

#include <iostream>
#include <stack>
#include <string>
#include <limits> // needed by std::numeric_limits<std::streamsize>::max()
#include <sstream> // needed by std::stringstream

// my hatred of using namespace std; knows no bounds so I've replaced it, only
// pulling in a few conveniences
using std::cin;
using std::cout;
using std::endl;

int main()
{
    int number; 
    cout << "Please input the number of strings to reverse" << endl;
    // give the user a prompt so they know what to do
    while (! (cin >> number) || number <= 0) // will loop until the user gives
                                             // us a good number and the number
                                             // is not 0
    {
        cin.clear(); // clear the error flag
        cout << "try again, wise guy." << endl; // mock user's stupidity
        cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
        // blow away whatever else user typed in up to the EOL or a few 
        // gajillion entered characters, whichever comes first.
    }
    // OK so we finally got a usable number from the user.
    cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
    // throw away anything else the user typed because we don't want to reverse it.
    for(unsigned int i = 0; i < number; i++) // reduced the range of the for loop
    {
        std::string str;
        cout << "Please input a strings to reverse" << endl; 
        // let the user know what's expected
        std::getline(cin, str);
        std::stringstream line(str); // allows us to easily split words just like cin
        std::stack<std::string> wordstack; // more descriptive name. Helps in debugging
        std::string word; //more descriptive name

        while (line >> word) // don't need a for loop here anymore
        { //See? Parsing made easy!
            wordstack.push(word); //push the string
        }

        while(!wordstack.empty())
        { // output
            cout << wordstack.top() << " ";
            wordstack.pop();
        }
        cout << endl; // \n does not force the output to the console. endl does,
                      // but  as a result it is much slower. This happens once
                      // per string and makes the output look prettier, so it's
                      // worth it.
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM