I have this code to generate lexicographic permutations. The following logic is used:
Start from the increasing order arrangement of the chars in a given test string.
To generate next lexicographic permutation:
a) find the rightmost character which is smaller than its next character. SAY A.
b) to the right of A, find the next larger character. SAY B. and swap A & B.
c) to the right of the original position of A, sort characters in an increasing order.
Algorithm ends when we get the last permutation. i.e. reverse of given test string.
my test string s = "0123456789"
Edit:
On every single run of the program, i get a separate position of segmentation fault.
to get A:
int firstchar(string s){
int pos = s.length()-2;
for(int i=pos;i>=0;i--){
if(s[i]<s[i+1]){
pos = i;
break;
}
}
return pos;}
to get B and then recursive approach (qsort is a function from <cstdlib>):
int ceilchar(string s, int fc){
int ceil = fc+1;
int diff=27;
for(int i=ceil;i<s.length();i++){
if(s[i]>s[fc] && s[i]-s[fc]<diff){
ceil = i;
diff = s[i]-s[fc];
}
}
return ceil;}
starting func:
void nextpermute(string& s){
int fc = firstchar(s);
int cc = ceilchar(s,fc);
swap(s,fc,cc);
sort(&s[fc]+1,&s[fc]+s.length()-fc);
if(s!="9876543210"){
cout<<s<<"\n";
nextpermute(s);
}
else
cout<<s<<"\n";}
call from main: nextpermute(test);
If the test string is "01234567" or anything smaller than this, it works well. but if it is a string like
"012345678" or "0123456789" , then i get segmentation faults.
Please help!!
I suspect your stack size is crossing its limit. If you are running it on Linux, do "limit" and see your stacksize. There are two ways to avoid this situation
1) (Not Recommended) Do "limit stacksize unlimited" (only if you are on unix based system). And run the program again.
2) (Recommended).
Change
void nextpermute(string& s){
int fc = firstchar(s);
int cc = ceilchar(s,fc);
swap(s,fc,cc);
sort(&s[fc]+1,&s[fc]+s.length()-fc);
if(s!="9876543210"){
cout<<s<<"\n";
nextpermute(s);
}
else
cout<<s<<"\n";
}
to
void nextpermute(string& s){
int fc = firstchar(s);
int cc = ceilchar(s,fc);
swap(s,fc,cc);
sort(&s[fc]+1,&s[fc]+s.length()-fc);
cout <<s<<"\n";
}
and modify your main function as
int main()
{
string s = "0123456789";
while (s != "9876543210")
{
nextpermute(s);
}
}
Above change will do away with the recursion of "nextpermute" and hence your stacksize limit will never be crossed
Related
I'm trying to create this c++ program to perform the description below. I am pretty certain the issue is in the recursive, but uncertain how to fix it. I'm guessing it just keeps iterating through to infinity and crashes. I do not even get an output. I figured I could just compare the previous and current pointer and perform a 3-piece temp swap based on lexicography. I would use a pointer to iterate through the array and decrement it after each swap, then recursively call with that ptr as the parameter. Didn't work, I'm here, help me please :). If there is a simpler solution that would work too, but prefer to understand where I went wrong with this code.
#include <string>
#include <iostream>
using namespace std;
// Given an array of strictly the characters 'R', 'G', and
// 'B', segregate the values of the array so that all the
// Rs come first, the Gs come second, and the Bs come last.
// You can only swap elements of the array.
char* RGBorder(char* c_a)
{
size_t sz = sizeof(c_a)/sizeof(*c_a);
char* ptr_ca = c_a;
char* prv_ptr = ptr_ca;
ptr_ca++;
char temp;
while(*ptr_ca)
{
switch(*ptr_ca)
{
case 'R' :
if( *prv_ptr < *ptr_ca ) {
temp = *prv_ptr; *prv_ptr = *ptr_ca; *ptr_ca = temp;
} else if( *prv_ptr == *ptr_ca ) {
continue;
} else { ptr_ca--; RGBorder(ptr_ca); }
case 'G' :
if( *prv_ptr < *ptr_ca ) {
temp = *prv_ptr; *prv_ptr = *ptr_ca; *ptr_ca = temp;
} else if( *prv_ptr == *ptr_ca ) {
continue;
} else { ptr_ca--; RGBorder(ptr_ca); }
default:
ptr_ca++;
continue;
}
ptr_ca++;
cout << *ptr_ca;
}
return c_a;
}
int main()
{
char ca[] = {'G', 'B', 'R', 'R', 'B', 'R', 'G'};
char *oca =RGBorder(ca);
char *pca = oca;
while(*pca)
{
cout << *pca << endl;
pca++;
}
}
There are many issues with your code.
1) You call the function RGBorder with a character pointer, and then attempt to get the number of characters using this:
size_t sz = sizeof(c_a)/sizeof(*c_a);
This will not get you the number of characters. Instead this will simply get you the
sizeof(char *) / sizeof(char)
which is usually 4 or 8. The only way to call your function using a char array is either provide a null-terminated array (thus you can use strlen), or you have to pass the number of characters in the array as a separate argument:
char *RGBorder(char *c_a, int size)
2) I didn't go through your code, but there are easier ways to do a 3-way partition in an array. One popular algorithm to do this is one based on the Dutch National Flag problem.
Since you want the array in RGB order, you know that the series of G will always come in the middle (somewhere) of the sequence, with R on the left of the sequence, and B always on the right of the sequence.
So the goal is to simply swap R to the left of the middle, and B to the right of the middle. So basically you want a loop that incrementally changes the "middle" when needed, while swapping R's and B's to their appropriate position when they're detected.
The following code illustrates this:
#include <algorithm>
char *RGBorder(char *c_a, int num)
{
int middle = 0; // assume we only want the middle element
int low = 0; // before the G's
int high = num - 1; // after the G's
while (middle <= high)
{
if ( c_a[middle] == 'R' ) // if we see an 'R' in the middle, it needs to go before the middle
{
std::swap(c_a[middle], c_a[low]); // swap it to a place before middle
++middle; // middle has creeped up one spot
++low; // so has the point where we will swap when we do this again
}
else
if (c_a[middle] == 'B') // if we see a 'B' as the middle element, it needs to go after the middle
{
std::swap(c_a[middle], c_a[high]); // place it as far back as you can
--high; // decrease the back position for next swap that comes here
}
else
++middle; // it is a 'G', do nothing
}
return c_a;
}
Live Example
Here is another solution that uses std::partition.
#include <algorithm>
#include <iostream>
char *RGBorder(char *c_a, int num)
{
auto iter = std::partition(c_a, c_a + num, [](char ch) {return ch == 'R';});
std::partition(iter, c_a + num, [](char ch) {return ch == 'G';});
return c_a;
}
Live Example
Basically, the first call to std::partition places the R's to the front of the array. Since std::partition returns an iterator (in this case, a char *) to the end of where the partition occurs, we use that as a starting position in the second call to std::partition, where we partition the G values.
Note that std::partition also accomplishes its goal by swapping.
Given this solution, we can generalize this for an n-way partition by using a loop. Assume we want to place things in RGBA order (4 values instead of 3).
#include <algorithm>
#include <iostream>
#include <cstring>
char *RGBorder(char *c_a, int num, char *order, int num2)
{
auto iter = c_a;
for (int i = 0; i < num2 - 1; ++i)
iter = std::partition(iter, c_a + num, [&](char ch) {return ch == order[i];});
return c_a;
}
int main()
{
char ca[] = "AGBRRBARGGARRBGAGRARAA";
std::cout << RGBorder(ca, strlen(ca), "RGBA", 4);
}
Output:
RRRRRRRGGGGGBBBAAAAAAA
Sorry to put it blunt, but that code is a mess. And I don't mean the mistakes, those are forgivable for beginners. I mean the formatting. Multiple statements in one line make it super hard to read and debug the code. Short variable names that carry no immediate intrinsic meaning make it hard to understand what the code is supposed to do. using namespace std; is very bad practise as well, but I can imagine you were taught to do this by whoever gives that course.
1st problem
Your cases don't break, thus you execute all cases for R, and both G and default for G. Also your code will never reach the last 2 lines of your loop, as you continue out before in every case.
2nd problem
You have an endless loop. In both cases you have two situations where you'll end up in an endless loop:
In the else if( *prv_ptr == *ptr_ca ) branch you simply continue; without changing the pointer.
In the else branch you do ptr_ca--;, but then in default you call ptr_ca++; again.(Note that even with breaks you would still call ptr_ca++; at the end of the loop.)
In both cases the pointer doesn't change, so once you end up in any of those conditions your loop will never exit.
Possible 3rd problem
I can only guess, because it is not apparent from the name, but it seems that prv_ptr is supposed to hold whatever was the last pointer in the loop? If so, it seems wrong that you don't update that pointer, ever. Either way, proper variable names would've made it more clear what the purpose of this pointer is exactly. (On a side note, consistent usage of const can help identify such issues. If you have a variable that is not const, but never gets updated, you either forgot to add const or forgot to update it.)
How to fix
Format your code:
Don't use using namespace std;.
One statement per line.
Give your variables proper names, so it's easy to identify what is what. (This is not 1993, really, I'd rather have a thisIsThePointerHoldingTheCharacterThatDoesTheThing than ptr_xy.)
Fix the aforementioned issues (add breaks, make sure your loop actually exits).
Then debug your code. With a debugger. While it runs. With breakpoints and stepping through line by line, inspecting the values of your pointers as the code executes. Fancy stuff.
Good luck!
just count the number of 'R', 'G' and 'B' letters and fill the array from scratch.
much easier, no recursions.
string Expression::addevaluate(string x){
stringrep = x; //Stringrep is the string that user typed in,
//it might be 5+6+7-8-9*3/(2+5)
int totalnum = stringrep.length();
for(int i=0;i < totalnum;i++){ //This for loop will seperate the
//string by "+" and output a vector
//with seperate string
int addop = stringrep.find("+");
addvector.push_back(stringrep.substr(0,addop));
string a =stringrep.substr(0,addop);
totalnum=totalnum-(a.length());
stringrep = stringrep.substr(addop+1,totalnum);
}
int vectorlength = addvector.size();
for(int i = 0;i<vectorlength;i++){
cout << i+1<<":"<<addvector[i]<<",";
}
subevaluate(addvector);
return stringrep;
}
string Expression::subevaluate(vector<string> &v){
int totalnum = v.size();
//This is the question, I have no idea how can i set the value totalnum
//If it's the size of vector,it's too small. If it's the last totalnum
//from last function. Then there is a error. In addition,I do not know
//what the error is.
for(int i=0;i < totalnum;i++){
int addop = v[i].find("-");
if(addop > 0){
subtvector.push_back(v[i].substr(0,addop));
string a =v[i].substr(0,addop);
totalnum=totalnum-a.length();
v[i] = v[i].substr(addop+1,totalnum);
}
}
int vectorlength = subtvector.size();
for(int i = 0;i<vectorlength;i++){
cout << i+1<<":"<<subtvector[i]<<",";
}
return stringrep;
}
I do not know why I did wrong for the second for loop. Please help me solve the for loop. In addition,how can i seperate all the string by."+","-","*","/". Then calculate the answer like a calculator. Thanks.
This implementation will not work... suppose you have
"1+2*(3+4)"
the first split (even when written correctly) will get
"1"
"2*(3"
"4)"
What are you going to do with "2*(3" ?
At the very minimum to write a calculator with this approach you need:
add "(" front and add ")" at the end (i.e. change to "(1+2*(3+4))"
look for last OPEN parenthesis
move from there to the first CLOSED parenthesis
process what is in-between (i.e. "3+4") and replace the whole parenthesized expression it in the original string with the result (i.e. get from "1+2*(3+4)" to "(1+2*7)")
repeat until there are no more parenthesis
For splitting a string on a given character you should write a dedicated function, for example:
std::vector<std::string> split(const std::string& text, char sep) {
std::vector<std::string> result;
size_t pos = text.find(sep);
while(pos != std::string::npos) {
result.push_back(text.substr(0, pos));
text = text.substr(pos + 1);
}
result.push_back(text);
return result;
}
then you can write
std::vector<std::string> res = split(text, '+');
to get from "1+2*3+4" to a vector containing "1", "2*3", "4".
PS: Note that this way of computing expression is not what normally is done, but it can be made working so you should in my opinion keep working on it until it's done.
I think it will be difficult to make the code work when you split the string into a vector. The operator precedence will be too hard to handle, I think.
How about a recursive process?
In this way you can simplify the original string step by step. You just keep calling the evaluate function with substrings until they are turned into simple expressions.
Example:
exp = 12/(5+1)
call 1: call f("12/(5+1)")
call 1: f identifies the substring "5+1" and call itself (recursive)
call 2: call f("5+1")
call 2: simple expression calculates into "6" which is returned
call 1: The substring "(5+1)" is replaced by the returned "6"
call 1: exp now looks "12/6"
call 1: simple expression calculates into "2" which is returned
More complex expressions like "48/(5 + (2*3/(3-1))) would just result in more calls so that the string is simplified step by step.
The code could look like the code below. Only the structure is include - it is for OP to fill in the actual code.
bool isSimpleExpression(string& s)
{
// Return true if s is simple, i.e. X+Y, X-Y, X*Y, X/Y
// Otherwise false
}
string evaluateString(string& exp)
{
while(!isSimpleExpression(exp))
{
// exp must be broken into smaller part as it isn't simple yet
if (ExpContainsParanthesis() )
{
// Example: exp is "12/(5+1)"
string s1 = FindSubstringInMostInnerMatchingParanthesis(exp);
// Example: s1 is "5+1"
// Example: call evaluateString("5+1")
strint s2 = evaluateString(s1); // Recursive call
// Example: s2 is 6
ReplaceS1WithS2(exp, s1, s2);
// Example: exp is "12/6"
}
else if (ExpContainsMultiplication())
{
// Find the substring with multiplication
// Call this function with the substring
// Replace the substring with the returned result
}
else if ....
{
// division
}
// ... and so on
}
// Calculate the simple expression
string result;
// ..
// ..
return result;
}
I'm trying to find all paths of length L in a 2-D grid(forgetting boundaries for the moment) by calling route(string s) recursively and appending to the stringth.
'l' stands for left
'r' stands for right
'd' stands for down
and
'u' stands for up
My logic is correct I think. I need to call route(string s) recursively with each of these values and append to s.
I can see the flaw in my code but cannot think of a way to correct it. I am changing the value of string s by appending to it 'r','l','u' or 'd' at each call but since successive calls are in the same scope, i get garbage answers and not the permutations of u,l,d,r that I am expecting.
#include <iostream>
#include <vector>
using namespace std;
void route(string s, int k);
int main(void){
string result="";
route("",5);
}
void route(string initial, int k){
if(initial.length()>5){
cout<<initial<<endl;
cout<<"Length of initial:"<<initial.length();
return;
}
for(int i=0;i<4;i++){
switch(i){
case 0:
{
initial.append("r");
route(initial);
}
case 1:
{
initial.append("l");
route(initial);
}
case 2:
{
initial.append("u");
route(initial);
}
case 3:
{
initial.append("d");
route(initial);
}
}
}
}
There is no need to change initial, just pass the new string to route. e.g.
route(initial + "u",k-1);
Note that you aren't using the k value currently, and you also aren't recursing for the r and l cases.
One more thing - a for loop with a switch in it for each different case, is a strange construction. Why not just call the 4 different options one after the other?
route(initial + "l",k-1);
route(initial + "r",k-1);
route(initial + "u",k-1);
route(initial + "d",k-1);
I am trying to make a program that, with a given word, can calculate and print every letter combination.
To be more specific, I am asked to use a recursive function and what I should get is something like this:
Given word: HOME
EHOM
EMOH
MEHO
The approach I am taking in to swap the content #x with #x+1 like this
string[0]->string[1]
string[0]->string[2]
This is what I came up with
void anagram(char * s, int len, int y)
{
char temp; //used to store the content to swap betwen the two
if (len < 0) //when the total lenght of the array gets to 0 it means that every single swap has been made
return;
temp = s[len]; //swapping
s[len] = s[y];
s[y] = temp;
puts(s); //prints the string
if (y == 0)
return anagram(s, len-1, y - 1);
return anagram(s, len, y - 1);
}
What I get is just a huge mess and a Break Point from VS (if not a crash).
Can somebody help me please?
(This problem is taken from IEEE Xtreme 2013 problem AS)
The problem I have to solve is as follows:
I am given a series of letters, consisting of pairs of joined crossroads, such as the below
F G
F H
H I
H J
I K
J K
G H
G I
The task is to navigate from one given letter to another, such as from F to K. In this case the optimum path would be F, H, I, K (i.e. the shortest path (or one of them)).
Part of the task is to find all possible paths. As the length of the path is variable, along with the number of crossroads and the number of crossroads joined to each crossroad, I reasoned I would need a variable level of nested loops - a new nested level of loop for each step along the path, along with the ability to step back along the path and go in a different direction.
the only way I could think of solving this was by creating a function, passing it an incomplete path, search for a joined letter, and have the function call itself until it reaches the end of the path, whereupon it steps back to a previous crossroads and goes in a different direction.
Is the recursion here a bad idea, or inefficient? is there a better/simpler/clearer way of solving this problem?
Code: (It doesn't quite run yet, I'm not finished with it)
(The recursive function is pathfind)
// Problem_AS (ice cream route finder).cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
//typdefs
typedef vector<char> route;
//each route when found will be put into a vector of routes
//function declarations
bool checkChar(vector<char>& chars, const char& c);
vector<char> create_turnings(vector<string>& pairs);
vector<char> find_joined(const char& a, vector<string>& routes);
void pathfind(const vector< vector<char> >& joined, const char& current, const char& dest, vector<char>& non_option,
vector<route>& routes, const vector<char>& turnings, route& current_route);
int _tmain(int argc, _TCHAR* argv[])
{
char dest;
cin >> dest;
char start = 'f';
vector<string> joined;
const string a_a = "a a";
char input[4];
do
{
cin.getline(input, sizeof(input));
if (input != a_a)
joined.push_back(input);
} while (input != a_a);
vector<char> turnings = create_turnings(joined);
//alpabetic list of all the turns
/*vector<char>::iterator iter;
for (iter = turnings.begin(); iter < turnings.end(); iter++)
{
cout << *iter << endl;
}*/
//dir is a vector of string vectors - for each letter, there will be a vector, containing all the
//letters that can be reached from the current letter
vector < vector<char> > dir;
for (unsigned int i = 0; i < turnings.size(); i++)
{
dir.push_back(find_joined(turnings[i], joined));
cout << turnings[i] << ": ";
for (unsigned int j = 0; j < dir[i].size(); j++)
{
cout << dir[i][j] << ", ";
}
cout << endl;
}
vector<char> non_option;
//will be passed to functions, contains all the letters that have been used or should not be
route current_route; //contains the current path
vector< route > routes; //vector of all valid paths
pathfind(dir,start, dest, non_option, routes, turnings, current_route);
getchar();
return 0;
}
//checks if char c is present in the character array chars
bool checkChar(vector<char>& chars, const char& c)
{
vector<char>::iterator iter;
for (iter = chars.begin(); iter < chars.end(); iter++)
{
if (*iter == c)
return true;
}
return false;
}
//converts a string vector of pattern:
//"g t"
//"t y"
//"d t"
//etc into a char vector in alphabetic order (containing no repeated characters)
//the first entry in pairs is skipped, as it is empty
vector<char> create_turnings(vector<string>& pairs)
{
vector<char> a;
a.push_back(pairs[1][0]);
if (!checkChar(a, pairs[1][2]))
a.push_back(pairs[1][2]);
vector<string>::iterator iter;
//do first action so that check char in loop has something to check against
for (iter = pairs.begin() + 2; iter < pairs.end(); iter++)
{
if (!checkChar(a, (*iter)[0]))
a.push_back((*iter)[0]);
if (!checkChar(a, (*iter)[2]))
a.push_back((*iter)[2]);
}
sort(a.begin(), a.end());
return a;
}
//takes a letter in the map, and finds all the letters associated with it, and outputs them in a char vector
//(alpthabetcially)
vector<char> find_joined(const char& a, vector<string>& pairs)
{
vector<char> joined;
vector<string>::iterator iter;
for (iter = pairs.begin()+1; iter < pairs.end(); iter++) // must skip first element as it is an empty string
{
if ((*iter)[0] == a)
joined.push_back((*iter)[2]);
if ((*iter)[2] == a)
joined.push_back((*iter)[0]);
//must check is the letter we are finding associations for on the left or right of the route - the opposite
//side of the joined letters will be added
}
sort(joined.begin(), joined.end());
return joined;
}
void pathfind(const vector< vector<char> >& joined, const char& current, const char& dest, vector<char>& non_option,
vector<route>& routes, const vector<char>& turnings, route& current_route)
{
current_route.push_back(current);
non_option.push_back(current);
//find the index of current in turnings
unsigned int index;
for (index = 0; index < turnings.size(); index++)
{
if (turnings[index] == current)
break;
}
int x = joined[index].size();
for (int i = 0; i < x; i++)
{
if (checkChar(non_option, joined[index][i]))
continue;
//check if the character being checked has been makred as a non option already
if (joined[index][i] == dest)
{
current_route.push_back(joined[index][i]);
routes.push_back(current_route);
continue;
}
//check if the character being checked is the destination, in which case mark a route
pathfind(joined, joined[index][i], dest, non_option, routes, turnings, current_route);
while (non_option.size() != current_route.size())
{
non_option.pop_back();
}
}
while (non_option.size() != current_route.size())
{
non_option.pop_back();
}
current_route.pop_back();
}
In answer to the question, but without specific reference to the code given:
Is recursion a bad thing?
In general, No.
What are the trade-offs?
Often using recursion boils down to simplicity of implementation versus simpicity of debugging and flexibility of changing implementations.
General factors around recursive / non-recursive implementations:
Judging by the number of questions that crop-up on StackOverflow regarding recursion, it's pretty clear that recursive code is harder to follow for many developers, partly because the code-path isn't always obvious. A non-recursive function is often easier to debug... you can step through the code and examine your stack easily without having to track which invocation of the method you're at.
However, removing recursion can sometimes make code more complex... often you have to introduce your own stack and do a bit of housekeeping that isn't necessary with recursive code.
I frequently see posters on Stack Overflow using recursion when a simple iteration would suffice such as traversing a list (no stack needed). In these trivial cases recursion should definitely be avoided (unless its a requirement of your assignment). In more comlex cases, the performance differences between a recursive solution and a non-recursive one usually aren't significant.
And although recursion itself isn't bad, one consideration is that because the size of the stack is limited by your environment you have an arbitrary limit imposed on you for the amount of recursive calls. If you know that the termination condition for your calls is met quickly then by all means recurse. If you're working with very large data sets, and potentially deep recursion, exercise caution and favour a non-recursive implementation.
Whenever you are thinking about a recursive solution (or any algorithm for that matter), favour clarity, readability and easy debugging first, only optimise when performance profiling shows there's a problem. Try to keep code encapsulated so implementations can be easily swapped out.
The recursion in not always a bad idea, however there's a problem with using a recursion which is the stack depth. If your recursion goes too deep - you run out of stack and your program will not work properly. Stack depth can change from system to system, may or may not be adjustable, and stack overruns may or may not lead to an immediate crash.
If you're considering a recursion of bounded depth that you know is within the limits of your stack - go for it, it is the easier way to write code.
If you're considering recursion with unbounded depth (i.e.: you don't know how big the input can be and how many calls you're going to make) - you better implement it iteratively (i.e.: without using the OS stack, use your own structures to manage the state).
There are also ways to make recursions more efficient wrt the stack usage (for example - tail recursion).
In this particular case, the input doesn't seem to be too large, and I'd expect the recursion to work. If it doesn't - it is more likely to be a bug in your algorithm/implementation, rather than an inherent "recursion problem".