What's wrong with my merge sort implementation (C++)? - c++

My merger sort implementation is working only partially and even raising seg faults on occasion.
Input: 5 4 3 2 1
Output: 0 1 2 3 4
Input: 7 6 5 4 3 2 1
Output: 0 1 2 3 4 5 6
Input: 4 3 2 1
Output: [some garbage value] 1 2 3
Input: 1 2 3 4 5 67 7 8
Output: [some garbage value] 1 2 3 4 5 7 8
It seems that the odd numbered inputs aren't causing seg faults but the even numbered ones are. Still, in both cases the largest value is not appearing in the output. Any help would be appreciated.
void merge(vector<int>& a, int i, int j)
{
int b[a.size()];
int start = i;
int mid = (i+j)/2;
int k = mid+1;
int l = i;
while(i<=mid && k<=j)
{
if(a[i] >= a[k])
b[l++] = a[k++];
else
b[l++] = a[i++];
}
if(i>mid)
{
while(k<=j)
b[l++] = a[k++];
}
else
{
while(i<=mid)
b[l++] = a[i++];
}
for(l=start; l<=j; l++)
a[l] = b[l];
}
void merge_sort(vector<int>& a, int l, int u)
{
int m;
if(l < u)
{
m = (l+u)/2;
merge_sort(a,l,m);
merge_sort(a,m+1,u);
merge(a,l,u);
}
}
//relevant portion in main
cin >> n;
cout << "n: " << n << endl;
a.resize(n);
for(int j=0; j<n; j++)
cin >> a[j];
cout << endl;
merge_sort(a, 0, a.size());

You shouldn't go up to j ("...<= j...") when j could be a.size(). Try a.size() - 1.

Related

different outputs in different compilers

I am writing a program for a practice coding question
this is the question
Rohan has an array of integers π‘Ž1,π‘Ž2,... π‘Žπ‘› of size 𝑛.
Each integer at index 𝑖 denotes the money placed at that index 𝑖. He can do the following operation exactly once:
Pick a subsegment of the array and cyclically rotate it in the clockwise direction by any amount. i.e. pick integer 𝑙 and π‘Ÿ such that 1β‰€π‘™β‰€π‘Ÿβ‰€π‘›, and rotate the array π‘Žπ‘™,π‘Žπ‘™+1,β€¦π‘Žπ‘Ÿ in the clockwise direction by any amount. Rohan wants the maximum amount of money by performing this particular operation exactly once. After performing the operation, Rohan will collect π‘Žπ‘›βˆ’π‘Ž1 amount of money.
Determine the maximum value of π‘Žπ‘›βˆ’π‘Ž1 that he can obtain.
Input
The first line contains a single integer 𝑑, the number of test cases. Description of the test cases is as follows:
The first line of each test case contains a single integer 𝑛.
The next line contains an array of 𝑛 integers separate by space.
Constraints
1<=𝑑<=100
1<=𝑛<=3000
1<=π‘Žπ‘–<=1000
The sum of 𝑛 over all test cases doesn’t exceed 3000
Output
For each test case, output a single integer indicating the maximum value of π‘Žπ‘›βˆ’π‘Ž1 that Rohan can obtain.
Example
Input:
2
5
1 9 8 4 6
4
3 2 10 8
Output:
8
7
And this is my program
#include <iostream>
#include <climits>
using namespace std;
void cycle(int start, int end, int* arr, int size);
void printArr(int* arr, int size);
int maximum = INT_MIN;
void reInitialize(int* arr, int* arr2, int size);
int main() {
int t, n;
//cout << "enter the number of test cases" << endl;
cin >> t;
while (t != 0) {
cin >> n;
//int data;
int* arr = new int[n];
int* arr2 = new int[n];
for (int i = 0; i < n; i++) {
cin >> arr[i];
}
for (int i = 0; i < n; i++) {
arr2[i] = arr[i];
}
if (arr[n - 1] - arr[0] > maximum) { maximum = arr[n - 1] - arr[0]; }
for (int i = n; i > 1; i--) {
for (int j = 0; j < ((n - i) + 1); j++) {
for (int z = 0; z < i - 1; z++) {
cycle(j, j + (i - 1), arr, i);
if (arr[n - 1] - arr[0] > maximum) { maximum = arr[n - 1] - arr[0]; }
//printArr(arr, n);
}
reInitialize(arr, arr2, n);
}
}
cout << maximum << endl;
delete [] arr;
delete [] arr2;
}
}
void cycle(int start, int end,int *arr, int size) {
if (size <= 0) return ;
int* tempArr = new int[size+1];
int j = 1;
for (int i = start; i <= end-1; i++) {
tempArr[j] = arr[i];
j++;
}
tempArr[0] = arr[end];
j = 0;
for (int i = start; i <= end; i++) {
arr[i] = tempArr[j];
j++;
}
delete[] tempArr;
}
void reInitialize(int* arr, int* arr2, int size){
for (int i = 0; i < size; i++) {
arr[i] = arr2[i];
}
}
while the program works as expected in my gcc compiler when I tried to upload it to the website, this is what the output that i am getting.
Initially I thought this migth be some memory deallocation issue, and I fixed it. but this is the current output that I am getting in that compiler
Input
10
2
6 5
5
2 10 10 9 5
7
3 9 2 1 9 10 9
10
6 10 2 5 10 3 1 9 10 10
10
10 7 5 1 10 10 9 7 3 2
2
9 3
5
7 4 1 9 6
2
7 8
8
9 5 4 9 3 2 3 1
7
5 2 10 7 6 2 1
Expected Output
1\n
8\n
8\n
9\n
4\n
6\n
5\n
1\n
6\n
5
Actual Output
Output too long
Status
Time Limit Exceeded
I would appreciate any help

Unintended behavior in c++ when passing in an incremented integer to a recursive function

The code itself accepts N and M from standard input and prints M-length combinations from 1 to N.
#include <iostream>
void print(int *arr, int size)
{
for (int i=0; i<size; i++)
std::cout << arr[i] << " ";
std::cout << "\n";
}
bool is_found(int *arr, int size, int num)
{
for (int i=0; i<size; i++)
{
if (num == arr[i])
return true;
}
return false;
}
void recurse(int *arr, int n, int m, int cur)
{
if (cur >= m)
print(arr, m);
else
{
for (int i=1; i<=n; i++)
{
if (is_found(arr, cur + 1, i))
continue;
arr[cur] = i;
recurse(arr, n, m, cur + 1);
}
}
}
int main()
{
int *arr;
int n;
int m;
int temp;
std::cin >> n >> m;
arr = new int[n];
for (int i=0; i<n; i++)
arr[i] = 0;
recurse(arr, n, m, 0);
}
Eg.
input: 4 4
output:
1 2 3 4
1 2 4 3
1 3 2 4
1 3 4 2
1 4 2 3
1 4 3 2
2 1 4 3
2 3 1 4
2 3 4 1
2 4 1 3
2 4 3 1
3 1 2 4
3 1 4 2
3 2 1 4
3 2 4 1
3 4 1 2
3 4 2 1
4 1 3 2
4 2 1 3
4 2 3 1
4 3 1 2
4 3 2 1
The code above works as intended.
However, in the recurse function, changing this part of the code results in unexpected behavior.
arr[cur] = i;
recurse(arr, n, m, cur + 1);
void recurse(int *arr, int n, int m, int cur)
{
if (cur >= m)
print(arr, m);
else
{
for (int i=1; i<=n; i++)
{
if (is_found(arr, cur + 1, i))
continue;
// option 1 (original, works)
arr[cur] = i;
recurse(arr, n, m, cur + 1);
// option 2 (doesn't work)
arr[cur++] = i;
recurse(arr, n, m, cur);
// option 3 (doesn't work)
arr[cur] = i;
cur = cur + 1;
recurse(arr, n, m, cur);
This is the output when using option 2 and option 3
input: 4 4
output:
1 2 3 4
1 2 4 3
1 3 2 4
1 3 4 2
My question is, aren't the three options written above equivalent? I don't understand why option 1 works as intended and options 2 and 3 don't. Why does passing in the value cur + 1 to the recursive function work, but changing the value of cur before passing, doesn't?
My best guess is that it has something to do with recursion and using the same array for the recursive call, or perhaps the problem is from a completely different part of the code. But I really have no idea why this is happening.
Any help is greatly appreciated! Thank you in advance!
This:
// option 1 (original, works)
arr[cur] = i;
recurse(arr, n, m, cur + 1);
Does not modify cur. The loop continues with the next loop and the value of cur is the same in the next iteration. On the other hand, this
// option 2 (doesn't work)
arr[cur++] = i;
recurse(arr, n, m, cur);
// option 3 (doesn't work)
arr[cur] = i;
cur = cur + 1;
Both modify cur and the value wont be the same in the next iteration. I suppose the confusion is caused by recursion, but consider the same without recursion:
int cur = 0;
for (int i=1; i<=n; i++)
{
arr[cur] = i;
}
vs
int cur = 0;
for (int i=1; i<=n; i++)
{
cur = cur + 1;
arr[cur] = i;
}
Would you expect this two to be identical?

How Vector allocation using push_back() and pop_back operation gives garbage values

I am solving a problem in which I have to find those element from the array whose total gives maximum sum. But there is a condition that no two adjacent element can be the part of that max subarray. Here is my code using simple brute Force solution-
#include <bits/stdc++.h>
using namespace std;
int main()
{
int t;
cin >> t;
while (t != 0)
{
int n, i, s, k = 0, m = -1001;
vector< int > a;
cin >> n;
a.resize(n, 0);
vector< int > b;
for (i = 0; i < n; i++)
{
cin >> a[i];
m = max(m, a[i]);
if (a[i] < 0)
{
a[i] = 0;
++k;
}
}
if (k == n)
cout << m;
else
{
k = 0;
s = a[0];
b.push_back(a[0]);
for (i = 1; i < n; i++)
{
if (i != k + 1)
{
if (a[i])
{
s += a[i];
b.push_back(a[i]);
k = i;
}
}
else
{
if (s - a[i - 1] + a[i] > s)
{
b.pop_back();
s -= a[i - 1];
s += a[i];
b.push_back(a[i]);
++k;
}
}
}
}
cout << endl;
for (i = n; i >= 0; i--)
{
if (b[i])
cout << b[i] << " ";
}
cout << endl;
--t;
}
return 0;
}
Here is input to code-
First line represent no. of test cases,
Second line represent size of array
And the next line shows array elements.m
5
5
-1 7 8 -5 4
4
3 2 1 -1
4
11 12 -2 -1
4
4 5 4 3
4
5 10 4 -1
Output-
4 8
32 32607 -787829912 1 3
32 32607 -787829912 12
3 5
10
Expected output-
4 8
1 3
12
3 5
10
So, there are 5 test cases. For the first test case and last two test case output is correct. But for second and third test case it is giving garbage value. What is the problem, that for some test cases it is giving garbage value, and for other not.
for (i = n; i >= 0; i--)
{
if (b[i])
cout << b[i] << " ";
}
This prints out n+1 values in b. But even in the best case, b only has n values (for n=1). And for n>1, b.size() is less than n, so you are reading garbage from outside the vector's storage (this is undefined behavior). Just use the correct bound:
for (i = b.size() - 1; i >= 0; ++i)
I think I found your (first) problem:
if(k==n)
cout<<m;
When all numbers are negative this outputs the largest of them.
But the empty array has a sum of 0 and is larger than a negative number and has no 2 adjacent members in it. So clearly the right answer should be 0, not m.

Executing print in standard output causing random assigning of value in array

I'm sorry if this is a silly question.
I have written the following piece of code for coin change problem.
#include <iostream>
using namespace std;
int coinChange(int coins[], int n, int amount)
{
int combinations[amount + 1];
combinations[0] = 1;
int start;
for(int i = 0; i < n; i++)
{
start = coins[i];
int coin = coins[i];
for(int j = start; j < amount + 1; j++)
{
if(j >= coin)
{
combinations[j] += combinations[j - coin];
}
}
for(int j = 0; j < amount + 1; j++)
cout << combinations[j] << " ";
cout << endl;
}
return combinations[amount];
}
int main(int argc, char const *argv[])
{
int coins[] = {1, 2, 5};
int n = sizeof(coins)/sizeof(coins[0]);
int amount = 12;
// cout << "Total combinations: ";
cout << coinChange(coins, n, amount) << endl;
return 0;
}
The code works fine and provides me the correct output as shown below.
1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 2 2 3 3 4 4 5 5 6 6 7
1 1 2 2 3 4 5 6 7 8 10 11 13
13
However, If I uncomment the line cout << "Total combinations: "; just above the function calling in the main function, the program gives me bizzare outputs.
Total combinations: 1 32768 32768 32768 44137 44137 44137 44137 196418491 196418492 -790461916 -790429149 619621115
1 32768 32769 65536 76906 109673 121043 153810 196539534 196572302 -593922382 -593856847 25698733
1 32768 32769 65536 76906 109674 153811 186579 196605070 196649208 -593812708 -593703036 25885312
25885312
Is executing cout before function calling causing this random outputs? Or is this a problem for my version of compiler?
What about initialize (to zero?) combinations ?
Something like
int combinations[amount + 1] {};
Otherwise the initial values of combinations[i] are undefined indeterminate, so are is undefined the final values behavior of the program (correction from Shafik Yaghmour; thanks!)
Do this in your coinChange function.
int combinations[amount + 1]{};
combinations[0] = 1;
int start;
for(int i = 0; i < n; i++)
{
start = coins[i];
int coin = coins[i];
for(int j = start; j < amount + 1; j++)
{
if(j >= coin)
{
combinations[j] += combinations[j - coin];
}
}
for(int j = 0; j < amount + 1; j++)
cout << combinations[j] << " ";
cout << endl;
}
Now uncomment the line and run. The basic problem is when you create the combinations array, you have to initialize the elements to 0. If you don't, they may be all 0 by a lucky coincidence, but you can't guarantee that.
EDIT : Using empty initializer list to initilize array with zeros as max66 suggested.

Can't get my sort function to use print method to show iterations

I want displayArray on line 69 to work every time it iterates to show the changes of the insertion sort. I haven't been able to get it to work and have been spinning my wheels for a bit. Please help/explain. Thank you in advance.
This is what my output should look like:
Expected Output:
Enter up to 20 nonnegative whole numbers.
Mark the end of the list with a negative number.
3 7 4 9 5 2 6 1 -1
3 7 4 9 5 2 6 1
3 4 7 9 5 2 6 1
3 4 7 9 5 2 6 1
3 4 5 7 9 2 6 1
2 3 4 5 7 9 6 1
2 3 4 5 6 7 9 1
1 2 3 4 5 6 7 9
In sorted order the numbers are:
1 2 3 4 5 6 7 9
Code:
#include <iostream>
using namespace std;
const int MAX_SIZE = 20;
// Fills the array a[] with data from the user for a[0] through a[numberUsed -1].
// Since the user will not necessarily use up all the allocated entries in the array,
// the function will set the actual number of entries used in the "numberUsed"
// reference variable.
void fillArray(int a[], int arraySize, int& numberUsed);
// Sorts the array a[] such that a[0] <= a[1] <= ... <= a[numberUsed - 1].
void insert_sort(int a[], int numberUsed);
// Interchanges the values of v1 and v2.
void swapValues(int& v1, int& v2);
// Displays the contents of the array
void displayArray(const int a[], int numberUsed);
int main( )
{
cout << "This program sorts numbers from lowest to highest.\n";
int sampleArray[MAX_SIZE] = {0};
int numberUsed = 0;
fillArray(sampleArray, MAX_SIZE, numberUsed);
insert_sort(sampleArray, numberUsed);
cout << "In sorted order the numbers are:\n";
displayArray(sampleArray, numberUsed);
return 0;
}
void fillArray(int a[], int arraySize, int& numberUsed)
{
cout << "Enter up to " << arraySize << " nonnegative whole numbers.\n"
<< "Mark the end of the list with a negative number.\n";
int next = 0;
int index = 0;
cin >> next;
while ((next >= 0) && (index < arraySize))
{
a[index] = next;
index++;
cin >> next;
}
numberUsed = index;
}
void insertion_sort (int a[], int numberUsed){
int j, temp;
for (int i = 0; i < numberUsed; i++){
j = i;
while (j > 0 && a[j] < a[j-1]){
temp = a[j];
a[j] = a[j-1];
a[j-1] = temp;
j--;
}
displayArray(a,numberUsed);
}
}
void swapValues(int& v1, int& v2)
{
int temp;
temp = v1;
v1 = v2;
v2 = temp;
}
void displayArray(const int a[], int numberUsed)
{
for (int index = 0; index < numberUsed; index++)
{
cout << a[index] << " ";
}
cout << endl;
}