代码之家  ›  专栏  ›  技术社区  ›  josh

C++中的字符串反转

  •  7
  • josh  · 技术社区  · 14 年前

    我试图通过保持下面的空格来颠倒句子中单词的顺序。

    [this is my test    string] ==> [string test my is    this]
    

    我一步一步地,

    [this is my test    string] - input string
    [gnirts    tset ym si siht] - reverse the whole string - in-place
    [string    test my is this] - reverse the words of the string - in-place
    [string test my is    this] - string-2 with spaces rearranged
    

    有没有其他方法可以做到这一点?最后一步是否也可以到位?

    9 回复  |  直到 14 年前
        1
  •  5
  •   codaddict    14 年前

    你的方法很好。但你也可以这样做:

    • 空间
    • S
    • 如果您发现空间,请将 Q

    N 书堆上的字 N-1 队列中的数字。

    While stack not empty do
     print S.pop
     if stack is empty break
     print Q.deque number of spaces
    end-while
    
        2
  •  2
  •   John Dibling    14 年前

    这里有一个方法。

    #include <iostream>
    #include <algorithm>
    #include <vector>
    #include <string>
    #include <sstream>
    using namespace std;
    
    string test_string = "this is my test    string";
    
    int main()
    {
        // Create 2 vectors of strings.  One for words, another for spaces.
        typedef vector<string> strings;
        strings words, spaces;
        // Walk through the input string, and find individual tokens.
        // A token is either a word or a contigious string of spaces.
        for( string::size_type pos = 0; pos != string::npos; )
        {
            // is this a word token or a space token?
            bool is_char = test_string[pos] != ' ';
            string::size_type pos_end_token = string::npos;
    
            // find the one-past-the-end index for the end of this token
            if( is_char )
                pos_end_token = test_string.find(' ', pos);
            else
                pos_end_token = test_string.find_first_not_of(' ', pos);
    
            // pull out this token
            string token = test_string.substr(pos, pos_end_token == string::npos ? string::npos : pos_end_token-pos);
            // if the token is a word, save it to the list of words.
            // if it's a space, save it to the list of spaces
            if( is_char )
                words.push_back(token);
            else
                spaces.push_back(token);
            // move on to the next token
            pos = pos_end_token;
        }
    
        // construct the new string using stringstream
        stringstream ss;
        // walk through both the list of spaces and the list of words,
        // keeping in mind that there may be more words than spaces, or vice versa
        // construct the new string by first copying the word, then the spaces
        strings::const_reverse_iterator it_w = words.rbegin();
        strings::const_iterator it_s = spaces.begin();
        while( it_w != words.rend() || it_s != spaces.end() )
        {
            if( it_w != words.rend() )
                ss << *it_w++;
            if( it_s != spaces.end() )
                ss << *it_s++;
        }
    
        // pull a `string` out of the results & dump it
        string reversed = ss.str();
        cout << "Input: '" << test_string << "'" << endl << "Output: '" << reversed << "'" << endl;
    
    }
    
        3
  •  2
  •   Arun    14 年前

    我可以这样重新表述这个问题:

    • 非空格标记被反转,但保留其原始顺序
      • 这5个非空格标记this,is,my,test,string被反转为string,test,my,is,this。
    • 太空代币保持原来的顺序

    下面是一个O(N)解[N是char数组的长度]。不幸的是,它并没有按照OP的要求就位,但是它也没有使用额外的堆栈或队列——它使用一个单独的字符数组作为工作空间。

    这是一个C-ish伪代码。

    work_array = char array with size of input_array
    dst = &work_array[ 0 ]
    
    for( i = 1; ; i++) {
       detect i’th non-space token in input_array starting from the back side
       if no such token {
          break;
       }
       copy the token starting at dst
       advance dst by token_size
       detect i’th space-token in input_array starting from the front side
       copy the token starting at dst
       advance dst by token_size
    }
    
    // at this point work_array contains the desired output,
    // it can be copied back to input_array and destroyed
    
        4
  •  1
  •   GôTô    14 年前

    对于从第一个词到中心词的单词,用单词长度-n切换单词n

        5
  •  1
  •   user191776 user191776    14 年前

    此伪代码假定初始字符串不以空格结尾,但也可以对此进行适当修改。

    1.  Get string length; allocate equivalent space for final string; set getText=1
    
    2.  While pointer doesn't reach position 0 of string,
    
        i.start from end of string, read character by character... 
          a.if getText=1 
           ...until blank space encountered
          b.if getText=0
           ...until not blank space encountered
    
        ii.back up pointer to previously pointed character
    
        iii.output to final string in reverse
    
        iv.toggle getText
    
    3.  Stop
    
        6
  •  0
  •   user411313    14 年前

    并非所有strtok解决方案都适用于您的示例,请参见上文。 试试这个:

    char *wordrev(char *s)
    {
      char *y=calloc(1,strlen(s)+1);
      char *p=s+strlen(s);
      while( p--!=s )
        if( *p==32 )
          strcat(y,p+1),strcat(y," "),*p=0;
      strcpy(s,y);
      free(y);
      return s;
    }
    
        7
  •  0
  •   Jay    14 年前

    #include <string>
    #include <iostream>
    #include <algorithm>
    
    class push_front
    {
    public:
       push_front( std::string& s ) : _s(s) {};
       bool operator()(char c) { _s.insert( _s.begin(), c ); return true; };
       std::string& _s;
    };
    
    int main( int argc, char** argv )
    {
    
       std::string s1;
       std::string s( "Now is the time for all good men");
       for_each( s.begin(), s.end(), push_front(s1) );
    
       std::cout << s << "\n";
       std::cout << s1 << "\n";
    }
    

    不,不,不,不,不

        8
  •  0
  •   MSD    11 年前

    复制数组中的每个字符串并按相反顺序打印(i--)

    int main()
    {
    int j=0;
    string str;
    string copy[80];
    int start=0;
    int end=0;
    cout<<"Enter the String :: ";
    getline(cin,str);
    cout<<"Entered String is : "<<str<<endl;
    for(int i=0;str[i]!='\0';i++)
    {
    end=s.find(" ",start);
    if(end==-1)
    {
    copy[j]=str.substr(start,(str.length()-start));
    break;
    }
    else
    {
    copy[j]=str.substr(start,(end-start));
    start=end+1;
    j++;
    i=end;
    }
    }
    
    for(int s1=j;s1>=0;s1--)
    cout<<" "<<copy[s1];
    }
    
        9
  •  -1
  •   Charles    14 年前

    我想我应该使用空格字符对字符串进行标记化(strtok或CString::Tokanize)。将字符串放入一个向量中,然后按相反的顺序将它们拉回来,并在它们之间用空格连接起来。