Reputation: 51
I'm meant to write a function that keeps the first and last letter of a string the same and ignores any non-letters after the last letter. I'm supposed to use the std::random_shuffle(). I read the documentation however I don't seem to grasp the concept of this function. This is my code:
#include <iostream>
#include <algorithm>
#include <string>
std::string mix(std::string s){
int last_char;
if(std::isalpha(s[s.size()-1]) == true){
last_char = s.size()-1;
} else {
for(int i=s.size()-1 ; i>0; --i){
if((std::isalpha(s[i]) == false) && (std::isalpha(s[i-1])==true)){
last_char = i -1;
break;
}
}
}
std::random_shuffle(&s[1],&s[last_char]);
return s;
}
int main(){
std::string test = "Hello";
std::cout << mix(test) << std::endl;
}
edit: Now however I keep getting the error: segmentation fault(core dumped). ANyone got an idea why? Can't seem to find the problem.
Upvotes: 0
Views: 3029
Reputation: 42082
Something to get you started. It has at least one corner case that you'll have to fix. Visit cppreference.com to understand how the algorithms work.
#include <iostream>
#include <cctype>
#include <algorithm>
#include <string>
std::string
special_shuffle(std::string s)
{
if (s.size() < 3) return s;
auto begin = std::find_if(s.begin(), s.end(), ::isalpha);
auto end = std::find_if(s.rbegin(), s.rend(), ::isalpha).base();
std::random_shuffle(++begin, --end);
return s;
}
int
main()
{
std::string s1 = "Hello World!";
std::string s2 = "AB";
std::string s3 = "A";
std::string s4 = "";
std::string s5 = "a string going from a to z";
std::cout << s1 << " --> " << special_shuffle(s1) << "\n"
<< s2 << " --> " << special_shuffle(s2) << "\n"
<< s3 << " --> " << special_shuffle(s3) << "\n"
<< s4 << " --> " << special_shuffle(s4) << "\n"
<< s5 << " --> " << special_shuffle(s5) << "\n";
}
Compile and run:
$ g++ example.cpp -std=c++14 -Wall -Wextra
$ ./a.out
Hello World! --> Hooll eWlrd!
AB --> AB
A --> A
-->
a string going from a to z --> aarfritomgi nnso t g goz
Upvotes: 0
Reputation: 121649
You'll need to find the leftmost "non-letter" in the right side of your string.
One place to the left of this is the position of the last letter.
One place to the right is your first letter.
Simply invoke random_shuffle with your "first" and "last".
Here are some useful links:
http://www.cplusplus.com/reference/algorithm/random_shuffle/
Remember that "begin" is inclusive, "end" is exclusive"
Upvotes: 1
Reputation: 118340
std::random_shuffle
takes iterators or pointers, as arguments, not values in the array/container to be sorted. Your call to std::random_shuffle
should probably be:
std::random_shuffle(&s[1],&s[last_char]);
Note that the second parameter is the ending iterator value. The ending iterator doesn't point to the last value to sort, but the one after that.
This is not the only problem with the shown code. You'll need to fix several bugs in your code that precedes the call to std::random_shuffle
. For example:
for(int i=s.size() ; i>0; --i){
if((std::isalpha(s[i]) == false) && (std::isalpha(s[i-1])==true)){
s.size()
gives you the size of the string. On the first iteration, i
will be equal to its size()
, but accessing s[i]
will now result in undefined behavior, and a bug, since s[i]
obviously does not exist. In a string that contains n
characters, the characters are s[0]
through s[n-1]
, of course.
You will need to fix your algorithm so that last_char
ends up being the index of the next character after the one you want to shuffle, and then use the fixed std::random_shuffle
call, above.
Or, alternatively, compute last_char
to be the index of the last character to sort, and call
std::random_shuffle(&s[1],&s[last_char+1]);
Either approach will be fine.
Upvotes: 3