Recursion call failure - c++

I'm creating a suduko generator and I either get a stack overflow when calling a function using recursion or it doesn't call the function when it is being called with the class, I can't explain very well what is happening but this is the code:
sudoku::sudoku()
{
srand((unsigned int)time(NULL));
generate(); // call the generate function
display(1);
}
sudoku::~sudoku()
{}
bool sudoku::validate(){ //makes sure not more than one of the same number in row/column
for (int x = 0; x < size; x++){
for (int y = 0; y < size; y++){
if (number == Array[x][y])
return true;
}
}
return false;
}
void sudoku::generate(){ // generates sudoku numbers which is 9x9
for (int x = 0; x < size; x++){
for (int y = 0; y < size; y++){
number = 1;
if (validate() == true){
generate(); //get a stack overflow with this call
//if I change "generate" to "sudoku generate" the
//stack overflow doesn't happen but then the function
} //is not called, the if statement just skips to the else
else{
Array[x][y] = number;
}
}
}
}
is there a way to call "sudoku generate()" without the if statement skipping the condition even when it is true? Or is there another way of doing this?

First of all the if statement is redundant
if(validate()==true)
validate returns a boolean right? why equate this to another boolean you can write this as:
if(validate())
The stack overflow might be caused of too many calls of the generate() and validate() function, remember each call of the recursion pushes another instance of this functions to the stack. To solve this you might want to take a look at the principles of communicating vases : https://www.youtube.com/watch?v=q1G6S0DbnJY
or you can audit this course on edX which gives a quick look at invariant programming and principles of communicating vases : https://courses.edx.org/courses/LouvainX/Louv1.01x/1T2014/info

Related

Stack OverFlow with Recursion

There is a stack overflow from my code I do not really know what is causing it. Parent is a fixed array like 14.
protected:
int* parent = new int[14];
int size = 14;
int Tree::level(int i) {
int count = 0;
for (int j = 0; j < size; j++) {
if (parent[i] == -1) {
count = 1;
} else {
count = level(i) + 1; //this is causing the stack Overlow
}
}
return count;
}
The recursive call in the following call is bound to cause an infinite recursion since i is not changed in the function.
count = level(i) + 1;
I am guessing that you meant to use j or parent[i] instead of i in that call. It's hard to tell what is the right value to use in the recursive call without more context.
In case of condition parent[i] == -1 false, function "level" becomes infinite recursive and hence stack overflow.

How do I refactor duplicate control structures?

I have duplicated control structures which are exactly the same, and the difference is how things happen inside. In particular, I don’t know how to deal with break, continue, and return. For example:
int f() {
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++) {
if (isFoo(i, j)) {
// doSomethingF1
} else {
// doSomethingF2
}
}
}
}
int g() {
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++) {
if (isFoo(i, j)) {
// doSomethingG1
} else {
// doSomethingG2
}
}
}
}
where doSomethings rely on i and j, and need to break or continue through the j loop, and return out of the function. How do I factor this out to get rid of the duplication?
I thought of writing a function that would take the doSomethings as arguments, but I'm not sure how to deal with the breaks, continues, or returns.
[I'm not fine with the duplication since there are some checks on i and j in f(), g(), and like four other functions that are exactly the same; the only difference is a few lines of code.]
If you really want/insist to have the same inner control in the loop context with break, continue, and return then the proposed solution is macros :-(.
On the other hand, if the doSomethingFG12 functions all have a defined interface, then compliment your generic control structure to handle the case with break, continue, and return to make a choice from there return values.

While loop task in c++

I am a beginner in c++ and I am having problems with making this code work the way I want it to. The task is to write a program that multiplies all the natural numbers up to the loaded number n.
To make it print the correct result, I divided x by n (see code below). How can I make it print x and not have to divide it by n to get the correct answer?
#include<iostream>
using namespace std;
int main(){
int n,x=1;
int i=0;
cout<<"Enter a number bigger than 0:"<<endl;
cin>>n;
while(i<n){
i++;
x=i*x;
};
cout<<"The result is: "<<x/n<<endl;
return 0;
}
At very first a principle you best get used to as quickly as possible: Always check user input for correctness!
cin >> n;
if(cin && n > 0)
{
// valid
}
else
{
// appropriate error handling
}
Not sure, why do you need a while loop? A for loop sure is nicer in this case:
int x = 1;
for(int i = 2; i < n; ++i)
x *= i;
If you still want the while loop: Start with i == 2 (1 is neutral anyway) and increment afterwards:
i = 2;
while(i < n)
{
x *= i;
++i;
}
In case of n == 1, the loop (either variant) simply won't be entered and you are fine...
You already have two very good options, but here is an other one you might want to take a look at when you are at ease enough in programming :
unsigned factorial(unsigned value)
{
if (value <= 1)
{
return 1;
}
else
{
return value * factorial(value - 1);
}
}
It's a recursive function, which is kind of neat when used in proper moments (which could not be the case here unfortunately because the execution stack might get so big you fill your memory before you're done. But you can check it out to learn more about recursive functions)
When your memory is full, you then crash your app with what is called actually a stack overflow.
How can I make it so that in the last cout I can only put x and not have to divide x by n to get the correct answer?
It will be better to use a for loop.
// This stops when i reaches n.
// That means, n is not multiplied to the result when the loop breaks.
for (int i = 1; i < n; ++i )
{
x *= i;
}
cout << "The result is: " << x <<endl;

why is bubble sort not working [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
Given some numbers and the amount of numbers, I have to sort them in ascending order, then output how many passes and swaps were done. Why is it not working? Also, I wanted to use a vector for this problem; am i passing the vector into the function and calling it properly?
//bubble Sort
#include<iostream>
#include<vector>
using std::cin;
using std::cout;
bool isSorted(std::vector<int> & myData);
int main()
{
std::vector<int> myData;
int length = 0;
int pass = 0;
int swap = 0;
cin >> length;
int x = 0;
for(x; x < length; x++)
{
int input = 0;
cin >> input;
myData.push_back(input);
}
x = 1;
while(!isSorted(myData))
{
int trash = 0;
for(x; x < length; x++)
{
if(myData[x] < myData[x-1])
{
trash = myData[x];
myData[x] = myData[x-1];
myData[x-1] = trash;
swap++;
}
}
pass++;
}
cout << pass << " " << swap;
return 0;
}
bool isSorted(std::vector<int> & myData)
{
for(int i = 1; i < myData.size(); i++)
{
if(myData[i] < myData[i-1])
{
return false;
}
}
return true;
}
You do not reset x between iterations of bubble sort. What happens is that before the first iteration of your outer loop x is equal to one. You then run the inner while loop until x becomes length, and go to the next iteration of the outer loop. By the next iteration x is never reset, so it still equals to length, so nothing happens on the second iteration, the inner loop immediately breaks without doing any work. You go to the third iteration of the outer loop, and nothing happens again. In particular, your array never becomes sorted, so the outer while loop never breaks, and the program never finishes (and never prints anything).
To fix it, just move x = 1 inside the loop, like this:
...
while(!isSorted(myData))
{
x = 1;
int trash = 0;
...

C++ program cant find mistake [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
this program creates random number array where elements wit arguments 1,3,5,7...,19 are negative and this program should find biggest negative element but when l test program it writes some random number (6784345 instead of array element) can you help me find mistake ?
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
void najneg(int *pa,int *nn)
{
nn=0;
for(int i=0;i<20;i++)
{
if((pa+i)<nn) nn=(pa+i);
}
}
int main()
{
int a[20],nn,i;
srand(time(0));
for(i=0;i<20;i++)
{
if(i%2==0) a[i]=rand()%(61);
else
a[i]=(rand()%(61))*(-1);
}
printf("Formirani niz je:\n");
for(int i=0;i<20;i++)
{
printf("\ "); printf("%d",a[i]);
}
najneg(a,&nn);
printf("\n\nNajveci negativni clan niza je:%d\n",nn);
return 0;
}
In this code, …
void najneg(int *pa,int *nn)
{
nn=0;
for(int i=0;i<20;i++)
{
if((pa+i)<nn) nn=(pa+i);
}
}
you forgot to dereference the pointers,
void najneg(int *pa,int *nn)
{
*nn=0;
for(int i=0;i<20;i++)
{
if(*(pa+i)<*nn) *nn=*(pa+i);
}
}
The most important fix for this function is to change its name to something readable and self-descriptive, with no arbitrary shortenings. When choosing names, think about making the calling code readable and clear. So E.g., najneg → most_negative_value_in.
Secondly, instead of logical out-argument, use the function return value.
Third, if the function doesn't need to change data, use const to let it offer a guarantee that it won't change the data.
Fourth, avoid magic numbers like 20: pass the array size as argument.
This, plus some purely cosmetic changes, yields:
int most_negative_number_in(int const* const a, int const size)
{
int n=0;
for(int i=0; i<size; ++i)
{
if(a[i]<n) { n = a[i] };
}
return n;
}
This function should be
void najneg(int *pa,int *nn)
{
*nn=0; //As you want to modify nn.
for(int i=0;i<20;i++)
{
if(pa[i]<*nn) *nn=pa[i]; //Here, you want to compare values and swap them. Not just address.
}
}
Do not try to complicate it.
In addition to what others have pointed out:
You can simplify the content of your for loops:
for(i = 0; i < 20; i++)
{
// The array slot is assigned a random value
// whether the index is positive or negative.
a[i] = rand() % 61;
// If the index is odd, change the value
// to a negative number.
if(i % 2 == 1)
{
a[i] *= -1;
}
}
In the next loop, you should combine into one printf call:
for(int i = 0; i < 20; i++)
{
printf("\ %d", a[i]);
}
Also, what is "\ " in the format specifier, a tab or a space?