c++:我试图颠倒字符串中单词的顺序(而不是整个字符串)

c++: I am trying to reverse the order of words in string (not the whole string)

本文关键字:字符串 顺序 单词 c++      更新时间:2023-10-16
#include <iostream>
#include <vector>
using namespace std;
void RevStr (char *str)
{   
    if(*str !=0)
    {
        vector<char> v1;
        while((*str != ' ')&&(*str !=0))
            v1.push_back(*str++);
        // trying to not add space in the last word of string
        if(*str !=0)
        {
            v1.push_back(' ');
            str++;
        }
        RevStr(str);
        cout<<*str;
    }

}
int main()
{
    RevStr("hello world!");
    cout<<endl;
}

我想更改字符串中单词的顺序,例如"how are you"=>"you are how">

我遇到了一些问题,它打印不正确(只打印w(,请帮帮我,告诉我我做错了什么。然而,我知道我不应该叫"cout<<*str;"因为我正在堆栈中插入"array of char"(递归(,但我不知道我需要做什么。

C++让它变得简单:

#include <algorithm>
#include <iterator>
#include <vector>
#include <string>
#include <iostream>
#include <sstream>
std::string reverse(std::string const& text)
{
    std::stringstream           inStream(text);
    std::stringstream           outStream;
    std::vector<std::string>    words;
    std::copy(std::istream_iterator<std::string>(inStream), std::istream_iterator<std::string>(), std::back_inserter(words));
    std::copy(words.rbegin(), words.rend(), std::ostream_iterator<std::string>(outStream, " "));
    return outStream.str();
}

int main()
{
    std::cout << reverse("Hello World") << "n";
}

一种常见的方法是先反转整个字符串,然后对每个单词反转单词中的字母。因此不需要递归。你可能会发现尝试一下更容易(是的,我知道这并不是你问题的答案:(。

使用cout << str而不是cout << *str打印字符串。char *存在operator<<过载。但也许这不是你想要做的;无论如何,我都不能完全按照你的逻辑行事。

您正在失去"你好"部分。

你想要的算法是这样的:

  1. RevStr的每次调用都会隔离字符串中作为参数传递的第一个单词
  2. 用字符串的剩余部分调用RevStr
  3. 在堆栈展开时打印它在步骤1中隔离的单词

基本上,您应该打印v1数据。

我强烈建议使用通过std::string公开的一些功能作为开始。

你可以这样做的一种方法是:

std::string ReverseString(std::string s)
{
    std::stack<std::string > stack;
    std::string tmpstr = "";
    std::string newstr = "";
    size_t strsize = s.size();
    size_t pos  = 0;   size_t tmppos = 0;
    size_t i = 0;      size_t stacksize = 0;
    while( pos < strsize )
    {
        tmppos = s.find(" ", pos, 1);    // starting as pos, look for " "
        if (tmppos == std::string::npos) // std::string::npos => reached end
        {
            tmppos = strsize;            // don't forget the last item.
        }     
        tmpstr = s.substr(pos, tmppos-pos); // split the string.
        stack.push(tmpstr);                 // push said string onto the stack
        pos = tmppos+1;
    }
    stacksize = stack.size();
    for ( i = 0; i < stacksize; i++ )
    {
        tmpstr = stack.top();              // grab string from top of the stack
        stack.pop();                       // stacks being LIFO, we're getting 
        if ( i != 0 )                      // everything backwards.
        {
            newstr.append(" ");            // add preceding whitespace.
        }
        newstr.append(tmpstr);             // append word.
    }
    return newstr;
}

这绝不是实现这一目标的最佳或最快的方式;有很多其他方法可以做到这一点(例如,Jerry Coffin提到使用带有迭代器的std::vector(,但由于你有C++的强大功能,对我来说,使用它是有意义的

我已经这样做了,所以如果你想的话,你可以使用不同的分隔符。

如果你感兴趣,你现在可以使用这个:

int main(int argc, char** argv)
{
    std::string s = "In Soviet Russia String Format You";
    std::string t = ReverseString(s);
    std::cout << t << std::endl;
}

给定它是一个char*,这会在原地反转它(即,不需要与传入的"str"成比例的更多内存(。这避免了将其转换为std::字符串(这并不是一个坏主意,只是因为它一开始就是一个char*。(

void reverse_words(char* str)
{
    char* last = strlen(str) + str;
    char *s, *e;
    std::reverse(str,last);
    for(s=e=str; e != last; e++)
    {
        if(*e == ' ') 
        {
            std::reverse(s,e);
            s = e+1;
        }
    }
    std::reverse(s,e);  
}
void Reverse(const string& text)
{
    list<string> words;
    string temp;
    for ( auto cur = text.begin(); cur != text.end(); ++cur)
    {
        if (*cur == ' ')
        {
            words.push_front(temp);
            temp.clear();
        }
        else
        {
            temp += *cur;
        }
    }
    if (! temp.empty())
    {
        words.push_front(temp);
    }
    for_each(words.begin(), words.end(), [](const string& word) { cout << word << " "; });
    cout << endl;
}
void swap(char* c1, char* c2) {
    char tmp = *c1;
    *c1 = *c2;
    *c2 = tmp;
}
void reverse(char* s, char* e) {
     if (s == NULL || e == NULL)
        return;
     while(s < e)
      swap(s++, e--);
}
void reverse_words(char* line) {
  if (line == NULL)
    return; 
  reverse(line, line+strlen(line)-1);
  char *s = line;
  char *e;
  while (*s != '') {
    e = s;
    while (*e != ' ' && *e != '') ++e;
    --e;
    reverse(s,e);
    s = e+2;
  }
}