簡體   English   中英

C ++中的字符串反轉

[英]String reversal in C++

我試圖通過保持下面的空格來顛倒句子中單詞的順序。

[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

有沒有其他方法可以做到這一點? 是否也可以在最后一步就地進行?

你的方法很好。 但另外你也可以這樣做:

  • 繼續掃描輸入的單詞和空格
  • 如果你找到一個單詞將它推到堆棧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

這是一種方法。

簡而言之,構建兩個您找到的標記列表:一個用於單詞,另一個用於空格。 然后拼湊一個新的字符串,其中的單詞順序相反,空格按正向順序排列。

#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;

}

我會用這種方式重新解釋這個問題:

  • 非空間令牌是相反的,但保留其原始順序
    • 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

對於從第一個字到中心字的字,用字長來切換字n - n首先使用分割功能然后進行切換

這個偽代碼假設你沒有用空格結束初始字符串,盡管也可以適當修改它。

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

復制數組中的每個字符串並以相反的順序打印(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];
}

所有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;
}

太糟糕的stl字符串沒有實現push_front。 然后你可以用transform()做到這一點。

#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";
}

現在是所有好人的時候了

nem doog lla rof emit eht si woN

我想我只是使用空格字符標記(strtok或CString :: Tokanize)字符串。 將字符串推入向量,而不是以相反的順序將它們拉回來,並將它們連接在一起。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM