C++ 颠倒句子中单词的顺序
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17026740/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Reversing order of words in a sentence
提问by SpiderRico
#include <iostream>
#include <cstring>
using namespace std;
void reverse(char* sentence)
{
int index = strlen(sentence) - 1;
char last = 'Howdy Mr. Mcfly?
Mcfly? Mr. Howdy
';
int hold = 0;
while ( index != 0){
while (sentence[index] != ' ')
index--;
hold = index; //keeps the index of whitespace
while (sentence[index] != last){
cout << sentence[index]; //printing till it either hits end character or whitespace.
index++;
}
last = sentence[hold]; //Keeps the whitespace
index = hold; //
}
}
int main()
{
char* sentence = new char[256];
cin.getline(sentence, 256);
reverse(sentence);
}
I want to reverse the orders of words in a sentence and you can see my attempt above.
我想颠倒句子中单词的顺序,您可以在上面看到我的尝试。
Sample intput and output should be like this:
示例输入和输出应该是这样的:
Howdy Mr. Mcfly?
Mcfly?
Where i get:
我在哪里得到:
void reverse(char* sentence)
{
int index = strlen(sentence) - 1,hold,last = 'std::string sentence = "Your sentence which contains ten words, two of them numbers";
std::stringstream stream(sentence);
std::vector<std::string> words;
for ( std::string word; stream >> word; )
{
words.push_back(word);
}
';
/*For the 1st iteration last is `std::reverse(words.begin(), word.end());
` for all others it is ` `*/
while (index >= 0)
{
/*
In your original code,
This while loop(below) will continue to keep decrementing index
even below `0`,You wont exit this while loop until you encounter a ` `.
For the 1st word of the sentence you will never come out of the loop.
Hence the check, index>=0
*/
while (index>=0 && sentence[index] != ' ')
index--;
/* You can print the whitespace later*/
hold = index - 1; // This keeps track of the last character
// of preceding word
index++; //character after space
while (sentence[index] != last)
{
cout << sentence[index];
index++;
}
last = ' ';
index = hold;
/* Dont print space after 1st word*/
if(index > 0)
cout<<" ";
}
}
int main()
{
char* sentence = new char[256];
cin.getline(sentence, 256);
reverse(sentence);
delete[] sentence; // Delete the allocated memory
}
There are many similar questions around the internet but what i want is to find error in my own code.
互联网上有很多类似的问题,但我想要的是在我自己的代码中找到错误。
采纳答案by Suvarna Pattayil
As the other answers suggest you should use std::string
which can save lot of hassles.
But just for the note,
正如其他答案所建议的那样,您应该使用std::string
它可以节省很多麻烦。但只是为了笔记,
#include <string> // for storing strings in a C++ way
#include <sstream> // to easily separate sentences into words
#include <vector> // to dynamically store arbitrary amounts of words
#include <algorithm> // for std::reverse
Tryin to keep it as close to your logic
尽量让它接近你的逻辑
回答by stefan
You can use std::string
std::vector
and std::reverse
to make things easier:
您可以使用std::string
std::vector
和std::reverse
使事情变得更容易:
index = hold;
Now you have everything separated into words. You may now want to remove question marks or other punctuation, since the logic will be easier to implement while the words are still in the correct order. For reversing, do this:
现在你把所有的东西都分成了单词。您现在可能想要删除问号或其他标点符号,因为当单词仍处于正确顺序时,逻辑将更容易实现。要倒车,请执行以下操作:
void reverse(char* sentence, const int START)
{
if(sentence[START] == '#include <sstream>
#include <iostream>
#include <list>
int main() {
char sentence[256];
std::cin.getline(sentence, 256);
std::istringstream f(sentence );
std::string s;
std::list<std::string> strings;
while (f >> s)
{
strings.push_front(s);
}
}
') return;
char last = '#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
namespace phx= boost::phoenix;
using namespace boost::spirit::qi;
int main()
{
auto out = std::ostream_iterator<std::string>(std::cout, " ");
boost::spirit::istream_iterator f(std::cin), l;
std::cin.unsetf(std::ios::skipws);
parse(f, l,
(
(as_string [ +~char_("\n\t ") ] % +char_("\t "))
[ phx::reverse(_1), phx::copy(_1, phx::ref(out)) ]
) % eol [ phx::ref(std::cout) << "\n" ]
);
}
';
int hold = 0;
int index = START + 1;
while(sentence[index] != '#include<iostream>
#include<string>
#include<algorithm>
#include<vector>
using namespace std;
vector<string> split(char* str, char delimiter=' ')
{
vector<string> result;
do
{
char* begin =str;
while(*str != delimiter && *str)
str++;
result.push_back(string(begin, str));
}while(0 != *str++);
return result;
}
int main()
{
string str;
vector<string> tempStr;
cout<<"Enter The String: ";
getline(cin, str);
cout<<endl;
tempStr=split((char*)str.c_str());
str.clear();
cout<<"Final Reverse: \n";
for(int i=tempStr.size()-1; i>=0; i--) str+=tempStr.at(i)+" ";
//cout<<tempStr.at(i)<<" ";
cout<<str<<endl;
return 0;
}
' && sentence[index] != ' ') {//There are better ways to do this logic, but I wanted to remain true to your implementation as much as possible
index++;
}
reverse(sentence, index);
for(int j = START; j < index; j++) {
cout << sentence[j];
}
cout << endl;
return;
}
You'll need to include several headers:
您需要包含几个标题:
#include <bits/stdc++.h>
using namespace std;
int main()
{
string s,st,w;
int i;
getline(cin,s);
istringstream is(s);
st="";
is>>st;
while(is>>w)
{
st=w+' '+st;
}
cout<<st<<endl;
return 0;
}
You can see this code in action with this demo on ideone.com
您可以在 ideone.com 上通过此演示查看此代码的运行情况
回答by ChrisCM
When you say
当你说
##代码##You hav ean infinite loop. You're always going back to the point where you find your '\0' character I believe. What you should do is have two separate while loops. One to get you to the end of your character array, to find '\0'. And then another set of loops to return back to white space, then loop back forward printing out characters.
你有一个无限循环。我相信,您总是会回到找到 '\0' 字符的地方。您应该做的是有两个单独的 while 循环。一个让你到你的字符数组的末尾,找到'\0'。然后另一组循环返回空白,然后向前循环打印出字符。
NOTE: I like all the answers presented better, but this is why the code you posted is failing. Here is a version of this function that works with just cstrings.
注意:我更喜欢所有提供的答案,但这就是您发布的代码失败的原因。这是此函数的一个版本,仅适用于 cstring。
##代码##I prints out a few extra end lines, you can of course format the output however you like, the hard part is done.
我打印出一些额外的结束行,您当然可以根据自己的喜好格式化输出,困难的部分已经完成。
回答by Enigma
at this moment strings
contains the words in reverse order
此时strings
包含倒序的单词
回答by sehe
Correction to the earlier version, firmly tongue-in-cheek:)
更正早期版本,坚决诙谐:)
Note that the program reads all of stdin, treating each individual line as a 'sentence'.
请注意,程序读取所有标准输入,将每一行视为“句子”。
##代码##回答by Dustin Doosun Yang
I would like to use stack. 1.Tokenize the string using delimiter("") 2. push the word into the stack 3. As you pops up, store that word in the new string variable.
我想使用堆栈。1. 使用 delimiter("") 标记字符串 2. 将单词推入堆栈 3. 弹出时,将该单词存储在新的字符串变量中。
回答by Ambrish D
Here I used splitting (tokenizing) sentence into words and then use that for reverse printing. Hope this help-
在这里,我使用将句子拆分(标记化)成单词,然后将其用于反向打印。希望这有帮助-
##代码##回答by Shawon
You can do it by istringstream class of C++
您可以通过 C++ 的 istringstream 类来完成
##代码##