[英]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.