2014-03-02 67 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; 
}