Modifying a recursive string reverse function - c++

I am doing some recursive exercises. The previous one was to make a reverse() function for a string which basically removes the first character and then combines the solution. I managed to do that, here is the source code (the entire source) The current task is to modify this function (the following exercise in the book) by adding a helper function which reverses a substring of the string. At this moment I am stuck at this. It is my understanding that you use helper functions when you need to pass additional arguments or something and this function takes none so I really have no idea how to approach this problem. Help appreciated.
#include <iostream>
#include <string>
using namespace std;
void reverse(string& text)
{
if (text.length() == 0)
{
return;
}
if (text.length() == 1)
{
return;
}
else
{
string firstLetter = text.substr(0,1);
text = text.substr(1, text.length()-1);
reverse(text);
text += firstLetter;
}
}
int main()
{
string a = "tyu";
reverse(a);
cout << a << endl;
return 0;
}
A guy suggested to use parameters, ect, this is my try with it:
#include <iostream>
#include <string>
using namespace std;
//is actually doing the hard work
void reverse1(string& input, int a, int b)
{
// base case
if( a >= b)
{
return;
}
//swap the characters
char tmp;
tmp = input[a];
input[a] = input[b];
input[b] = tmp;
//create the boundries for the new substring
a++;
b--;
//call the function again
reverse1(input, a, b);
}
// sets the parameters and calls the helper function
void strreverse(string& input)
{
reverse1(input, 0, input.length()-1);
}
int main()
{
cout << "Please enter the string which you want to be reversed:";
string a;
cin >> a;
strreverse(a);
cout << a << endl;
return 0;
}

The goal is probably to avoid creating all of the intermediate substrings. The helper function will take iterators, or a start and end index in addition to the string begin reversed.

Try to implement reversing so that there is only one instance of std::string (i.e. work with it as with an array). Then you will need a helper function with additional parameters (at least one parameter - which index to reverse now).
I would implement reverse here as series of exchanges: a[0] <-> a[n-1], a[1] <-> a[n-2] etc. where n is length of the string.

You can define a helper function that takes a start and an end index of the substring which it will reverse.
The function should exchange the element at the start index with that at the end index IFF the difference between the start and the end indices is 1. Otherwise, it places a recursive call to itself by decrementing the end index and incrementing the start index. You will need to keep check on the condition if the start and end index become same though.

Related

String permutation recursion issue

(--This question was answered down below--)
Hey guys so I know this question has been answered in various ways so far on this site but I wanted to see if I could get a hint to my question without getting the blunt answer... sorry if this is redundant!
so... so far my code is this (as the function says, this is supposed to print out every permutation of the string "ABCD" and MUST be done recursively and without the use of STL algorithms):
void printPermutations(string prefix, string remainder)
{
if (remainder.empty())
cout<<prefix<<endl;
else {
for(int i = 0; i<remainder.length(); i++)
{
prefix += remainder[i];
remainder = (remainder.substr(0, i) + remainder.substr(i+1)); //Gets rid of selected char
printPermutations(prefix, remainder); //recursion w/updated values. Problem here?
}
}
}
Where remainder = "ABCD" as a test string. I'm assuming my problem is with the recursive call itself?
So far, the function only prints out the first 3 permutations: ABCD, ABDC, ACBD. I also have a hunch that this could have something to do with the for control since it printed out 3 permutations and 3 would be less than the string's length of 4? I don't know. I just started learning recursion and it's really hard for me to figure out how to implement recursive calls properly.
The problem is that you're modifying both strings in the loop, so prefix grows and remainder shrinks.
That is, you want the "top-level" call to iterate through A/BCD, B/ACD, C/ABD, and D/ABC, but you're iterating through A/BCD, AB/CD, ABC/D, and ABCD/empty.
Don't modify the strings, just pass the values you want to the recursion:
void printPermutations(string prefix, string remainder)
{
if (remainder.empty())
cout<<prefix<<endl;
else {
for(int i = 0; i<remainder.length(); i++)
{
printPermutations(prefix + remainder[i],
remainder.substr(0, i) + remainder.substr(i+1));
}
}
}
Or use "fresh" variables if you want a more "step-by-step" look:
void printPermutations(string prefix, string remainder)
{
if (remainder.empty())
cout<<prefix<<endl;
else {
for(int i = 0; i<remainder.length(); i++)
{
string thisPrefix = prefix + remainder[i];
string thisRemainder = remainder.substr(0, i) + remainder.substr(i+1);
printPermutations(thisPrefix, thisRemainder);
}
}
}
Please consider using the stl algorithm next_permutation for the job. The code in your case is than:
#include <algorithm>
#include <string>
#include <iostream>
int main()
{
std::string s = "ABCD";
std::sort(s.begin(), s.end());
do {
std::cout << s << '\n';
} while(std::next_permutation(s.begin(), s.end()));
}
If you need to, you can write a wrapper around this snippet.

recursive method for array element printing

I am learning recursive calls implementation. i get stuck with return statements, i am trying to print an array elements by recursive call. though i print but it but i want to return it, can some body help
#include<iostream>
using namespace std;
int recursive_arr_traversal(int *arr, int length_of_array) {
if (length_of_array <= 0) {
return 0;
}
else {
return *arr; //this statement prints only one array element<endl
cout << *arr << endl;//this works fine
}
return recursive_arr_traversal(arr + 1, length_of_array - 1);
}
int main() {
int arr[10] = { 1,2,3,4,56,7,8,9,99,0 };
int length_of_array = 10;
//recursive_arr_traversal(arr,length_of_array);
cout << recursive_arr_traversal(arr, length_of_array);
return 0;
}
As Nathan stated, you do not need to return anything. Have a look at the following code which is your code only slightly modified, as I think you got the main idea of recursion:
#include<iostream>
using namespace std;
void recursive_arr_traversal(int *arr, int length_of_array) {
if (length_of_array <= 0) return;
cout << *arr << endl;//this works fine
recursive_arr_traversal(arr + 1, length_of_array - 1);
}
int main() {
int arr[10] = { 1,2,3,4,56,7,8,9,99,0 };
const int length_of_array = 10;
//recursive_arr_traversal(arr,length_of_array);
recursive_arr_traversal(arr, length_of_array);
return 0;
}
In each call one element is printed and it returns once you have traversed the array. Note that there is an implicit return at the end of recursive_arr_traversal.
A (basic) recursive function should have two parts--the base case, where all the work is already done or almost done and all we have to do is clean up and return, and the recursive case, where we need to do some small part of the work and then pass on the rest to the recusive function.
The base case here is pretty simple, and you already have it right. if(length <= 0), all we have left is an empty array, so we can just return and be done. There's no more work to do.
The recursive case is a little more difficult though and you almost have it!
Our recursive case in this problem should print the first element and then pass on an array that's one shorter and starts one element later. Also note that you never use the return value, and since this is a print function, it should probably be void. With those fixes the code could look like:
int arr_print(int *arr,int len){
//base case: if arr is empty, we're done
if(len <= 0) { return; }
//recursive case: print first element, then pass array along to print rest
cout << *arr << endl;
arr_print(arr + 1, len - 1);
}
If you are saying that you want to return all the values to function like main() so that you have permanent access to your array values, that is not possible just by returning in your recursive function. As said above by others, when you return a value, that value is returned to the function that called it (draw a callstack if you need).
If you just make a global variable to save which ever values you need, that could fix your needs.

Segmentation fault during counting of elements in array of strings c++

I am trying to solve an old problem found on topcoder. I am immediately stuck in trying to find the number of elements in an array of strings. Here is my code
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string>
using namespace std;
class MiniPaint {
private:
size_t numLines;
public:
int leastBad(string picture[], int maxStrokes) {
numLines = 0;
while (!picture[numLines].empty()) {
numLines++;
}
cout << numLines << '\n';
return 0;
}
};
int main() {
MiniPaint instance;
string picture[] = {"BBBBBBBBBBBBBBB", "WWWWWWWWWWWWWWW", "WWWWWWWWWWWWWWW", "WWWWWBBBBBWWWWW"};
instance.leastBad(picture, 10);
return 0;
}
This code gives me a segmentation fault. Something is going wrong, the code is a little bit excessive for just the functionality of counting the number of elements but of course I want to extend the class to include more functionality. If anyone can explain what is going wrong here I would be grateful! Thanks in advance.
EDIT: when I expand the code by
cout << picture[numlines] << '\n';
in the while loop, to show the actual elements in the array, first the four proper strings are shown and then somehow it endlessly prints spaces to the terminal. So the problem lies somewhere in the fact that
picture[4].empty()
does not return true, even though picture has only four elements.
Your while loop condition assumes that the last string in the array is empty:
int leastBad(string picture[], int maxStrokes) {
numLines = 0;
while (!picture[numLines].empty()) {
But your input string array defined in main() is not terminated with an empty "" string.
So you may want to add this empty string terminator:
// inside main()
string picture[] = {..., "" /* Empty string terminator */ };
In addition, in modern C++ I'd encourage you to use array container classes instead of raw C-style arrays, typically std::vector<std::string>.
In this case, you can use the size() method to get the array size (i.e. element count), or just a range-for loop for iterating through the whole array.
You access the array out of bounds.
When you call picture[4] you want to access a string object which is not there end the call to the function empty() is on uninitialized memory.
You either need to store how big the array is and iterate until numLines<=3 or you can use a vector
std::vector<std::string> picture = ...
for(std::string line : picture)
{
//do stuff
}
You are out of array bounds at picture[numLines]. You should pass array length or calculate it and check the index numLines. Code will look like:
size_t length = sizeof(picture) / sizeof(*picture); // For VS use _countof macro
while (numLines < length && !picture[numLines].empty())
{
++numLines;
}

Balance ordering parenthesis via Dynamic programing

Hi from the very famous book Code to Crack i come across a question :
Implement an algorithm to print all valid (e.g., properly opened and closed) combinations of n-pairs of parentheses.
Example:
input: 3 (e.g., 3 pairs of parentheses)
output: ()()(), ()(()), (())(), ((()))
#include <iostream>
#include <string>
using namespace std;
void _paren(int l,int r,string s,int count);
void paren(int n)
{
string s="";
_paren(n,n,s,n);
}
void _paren(int l,int r,string s,int count){
if(l<0 || r<0)
return;
if(l==0 && r==0)
cout<<s<<endl;
else{
if(l>0)
{
_paren(l-1,r,s+"(",count+1);
}
if(r>l)
_paren(l,r-1,s+")",count+1);
}
}
int main(){
int n;
cin>>n;
paren(n);
return 0;
}
This is a recursive approach I tried for it . I am pretty sure that we can solve this through dynamic programming as well , as we are already using a lot of value again and again , but I have no idea how to implement this through Dynamic programming I tried tabular bottom up approach but couldnt work out. Please help me out just the basic idea on how to work with this
DP does not really help you. The recursive algorithm is time and space optimal!
In fact, there is a reason not to use DP: the memory requirements! This will be huge.
A better algorithm is to have one character array that you pass in, have the recursive method modify parts of it and print that when needed. I believe that solution is given in the book you mention.
DP can reduce count of traversed states by choosing the optimal solution every call. It also help you to reuse calculated values. There is no calculations, every valid state must be visited, and non-valid states can be avoided by if( ).
I suggest you to implement some another recursion (at least without copying new string object after call, just declare global char array and send it to output when you need).
My idea of recursion is
char arr[maxN]; int n; // n is string length, must be even though
void func(int pos, int count) { // position in string, count of opened '('
if( pos == n ) {
for(int i = 0; i < n; i++)
cout << char(arr[i]);
cout << "\n";
return;
}
if( n-pos-1 > count ) {
arr[pos] = '('; func(pos+1,count+1);
}
if( count > 0 ) {
arr[pos] = ')'; func(pos+1,count-1);
}
}
I didn't checked it, but the idea is clear I think.

Mysterious Segmentation fault in string reversal

I'm writing a piece of code meant to reverse strings using recursion. I believe my method is correct, but I keep getting a segmentation fault and I'm not sure where it's coming from. All my research indicates that it means I'm doing "something strange with memory". I'm new enough at this that these kinds of errors are still baffling, so any help here would be much appreciated. Here's my code:
#include <iostream>
#include <string>
using namespace std;
class Palindrome
{
int front;
int back;
public:
Palindrome();
string reverse(string word)
{
int len = word.length()-1;
if (back == 0) {
back = len;
}
if (front >= back)
return word;
else{
char first = word[front];
char last = word[back];
word[front] = last;
word[back] = first;
front += 1;
back -= 1;
reverse(word);
}
}
};
Palindrome::Palindrome(){
front = 0;
back = 0;
}
I tried your code and got an "access violation" too, even with only one call. Beside the initialization issue described in other answers and comments, what is causing your seg fault is the missing "return" before your recursive call to "reverse". You need to write return reverse(word);
In Visual Studio, your original code gives this: warning C4715: 'Palindrome::reverse' : not all control paths return a value.
See this question for more details.
Here's a version of reverse() with both fixes:
string reverse(string word)
{
int len = word.length()-1;
if (back == 0)
{
back = len;
}
if (front >= back)
{
front = 0;
back = 0;
return word;
}
else
{
char first = word.at(front);
char last = word.at(back);
word.at(front) = last;
word.at(back) = first;
front += 1;
back -= 1;
return reverse(word);
}
}
What I think Jacob Abrahams was trying to say, front is iterated, but never re-set to zero, so the second time you call it, it will either segfault or produce incorrect results depending on whether the second word is longer or shorter.
Furthermore, what Mark B already hinted at is that you can include algorithm and replace the whole Palindrome::reverse function with
std::reverse(word.begin(), word.end());
Most of all it would help if you learned how to use a debugger or, in the future, at least give the specific error message for these kinds of questions.
EDIT: Forgot to add that recursion (e.g. a function calling itself) is usually a bad idea, because the execution stack is quite small and in this case, even after fixing the aforementioned issue, you will get a stack overflow for a particularly long string. It actually makes this particular code less clear.
Personally, I consider mixing recursion and objects somewhat odd. One of the fundamental concepts of objects is that the object holds state that you want to keep track of. One of the fundamental concepts of recursion is that the execution stack holds the state you want to keep track of.
In this case, the state you want to keep track of is how much of the string has been processed/how much of the string remains to be processed. You can keep track of that without an object.
This smells a lot like a homework question. But I can't think of a hint to give you without just handing you the answer. The best I can do is make my answer (1) reverse any container, including but not limited to strings; (2) use an STL-like interface (i.e., iterators); and (3) reverse the string in place instead of reversing a copy of the string:
#include <algorithm> // std::swap
// the other headers are only for my example on how to use the code
#include <iostream>
#include <iterator>
#include <string>
#include <list>
template<typename Itor> void reverse_with_recursion(Itor begin, Itor end)
{
using std::swap; // same trick used by the STL to get user-defined swap's,
// but fall back to std::swap if nothing else exists:
// http://en.wikipedia.org/wiki/Argument-dependent_name_lookup#Interfaces
// if begin and end are pointing at the same element,
// then we have an empty string and we're done
if (begin == end) {
return;
}
// the STL follows the pattern that end is one element after
// the last element; right now we want the last element
--end;
// if begin and end are pointing at the same element *now*,
// then we have a single character string and we're done
if (begin == end) {
return;
}
swap(*begin, *end);
return reverse_with_recursion(++begin, end);
}
int main()
{
std::string foo("hello world");
reverse_with_recursion(foo.begin(), foo.end());
std::cout << foo << '\n';
std::list<int> bar;
for (int i = 0; i < 10; ++i) {
bar.push_back(i);
}
reverse_with_recursion(bar.begin(), bar.end());
std::copy(bar.begin(),
bar.end(),
std::ostream_iterator<int>(std::cout, " "));
std::cout << '\n';