I am preparing for an entry-level job interview. I am trying to reverse the order of words in a string, but my output is a bunch of junk that makes no sense. I think the problem may be because I'm using "char*" for my functions? Anyways, heres my code
#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;
}
I would like to reiterate what WeaselFox said about not reinventing the wheel, try to learn the C++ STL, in the long run that will be a lot more helpful.
Having said that let me suggest an approach as well. Whenever you come across problems like reversing order of chars in a string OR reversing words in a string, interviewers are really trying to test your knowledge of data structures, and in this case, specifically the "stack" data structure.
Consider what happens if you parse words in a string and place them all into an array one at a time: "I AM A STRING" --> {"I", "AM", "A", "STRING"}
Now do the same thing for a stack:
"I AM A STRING" --> {"STRING", "A", "AM", "I"}
Do you see why a stack would be useful ? It's better if you reason it out yourself than I provide source code, the reason being that your approach is incorrect regardless of whether or not it yields the correct answer.
I hope this helps!
If you're wanting a C-like solution, you can do it with only pointers and a temp variable of type char
if you need to define your own reverse
function to reverse a string between two pointers. The code below simply reverses the entire string it receives (it could be modified to reverse only the string in a range [iterA, iterB)) and reverses the letters in each of the word is that string. For example, reversing hello world!
first results in !dlrow olleh
inside reverse_words
, which is corrected to world! hello
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(...)
You could substitute std::reverse
in the library for the reverse
function defined above. I included an implementation nonetheless. An implementation of reverse_words
working on a range could be potentially more useful and shouldn't be difficult to implement with the above code. It is left as an exercise to the reader.
let me recommend a different approach. If youre using char pointers:
strtok
into an array of char*
s. If you opt to use strings and STL containers, refer to this question as for splitting the string to tokens, and reassembling them nicely:
Its always a better idea not to reinvent the wheel. Use library functions, dont manipulate the chars yourself.
// 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;
}
Change int length = ab;
to int length = b-a+1;
in reverse()
.
Also you need to loop till middle, otherwise it will be reversed twice, giving the original output.
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;
}
#include "stdafx.h"
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
void split(string &str, vector<string> &v, char ch);
int main() {
string str;
std::getline(std::cin, str);
vector <string> stringVec;
split(str, stringVec, ' ');
vector <string>::reverse_iterator it;
for (auto it = stringVec.rbegin(); it != stringVec.rend();
++it)
{
cout << *it << " ";
}
return 0;
}
void split(string &str, vector<string> &v, char ch)
{
size_t pos = str.find(" ");
size_t initialpos = 0;
v.clear();
while (pos != string::npos)
{
v.push_back(str.substr(initialpos, pos - initialpos));
initialpos = pos + 1;
pos = str.find(ch,initialpos);
}
v.push_back(str.substr(initialpos, (std::min(pos, str.size()) -
initialpos + 1)));
}
Just to give you headsup for how to reverse a string using RECURSION, I modified your code that is given below. Learn and feel the power of 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;
}
here is my version
#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;
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.