How can I recover previous data from recursion? - c++

I have a small program below:
#include <iostream>
#include <time.h>
using namespace std;
void changeArray(int *a, int n)
{
swap(a[rand() % n], a[rand() % n]);
}
void Try(int* a, int n, int step)
{
if (step > n)
return;
changeArray(a, n);
Try(a, n, step + 1);
//Do something to recovery previous array data?
}
void printArr(int *a, int n)
{
for (int i = 0; i < n; ++i)
cout << a[i] << " ";
cout << endl;
}
int main()
{
srand(time(NULL));
int a[] = { 1, 2, 3, 4, 5 };
int step = 0;
int n = sizeof(a) / sizeof(int);
printArr(a, n); //Before
Try(a, n, 0);
printArr(a, n); //After recursion
// Expected array is : 1,2,3,4,5
return 0;
}
The problem is a as follows: can I recover previously created data? Line 17 will recover an array after Try() function is run on line 16.
The resulting, line 36, array will be 1,2,3,4,5.
Any ideas would be really appreciated! Thank you!

Related

Sorting the array gives erroneous values

I have implemented quick sort in c++. Following is my code .
#include <iostream>
using namespace std;
template <typename T>
void swap(T *a, T *b)
{
T temp;
temp = *a;
*a = *b;
*b = temp;
}
template <typename T>
void PrintArray(T arr[], int n)
{
cout << "---------- Array ----------" << endl;
for (int i=0; i<n ; i++)
{
cout << arr[i] <<'\t';
}
cout << endl;
}
template <typename T>
int partition(T arr[], int low, int high)
{
T pivot = arr[low];
int i = low+1, j = high;
do
{
while (pivot >= arr[i])
{
i += 1;
}
while (pivot < arr[j])
{
j -= 1;
}
if (i<j)
{
swap<T>(arr[i], arr[j]);
}
}while( i < j);
swap<T>(arr[low], arr[j]);
return j;
}
template <typename T>
void quick_sort(T arr[], int low, int high)
{
if (low < high)
{
int parition_index;
parition_index = partition<T>(arr, low, high);
quick_sort<T>(arr, low, parition_index-1);
quick_sort<T>(arr, parition_index+1, high);
}
}
int main()
{
// Array creation
int n = 8;
int a[] ={4, 3,2, 1, 18, -1, 89, -200};
// Array sorting
quick_sort<int>(a,0, n);
PrintArray<int>(a, n);
return 0;
}
It gives sorted array i.e -200, -1, 1, 2, 3, 4, 18, 89 most of the times. However, re-running the code may gives garbage values at some indices (for ex: -968225408, -200, -1, 1, 2, 3, 4, 18). To check, I replaced all the functions in the code above with the functions from blocks in the post https://www.geeksforgeeks.org/quick-sort/ . Nonetheless, the problem persists.
What could be the problem with the code and what is the solution to the problem.
#FrançoisAndrieux comments were very useful in finding out the problem.
As he pointed out that j is taking 8 as value which is out of bounds.
To solve the problem
step 1: quick_sort<int>(a,0, n-1); in the int main().
steps 2: knock off the custom swap function

Debugging Problem - I'm getting random outputs from a C++ program

It is a very simple code that should solve the Cut Rod Optimization Problem. Most of the time it outputs the correct output but sometimes it gives random answers. I don't know what might be causing this.
Code:
#include <iostream>
#include <limits>
int cutRod(int p[], int n);
int max(int a, int b);
int main()
{
int n = 10;
int p[n] = {1, 5, 8, 9, 10, 17, 17, 20, 24, 30};
int numOfCuts = cutRod(p, n);
std::cout << "Cuts: " << numOfCuts << std::endl;
return 0;
}
int cutRod(int p[], int n)
{
if (n == 0)
{
return 0;
}
int q = INT32_MIN;
for (int i = 0; i <= n; ++i)
{
q = max(q, p[i] + cutRod(p, n-i-1));
}
return q;
}
int max(int a, int b){
if (a >= b)
{
return a;
}
else if (b > a)
{
return b;
}
}
How to regenerate error:
Just run the program a couple of times. Most of the times, it gives 30 as answer. Which is correct. But other times, it will give a random big number as an output.
for (int i = 0; i <= n; ++i)
{
q = max(q, p[i] + cutRod(p, n-i-1));
}
here you are calling p[n] which is out of index but in c++ array it still lets you access that memory block having a garbage value, so you are basically adding a garbage value with returned value of function.
in array you will have valid value upto only 0 to n - 1 for p,
I guess this is the thing that is causing the problem

Im currently learning about algorithms in one of my CS classes. I am trying to write a code for QuickSort

Like the title says, I am trying to write a code for QuickSort, but I am trying to do this following a psuedocode given to us in the lecture. This isn't an assignment that's due it's just me trying to figure it out on my own. I've found a sample of QuickSort online, but it looks different than what our psuedocode says. The QuickSort code i found online uses pointers, i don't think pointers are mentioned in the given psuedocode. In other words, could someone check if im on the right path and maybe point out where I messed up. Thank you!
My code
#include <iostream>
using namespace std;
int Partition(int arr[], int p, int r)
{
int x = arr[r];
int i = p - 1;
for (int j = p; j < r - 1; j++)
{
if (arr[j] <= x)
{
i = i + 1;
swap(arr[i], arr[j]);
}
swap(arr[i + 1], arr[r]);
}
return i + 1;
}
void Quicksort(int arr[], int p, int r)
{
if (p < r)
{
int k = Partition(arr, p, r);
Quicksort(arr, p, k - 1);
Quicksort(arr, k + 1, r);
}
}
void print(int arr[], int n)
{
int i;
for (i = 0; i < n; i++)
{
cout << arr[i] << " ";
}
}
int main()
{
int arr[] = { 5, 3, 4, 9, 10 };
int n = sizeof(arr) / sizeof(arr[0]);
Quicksort(arr, 0, n);
print(arr, n);
//I get an error here "Stack around the variable 'arr' was corrupted"
}
This is the psuedocode for my QuickSort function
Picture number two is the given psuedocode for my Partition function
In Partition(), if i is never incremented, then a swap(arr[p-1], ...) is done, probably the cause of the stack error. Normally, quick sort parameters are first and last index, as opposed to first and end (= last+1) index, in this case, Quicksort(arr, 0, n-1). The inner loop is looking for values < pivot (not <= pivot). The final swap needs to be done after the for loop. Fixes noted in comments.
#include <iostream>
using namespace std;
int Partition(int arr[], int p, int r)
{
int x = arr[r];
int i = p; // fix
for (int j = p; j < r; j++) // fix
{
if (arr[j] < x) // fix
{
swap(arr[i], arr[j]);
i = i + 1; // fix
}
}
swap(arr[i], arr[r]); // fix
return i; // fix
}
void Quicksort(int arr[], int p, int r)
{
if (p < r)
{
int k = Partition(arr, p, r);
Quicksort(arr, p, k - 1);
Quicksort(arr, k + 1, r);
}
}
void print(int arr[], int n)
{
int i;
for (i = 0; i < n; i++)
{
cout << arr[i] << " ";
}
}
int main()
{
int arr[] = { 5, 3, 4, 9, 10 };
int n = sizeof(arr) / sizeof(arr[0]);
Quicksort(arr, 0, n-1); // fix
print(arr, n);
return 0; // fix
}

I have written a quick sort code and logic seem pretty correct but there is no output on the console

I have written a quick sort code and logic seem pretty correct but there is no output on the console.
when only index function runs the output is correct and also the output loop is correct but when quicSort function is added then there is no output.
#include <iostream>
using namespace std;
int index(int* a, int s, int e) {
int i, j, start, piv, temp;
start = s;
piv = a[e];
for (i = start; i <= e; i++) {
if (a[i] <= piv) {
temp = a[i];
a[i] = a[start];
a[start] = temp;
start++;
}
}
return start;
}
void quickSort(int* a, int s, int e) {
int pivot;
if (s < e) {
pivot = index(a, s, e);
quickSort(a, s, pivot - 1);
quickSort(a, pivot + 1, e);
}
}
int main() {
int A[] = {2, 5, 8, 3, 6, 9, 1, 4};
quickSort(A, 0, 7);
for (int i = 0; i < 8; i++) {
cout << A[i];
}
return 0;
}
the output should be sorted array
Code needs two fixes. Changes noted in comments:
#include <iostream>
using namespace std;
int index(int* a, int s, int e) {
int i, start, piv; // j, temp not used
start = s;
piv = a[e];
for (i = start; i <= e; i++) {
if (a[i] < piv) { // fix (not <=)
swap(a[i], a[start]); // simplify
start++;
}
}
swap(a[start], a[e]); // fix (swap pivot into place)
return start;
}
void quickSort(int* a, int s, int e) {
int pivot;
if (s < e) {
pivot = index(a, s, e);
quickSort(a, s, pivot - 1);
quickSort(a, pivot + 1, e);
}
}
int main() {
int A[] = {2, 5, 8, 3, 6, 9, 1, 4};
quickSort(A, 0, 7);
for (int i = 0; i < 8; i++) {
cout << A[i] << " "; // put space beteen numbers
}
cout << endl;
return 0;
}
I think you get confused by bubblesort when creating your quicksort program.
The quicksort ideia is to break the vector in smaller vectors one with the numbers bigger than the pivot e another with the numbers smaller than the pivot.
You should round up your code in C++ data structures like vectors.
One example is, with c++11:
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <numeric>
#include <vector>
using namespace std;
vector<int> quicksort(vector<int> data) {
if (data.size() == 1) return data;
vector<int> small_numbers;
vector<int> big_numbers;
vector<int> ret;
float pivot = accumulate(data.begin(), data.end(), 0.0) / data.size();
for (int value : data) {
if (value < pivot) {
small_numbers.push_back(value);
} else {
big_numbers.push_back(value);
}
}
if (small_numbers.empty()) return big_numbers;
small_numbers = quicksort(small_numbers);
big_numbers = quicksort(big_numbers);
ret.insert(ret.end(), small_numbers.begin(), small_numbers.end());
ret.insert(ret.end(), big_numbers.begin(), big_numbers.end());
return ret;
}
int main() {
vector<int> A({2, 5, 8, 3, 6, 9, 1, 4});
A = quicksort(A);
for (int value : A) cout << value << endl;
return 0;
}
This example break the the vector into two vectors, the pivot is the mean value of the values of vector. It calls the function recursively until it calls a vector with the size of 1 element.
Hope it push you to a less complicated way of see quicksort.

All Strings of {A,C,T,G}

I'm currently working on a problem of solving the combination of the different length of {A,C,T,G}, from 1 letter to 6 letters.
For example:
------#=1------
1:A
2:C
3:G
4:T
------#=2------
1:AA
2:AC
3:AG
4:AT
5:CA
6:CC
7:CG
8:CT
9:GA
10:GC
11:GG
12:GT
13:TA
14:TC
15:TG
16:TT
------#=3------
1:AAA
2:AAC
3:AAG
4:AAT
5:ACA
.
.
.
Now I can only solve the combinations from 1 to 4 letters, and I have no idea how to solve the combination of {A,C,T,G} of 5 letters and 6 letters, which the length of the combination(5 and 6) is greater than the length of all the strings(4)....
Here is my code:
#include <iostream>
#include <cstdlib>
using namespace std;
void combinationUtil(char arr[], char data[], int start, int end, int index, int r);
void printCombination(char arr[], int n, int r)
{
char data[100];
combinationUtil(arr, data, 0, n-1, 0, r);
}
void combinationUtil(char arr[], char data[], int start, int end, int index, int r)
{
if (index == r) {
for (int j=0; j<r; j++)
cout << data[j];
cout << endl;
return;
}
for (int i=start; i<=end && end-i+1 >= r-index; i++)
{
data[index] = arr[i];
combinationUtil(arr, data, i+1, end, index+1, r);
}
}
int main()
{
char arr[] = {'A','T','C','G'};
int n = sizeof(arr)/sizeof(arr[0]);
printCombination(arr, n, 1);
printCombination(arr, n, 2);
printCombination(arr, n, 3);
printCombination(arr, n, 4);
printCombination(arr, n, 5);
system("pause");
}
At least assuming I understand what you want, this is pretty easy to solve by treating it as counting from 0 to some limit in base 4, with the "digits" displayed as "A", "C", "G" and "T".
#include <string>
#include <iostream>
std::string cvt(unsigned input, unsigned len) {
std::string ret;
static const char letters[] = "ACGT";
for (int i=0; i<len; i++) {
ret.push_back(letters[input%4]);
input /= 4;
}
return ret;
}
int main() {
unsigned limit = 1;
unsigned length = 4;
for (int i=0; i<4; i++)
limit *= 4;
for (int i=0; i<limit; i++)
std::cout << cvt(i, length) << "\n";
}
Your code assumes each letter can only be used once. That's why you are getting no results for both sequences of length 5 and 6. Rewrite your function as the following and do not pass as start or end value to it:
void combinationUtil(char arr[], char data[], int index, int r)
{
if (index == r)
{
for (int j=0; j<r; ++j)
cout << data[j];
cout << endl;
return;
}
for (int i=0; i<r; ++i)
{
data[index] = arr[i];
combinationUtil(arr, data, index+1, r);
}
}