2014-03-02 118 views
6

我正在準備入門級面試。我試圖扭轉字符串中單詞的順序,但是我的輸出是一堆毫無意義的垃圾。我認爲這個問題可能是因爲我爲我的功能使用了「char *」?無論如何,繼承人我的代碼字符串中字的顛倒順序

#include <iostream> 
#include <string> 
using namespace std; 

char* reverse(char* str, int a, int b); 
char* reversewords(char* str); 

int main() 
{ 
    char str[] = "The interview is"; 
    cout<<"Reverse is: "<<reversewords(str); 
    cin.ignore(); 
    return 0; 
} 


char* reverse(char* str, int a, int b) 
{ 
    int length = a-b; 

    for (int i=a; i<b+1; i++) 
    { 
     char c =str[length-i-1]; 
     str[length-i-1]=str[i]; 
     str[i] = c; 
    } 
    return str; 
} 

char* reversewords(char* str) 
{ 
    int length = strlen(str); 
    int a=0; 
    int b=0; 
    while (b<length) 
    { 
     if (str[b]==' ' || b==length-1) 
     { 
       b=b-1; 
      reverse(str, a, b); 
      a=b+2; 
      b=a; 
     } 
     b++; 
    } 
    return str; 
} 
+0

的[反話的字符串中的排序]可能重複(http://stackoverflow.com/questions/1009160/reverse-the-字符串排序) – tenfour

+1

如果沒有網頁的警告,你甚至可以問這個問題,已經有100萬次了? – tenfour

+0

對於循環簽名,不應該是:for(int i = a; i> b + 1; i - )'(使用'>'而不是'<'並遞減'i')。 – 0x499602D2

回答

1

讓我推薦一種不同的方法。如果您使用字符指針:

  1. 將字符串使用strtok拆分爲char*的數組。
  2. 從結尾向後迭代這組單詞並重新組裝字符串。

如果您選擇使用字符串和STL容器,是指這個問題作爲字符串分割到令牌,並很好地重組它們:

Split a string in C++?

它總是一個好主意不重塑車輪。使用庫函數,不要自己操縱字符。

+1

什麼是世界上最好的發明。軸! –

+0

雖然使用strtok聽起來像是一個好主意,但我想在「通過將最後一個字符替換爲第一個字符,使用倒數第二個字符替換第二個字符等來反轉字符串」這個問題上解決了這個問題。然後,通過字符串尋找空格。通過再次將第一個字符與最後一個字符交換,第二個字符與倒數第二個字符交換,來反轉您遇到的每個單詞,等等。「 – user3370198

0

int length = a-b;更改爲int length = b-a+1;reverse()

你也需要循環到中間,否則它會被顛倒兩次,給出原始輸出。

for (int i=a; i<=a+(b-a)/2; i++) 
{ 
    char c =str[a+length-i-1]; 
    str[a+length-i-1]=str[i]; 
    str[i] = c; 
} 
5

我想重申WeaselFox說一下,不要重複發明輪子,試着學習C++ STL,從長遠來看,這將是一個很大更有幫助。

話雖如此,讓我建議一種方法。無論何時遇到像字符串中的字符顛倒順序或字符串中的字符顛倒等問題,採訪者都試圖測試您對數據結構的瞭解,在這種情況下,特別是「棧」數據結構。

請考慮如果您解析字符串中的單詞並將它們全部放入一個數組中,會發生什麼情況: 「我是一個STRING」 - > {「I」,「AM」,「A」 STRING 「}

現在做同樣的事情堆棧:

」我是一個字符串「 - > {」 STRING」, 「A」, 「AM」, 「I」}

你明白爲什麼堆棧會有用嗎?如果你自己推理出來比我提供源代碼更好,原因是你的方法是不正確的,不管它是否產生正確的答案。

我希望這有助於!

+0

我看不到爲什麼這個解決方案好。堆棧使用額外的空間。而堆棧方法和常規方法具有相同的時間複雜度。 –

+0

@jaffar:您的答案可以很容易地編輯來解釋*爲什麼*堆棧方法會導致更乾淨的代碼,而不需要執行解決方案實施。 – jlouzado

+0

最好使用遞歸函數來反轉字符串,然後將字符串本身保存在堆棧中。 – iankits

2

如果你想要一個類似C的解決方案,你可以只用指針和char類型的臨時變量,如果你需要定義自己的reverse功能扭轉兩個指針之間的串做到這一點。下面的代碼簡單地反轉了它接收到的整個字符串(它可以被修改爲僅反轉範圍[iterA,iterB)中的字符串),並且每個單詞中的字母都是該字符串。例如,將hello world!的第一個結果在!dlrow ollehreverse_words內糾正爲world! hello

#include <cstring> 
#include <cctype> 
using std::isspace; 
using std::strlen; 

void reverse(char *start, char *end) 
{ 
    for (char c; --end - start > 0; ++start) { 
     c = *start; 
     *start = *end; 
     *end = c; 
    } 
} 

void reverse_words(char *s) 
{ 
    char *end = s + strlen(s); 
    char *delimp; 

    // Don't reverse any leading/trailing space (e.g. a newline). 
    while (isspace(*s)) 
     ++s; 
    while ((isspace(*end) || !*end) && end - s > 0) 
     --end; 

    // Reverse the remaining string. 
    reverse(s, ++end); 

    // Reverse each word. 
    while (end - s > 0) { 

     // Skip leading space characters. 
     while (isspace(*s)) 
      ++s; 

     // Find the next space character. 
     delimp = s; 
     while (!isspace(*delimp) && *delimp) 
      ++delimp; 

     // Reverse the word. 
     reverse(s, delimp); 

     // Point to the next space character (or the end of the string). 
     s = delimp; 
    } //while(end - s > 0) 
} //void reverse_words(...) 

你可以在上面定義的reverse函數庫替代std::reverse。儘管如此,我還是包含了一個實現。在範圍上工作的reverse_words的實現可能更有用,並且應該不難以上述代碼實現。這是留給讀者的一個練習。

-1

只是爲了讓你知道如何使用RECURSION來反轉字符串,我修改了下面給出的代碼。學習並感受遞歸的力量。

#include <iostream> 
#include <string> 
using namespace std; 

char * reverse_s(char *, char*, int,int); 

int main() 
{ 
    char str[] = "The interview is"; 
    char* rev_str = new char[strlen(str)]; 
    cout<<"\n\nFinal Reverse of '" << str << "' is -->"<< reverse_s(str, rev_str, 0, strlen(str)) << endl; 
    cin.ignore(); 
    delete rev_str; 
    return 0; 
} 

char* reverse_s(char* str, char* rev_str, int str_index, int rev_index) { 

if(strlen(str) == str_index) 
     return rev_str; 

str_index += 1; 
rev_index -=1; 

rev_str = reverse_s(str, rev_str, str_index, rev_index); 

cout << "\n Now the str value is " << str[str_index-1] << " -- Index " << str_index-1; 
rev_str[rev_index] = str[str_index-1]; 

cout << "\nReversed Value: " << rev_str << endl; 

return rev_str; 
} 
+0

你正在泄漏記憶。爲什麼'malloc'而不是'new'? –

+0

用新的而不是malloc。在答案和我正在泄漏內存的地方改變了? – iankits

+0

在主函數中。如果你使用'new []',你需要一個相應的'delete []'。對於'malloc'和'free'同樣如此。 –

-1

這裏是我的版本

#include <iostream> 
#include <vector> // template for list 
#include <algorithm> // copy algorithm or revers 
#include <sstream> //sstringstream 
#include <iterator>// iterator 
#include <fstream> 
using namespace std; 

/* overloading ostream operator operator */ 
ostream &operator<<(ostream&out, const vector<string> a){ 
static int i = 1; 
out << "Case #" << i++ << ": "; 

for (vector<string> ::const_iterator v = a.begin(); v != a.end(); v++) 
    out << *v; 
return out; 
} 

void showElemnts(vector<string> vec, int line){ 
cout << "Case #" << line << " " << vec; // overloading operator for output vector 
} 

vector<string> reversWord(string &s){ 
istringstream processWordByWord(s); // store string in processWordByWord and store in events 
vector<string> events; // store events here 
string input; 

while (processWordByWord >> input){ 
    events.push_back(input); 
    events.push_back(" "); 
} 


events.pop_back(); // delete space 
reverse(events.begin(), events.end()); 
return events; 
} 





int main(){ 
vector<string> a; 
string Line; 
ifstream dataInput("B-small-practice.in", ios::in); 
ofstream dataOut("out.out"); 
int number; 

getline(dataInput, Line); // skip first line 
getline(dataInput, Line); // skip first line 

while (!dataInput.eof()) 
{ 
    dataOut << reversWord(Line)<<endl; 
    getline(dataInput, Line); 


} 
dataInput.close(); 
dataOut.close(); 

return 0; 
} 
1
// Maybe just take the words out of the string and put them back in reverse 
#include <algorithm> 
#include <vector> 
#include <string> 

using namespace std; 

int main() { 

string a("This is my string to try and reverse"); 

// Reverse word order 
vector<string> words; 
string::size_type pos = 1; 
while(pos != string::npos) { 
    pos = a.find(" "); 
    if(pos != string::npos) { 
     words.push_back(string(a.begin(),a.begin()+pos)); 
     a.erase(a.begin(),a.begin()+pos+1); 
    } 
    else { 
     words.push_back(string(a.begin(),a.end())); 
     a.erase(a.begin(),a.end()); 
    } 
} 
reverse(words.begin(), words.end()); 
for(int i=0; i<words.size(); i++) a.append(words[i].append(" ")); 
cout << a << endl; 
return 0; 
}