I'm quite new to programming and for my Object Oriented class (in C++), we have a 2d array with random groupings of "X". I have to use a recursive function to find the different groupings and clear them. As of right now, I check if the spot is an X, clear it, then check the 8 positions around it (including diagonals), and if one of the positions in an X, I call the function again but on that location. My idea is that if I find one X, I will be able to get all the X's around it in one go, thus, I can count it as a group when I find an X.
At the end of the function, I basically loop through all the spots and call the recursive function again if there is another X. However, I keep getting segmentation faults and I'm not sure why. Any help would be greatly appreciated!
void Recurssive(string Array[][72],int Pos1, int Pos2)
{
int One=1;
int Two=1;
//cout<<"Test 2";
if(Array[Pos1][Pos2]=="X")
{
Array[Pos1][Pos2]="0";
if(Array[Pos1+1][Pos2]=="X")
{
Recurssive(Array,Pos1+1,Pos2);
}
if(Array[Pos1-1][Pos2]=="X")
{
Recurssive(Array,Pos1-1,Pos2);
}
if(Array[Pos1][Pos2+1]=="X")
{
Recurssive(Array,Pos1,Pos2+1);
}
if(Array[Pos1][Pos2-1]=="X")
{
Recurssive(Array,Pos1,Pos2-1);
}
if(Array[Pos1+1][Pos2+1]=="X")
{
Recurssive(Array,Pos1+1,Pos2+1);
}
if(Array[Pos1-1][Pos2-1]=="X")
{
Recurssive(Array,Pos1-1,Pos2-1);
}
if(Array[Pos1+1][Pos2-1]=="X")
{
Recurssive(Array,Pos1+1,Pos2-1);
}
if(Array[Pos1-1][Pos2+1]=="X")
{
Recurssive(Array,Pos1-1,Pos2+1);
}
}
for(int i=1;i<22;i++)
{
for(int j=1;j<72;j++)
{
if(Array[i][j]=="X")
{
Recurssive(Array,i,j);
}
}
}
}
Here is the output of the array I am looping through
X
X
X XXXXXXXXXXXXXXX
X XXXXXXXXXXXXXXX
X XXXXXXXXXXXXXXX XXXX
XXXX XXXXXXXXXXXXXXX XXX XXX
X XXX XXX
XXXXXXXXXXXXXX X XXX XXX
XX XX X XXX XXX
XX XX X XXX XXX
XX XX X XXXX
XX XXXXX XX X
XX XX X
XX XX X
XXXXXXXXXXXXXX X
X
X
X
X
X
Let's play computer and go through the motions for Recurssive(Array, 0, 0).
If this position was marked as X, this will make the following array accesses, in order:
Array[1][0]
Array[-1][0]
Array[0][1]
Array[0][-1]
Array[1][1]
Array[-1][-1]
Array[1][-1]
Array[-1][1]
These -1 accesses will go outside the memory defined by Array and may read a random value or may cause a segmentation fault.
In order to fix this, you need to verify that a candidate position is inside the board before you actually access it.
Something like:
std::optional<std::string> safe_access(std::string Array[][72], int Pos1, int Pos2) {
if (Pos1 < 0 || Pos1 >= 71) return {};
if (Pos2 < 0 || Pos1 >= 21) return {};
return Array[Pos1][Pos2];
}
You can then call safe_access(Array, -1, -1) == "X" and be guaranteed this will not access outside of Array.
Related
X Y
So,I'm having two numbers. say, [12,3]
And I want to compare 123 with 321 i,e XY and YX
Or [1234,4] ---> 12344<44321
If I directly try using append, that is not valid in python.
C++ code which does what I want->
int Compare(string X, string Y)
{
// first append Y at the end of X
string XY = X.append(Y);
// then append X at the end of Y
string YX = Y.append(X);
// Now see which of the two formed numbers is greater
if (XY > YX)
{
return 1;
}
else
{
return 0;
}
}
Firstly there is a mistake in your C++ code
XY=X.append(Y) will also change X to X+Y
for example consider the following code snippet:
string X="ab", Y="cd";
string XY=X.append(Y);
cout<<"X="<<X<<", Y="<<Y<<", XY="<<XY;
output:
X=abcd, Y=cd, XY=abcd
Because append will first join Y in X then assign value of X to XY.
this will cause problem when you compute YX later.
I will suggest using '+' operator instead:
int Compare(string X, string Y)
{
string XY = X+Y;
string YX = Y+X;
if (XY > YX) return 1;
else return 0;
}
Equivalent Python3 code would be
def Compare(X, Y):
X=str(X) # Convert to string in case integer parameters are passed (if you are
Y=str(Y) # sure that only string will be passed you can skip these two lines)
XY = X+Y
YX = Y+X
if (XY > YX):
return 1
else:
return 0
You can concatenate strings in python using +. I.e., "a" + "b" results in the string "ab". To convert a string into a number use int() constructor. I.e., int("10") will produce the number 10.
This should provide you with enough information to form the solution to your problem.
arr.push_back("1");
arr.push_back("34");
arr.push_back("3");
arr.push_back("98");
arr.push_back("9");
arr.push_back("76");
arr.push_back("45");
arr.push_back("4");
sort(arr.begin(), arr.end(), myCompare);
//Here is the compare function
int myCompare(string X, string Y)
{
string XY = X.append(Y);
string YX = Y.append(X);
return XY.compare(YX) > 0 ? 1: 0;
}
//output should be 998764543431
I got some confusion regarding the sorting for eg. we have numbers {"1","34","3","98","9","76","45","4"}. When we first compare 2 strings we have 2 options 134 and 341 so as 341 is bigger we'll get 341 as a returned string.
Similarly, we get 3341 in next iteration and 983341 in next and 9983341 in next but when 76 arrives it has to be appended either at the beginning or at the end either it will 998334176 or 769983341 which is wrong. Am I missing something?
There are a few issues. Ignoring the questions of why you're storing int as std::string? This only makes sense if you'll be storing non-integer data in the array at some point. Integer comparison is very fast. string comparison is slow and almost never produces the desired result.
First,
std::string::append modifies the parameter. So, if I have:
string x = "left";
string y = "right";
string xy = x.append(y);
x now equals "leftright", as does xy. Your comparison function would append x to y, then y to the result.
Your method, called with X = 1, Y = 34:
string XY = X.append(Y);
// XY = "134", X = "134", Y = "34"
string YX = Y.append(X);
// YX = 34134, Y = "34134", X = "134"
return XY.compare(YX) > 0 ? 1: 0;
So, this could be expressed as
X = X + Y;
XY = X;
Y = Y + X;
YX = Y;
string::compare does a character compare. So, if your array were sorted just using string::compare, you'd get
1 3 34 4 45 76 9 98
Second,
When we first compare 2 strings we have 2 options 134 and 341 so as
341 is bigger we'll get 341 as a returned string.
"341" is bigger than "134". However, you aren't comparing "341" with "134" - you're comparing "134" with "3134". "3134" is only bigger because it starts with a 3 instead of a "1". If the numbers were "1341" and "341", "341" would still be bigger.
If your goal is just to sort the list based on integer value,
int myCompare(string X, string Y)
{
return atoi(X.c_str()) < atoi(Y.c_str());
}
Or, more sanely, use an int array instead of strings, and let sort use it's built-in comparison function.
I dont understand how this code works can you please explain it to me.
#include <iostream>
using namespace std;
int fun (int &x, int &y) {
if (y<=0)
return x;
x=x+2;
cout<<x<<y<<endl;
return x*y;
}
int main () {
int x=5, y=-1;
cout <<fun(x,y)<<endl;
fun(y,x);
fun(x,y);
fun(y,x);
cout <<fun(x,y)<<endl;
return 0;
}
the correct answers are
5
15
71
37
93
27
The first function call cout << fun(x,y) << endl; passes x as 5 and y as -1. Because y is less than 0 the function simply returns x to cout, so it prints 5.
The next function call fun(y,x) which still passes -1 and 5, however this time the values are passed in reverse so within the function x is -1 and y is 5. Because y is 5 the if statement is false and x is assigned -1 + 2, or 1. Then x as 1 and y as 5 are printed and the multiplication of the two is returned, however nothing is done with the multiplied value.
The third function call passes x and y, but in the previous function call x (as y) was changed to 1. Because the value was passed in as a reference of y, it is now 1. So, x is assinged 5 + 2 and x and y are printed as 71.
The fourth function call passes x and y again in reverse. So, recall that x was changed to 7 and y is 1. But the values are in reverse so in our function x is 1 and y is 7. So again x is assigned the value of 1 + 2 and these are printed as 3 and 7.
Finally, the last function call passes x and y, but remember that x (as y) was changed to 3. So now x is 7 and y is 3. Once more x is assigned 7 + 2, and x and y are printed as 93. Since the function was called from a cout statement the multiplication of 9 and 3 is also printed as 27.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
How can I calculate the recursive calls to this function and what will be the correct answer to it??????
int func(x,y)
{
if (x % y == 0) return y;
x = x % y;
return func(y,x);
}
I need a formula for it or an explanation or general expression for it really confused here?????
using global variable is easy solution.
int i;
main()
{
i=0; //if you want to avoid main call just start with i=-1
//if you are using loop and then calling function in loop ,
//make i value zero or -1 to know how many recursive calls are made to particular call.
func(x,y);
//now i consists number of recursive calls made.
}
int func(int x,int y)
{
i++;
if (x % y == 0) return m;
x = x % y;
return func(y,x);
}
First off your code won't compile. You need to give x and y types like int or long. Secondly you ;probably want to order x and y before you do anything else. Some thing like:
int func(int x, int y) {
int mx = max(x, y);
int mn = min(x, y);
// as above with mx for x and mn for y
}
How do you know the number of calls?
Well, there are two ways.
Instrument the code: add a variable that counts up to the top of the function, and when the function completes, print the count.
Walk the code yourself: Pretend to be the computer, calculate each step and follow the decision path. Do this for a variety of inputs and see what results it gives you. Count the number of steps it takes. Do remember to take into account where you are returning to - recursive functions return back to itself.
How to find the correct answer?
Similar to above.
Run the code and print the result.
Walk through the code, and figure out what the result is for each step, and what the final result is.
I would change your function into this:
int func(int x, int y, int& n)//I asume x and y are ints
{
if (x % y == 0) return y;
x = x % y;
return func(y,x, n+1);//not sure if I understood question correctly, so I think you need to change n value here.
}
int func(int x, int y, int& n)//I asume x and y are ints
{
++n;//not sure if I understood question correctly, it may be you need this place for count variable increment
if (x % y == 0) return y;
x = x % y;
return func(y,x, n);
}
And to use that function you will need:
int x = 1000, y = 7, n = 0;
int ret = func(x, y, n); //n must be zero
BTW, also you can use global variables, however it is not the best experience, so better pass one more parameter to the function.
I have the following function:
int mult(int y, int z)
{
if (z == 0)
return 0;
else if (z % 2 == 1)
return mult(2 * y, z / 2) + y;
else
return mult(2 * y, z / 2);
}
What I need to do is prove its correctness by induction. Now the trouble I'm having is that even though I know it works since I ran it I can't follow each individual step.
What is confusing me is that y only shows up as an argument and in no place does it show up in a return except in the recursive part, and yet the function actually returns y as the answer.
How does this happen? I need to be able to follow everything that happens so that I can do the iterations of it for the proof.
Since this is obviously a homework question, I recommend you do what the assinment was likely meant fot you to do. Trace through the code.
1) give a starting value for y and z.
2) either on paper or in a debugger, trace what happens when you call the function.
3) repeat step 2 with your current y/z values until program completion.
#include <iostream>
using namespace std;
int mult(int y, int z)
{
if(z==0) {
cout<<"z is null! - y:"<<y<<" z: "<<z<<endl;
return 0;
}
else if (z%2==1)
{
cout<<"z is odd! - y:"<<y<<" z: "<<z<<endl;
// make z even
return mult(2*y,z/2)+y;
}
else
{
cout<<"z is even! - y:"<<y<<" z: "<<z<<endl;
return mult(2*y,z/2);
}
}
int main() {
cout<<"result: "<<mult(3,13)<<endl;
}
Output:
z is odd! - y:3 z: 13
z is even! - y:6 z: 6
z is odd! - y:12 z: 3
z is odd! - y:24 z: 1
z is null! - y:48 z: 0
result: 39
How it works for 3 and 13:
There's a switch for even and odd numbers (see comment in code).
When z is null, the recursion "starts to return to the initial call". If the number z is odd it adds y to the returned value of the recursive call, if it's even it justs returns the value from the recursive call.
odd: return 0 + 24
odd: return 24 + 12
even: return 36
odd: return 36 + 3
step-by-step analisis
final result: 100
mult(10, 10)
{
makes 100
mult(20, 5)
{
makes 100
mult(40, 2) + 20
{
makes 80
mult(80, 1)
{
makes 80
mult(160, 0) + 80
{
return 0;
}
}
}
}
}
Note: If this is homework, tag it as such.
So, we basically got three recursive cases. To make it all clearer, I'd rewrite the C-code into some functional pseudo-code. Replace mult with an intuitive operator sign and figure out descriptive explanations of low-level expressions like (z%2==1).
You'll come up with something like
a ** b =
| b is 0 -> 0
| b is even -> 2a ** (b/2)
| b is odd -> 2a ** (b/2) + a
Do you get the point now?
One approach would be to translate each line into "English". My translation would be something like this:
if z is zero, return zero
if z is odd, return mult(y*2, z/2) + y
if z is even, return mult(y*2, z/2)
The general pattern is to recursively call mult with the first parameter doubling, and the second parameter halving.
Note that here you're calling mult with z/2, but its arguments are integers, so if your function continues to recurse, the 2nd parameter will halve each time until it gets down to 1, and then finally 1/2 which rounds down to 0 - at which point recursion will stop because z==0.
With those clues, you should be able to understand how this algorithm works.
Demonstrations by induction are based on proving that the result is valid for the first value, and that if the principle is correct for a generic value N, it is provable that it holds for N+1.
To simplify, you can start by proving that it works for z in { 0, 1, 2 } which should be trivial with a manual test. Then to demonstrate the induction step, you start with a generic z=N, and prove that if mult( y, N ) is a valid result, then mult( y, N+1 ) is also a valid result in terms of the previous one. Since there are different branches for even and odd numbers, you will have to prove the induction step for both even and odd N numbers.
ya = ya
a = an even number
b = the next odd number (in other words a + 1)
So, if you want the equation above in terms of only even numbers (an 'a') when given an odd number (a 'b') you can do the following:
yb = y(a+1) = y*a + y
Now confuse everyone by writing 'a' as 2*(z/2).
y*a becomes (2*y)*(z/2)
y*b becomes ((2*y)*(z/2))+y
Since 'z' appears in the formula for both even and odd numbers, we want to think that the code is telling us that (2*y)*(z/2) = (2*y)*(z/2) + y which is obviously MADNESS!
The reason is that we have snuck in the fact that z/2 is an integer and so z can never be odd. The compiler will not let us assign z/2 to an integer when z is odd. If we try to make 'z' odd, the integer we will really be using is (z-1)/2 instead of z/2.
To get around this, we have to test to see if z/2 is odd and pick our formula based on that (eg. either ya or yb in terms of 'a').
In mult(y,z) both 'y' and 'z' are both integers. Using the symbols above mult(2*y,b/2) becomes mult(2*y,a/2) because b/2 will be truncated to a/2 by the compiler.
Since we are always going to get an 'a' as a parameter to 'mult', even when we send a 'b', we have to make sure we are only using formulas that require 'a'. So, instead of yb we use ya+1 as described above.
b/2 = a/2 + 1/2 but 1/2 cannot be represented as part of an int.
Not really an answer, but more of a suggestion.
You may want to reduce the recursion call from 2 to one:
int mult(int y, int z)
{
int result = 0;
if (z == 0)
return result;
result = mult(2 * y, z / 2); // Common between "then" and "else"
if ((z % 2) == 1)
{
result += y;
}
return result;
}
This could be simplified once more by observing the rule "one exit point only":
int mult(int y, int z)
{
int result = 0;
if (z != 0)
{
result = mult(2 * y, z / 2); // Common between "then" and "else"
if ((z % 2) == 1)
{
result += y;
}
}
return result;
}
Although many compilers will perform this simplification automatically, debugging is usually easier when the code is simplified. The debugger will match the code when single-stepping.
Sometimes simplifying will add clarity. Also, adding comments will help you figure out what you are doing as well as the next person who reads the code.