C++ program wont compile with expected expression and function not allowed here - c++

#include <iostream>
using namespace std;
const int lab8 = 10;
int labArray[lab8];
void promptUser(int [], int);
void sortArray(int [], int);
void showArray(const int[], int);
int searchArray(const int [], int, int value);
int x = 0;
int results = 0;
int main()
{
promptUser(labArray, lab8);
sortArray(labArray, lab8);
showArray(labArray, lab8);
cout << "Choose an integer you want to search from the array: " << endl;
cin >> x;
results = searchArray(labArray, lab8, x);
if (results == -1) {
cout << "That number does not exist in the array. \n";
else
{
cout << "The integer you searched for was for at element " << results;
cout << " in the array. \n";
}
}
void promptUser(int numbers[], int size)
{
int index;
for (index = 0; index <= size - 1;index++ )
{
cout << "Please enter ten numbers to fill the array " << endl
<< (index + 1) << ": ";
cin >> numbers[index];
}
}
void sortArray(int array[], int size)
{
bool swap;
int temp;
do
{
swap = false;
for (int count = 0; count < (size -1); count++)
{
if (array[count] > array[count + 1])
{
temp = array[count];
array[count] = array[count + 1];
array[count + 1] = temp;
swap = true;
}
}
} while (swap);
}
void showArray(const int array[], int size)
{
for (int count = 0; count < size; count++)
{
cout << "The array you entered when sorted was: ";
cout << array[count] << " ";
cout << endl;
}
}
int searchArray(const int array[], int size, int value)
{
int first = 0,
last = size - 1,
middle,
position = - 1;
bool found = false;
while (!found && first <= last)
{
middle = (first + last) / 2;
if (array[middle] == value)
{
found = true;
position = middle;
}
else if (array[middle] > value)
last = middle - 1;
else
first = middle + 1;
}
return position;
}
I am new to c++ and just working on an assignment for my class. I thought the program I wrote would have worked but for the life of me I can not figure out why it will not compile. I am sure I am missing something or not understanding how it should work completely. The errors I keep receiving are expected expression on line 26 by the 'else' statement and when I put the 'if' and 'else' statements in I started receiving function not allowed here errors. Any help would be greatly appreciated.

In the if statement, you open the bracket { but you never close it. Not sure if this is the problem but it should raise some issues.
if (results == -1) {
cout << "That number does not exist in the array. \n";
**}**
else
{
cout << "The integer you searched for was for at element " << results;
cout << " in the array. \n";
}
This is how it should look. Try it

Related

Why is the Vector array printing the memory addresses instead of the array values and why do I get an access violation in my sorting functions? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
I'm developing a program that reads text files and stores the words in an array that can be sorted and then searched through. I've already tried using a dynamically allocated array to place the words into from the text files, but all I get is string cannot be read error from my getline (this doesn't happen when I use vectors). When I try to print out the vector array to see what is being passed through to my sorting functions, it prints out the memory addresses of the array and not the values stored in the array.
I also get a read access violation in my sorting functions at certain points in the function after I've pass the vector arrays to them and I don't understand why. I do show in the code where the problem is accruing. Please note that I'm very new to coding and this program is far from complete. I'm including all of the code I have done so far because if I just show the problem areas I don't think it will be understandable why I'm having these errors. Any help is appreciated thank you.
#include "flore0900header.h"
int main()
{
string name;
int num = 0, num2 = 0, count = 0;
vector<string> word; //to pass vector array to another function
cout << "Hello. Enter your name: ";
cin >> name;
cout << endl;
cout << "Welcome " << name << " This program lets you test 5 different sorting algorithms using texts files" << endl;
cout << endl;
cout << "Which text file would you like to search?" << endl;
cout << "=========================================" << endl;
cout << "1. The Blue Hotel" << endl;
cout << "2. 20,000 Leagues Under the Sea" << endl;
cout << "3. A Tale of Two Cities" << endl;
cin >> num;
count = text_select(num);
catch_array(&word); //passing vector array by reference. '&' is there because it won't work otherwise
cout << endl;
cout << "Which sorting algorithems would you like to use?" << endl;
cout << "========================================" << endl;
cout << "1. Selection" << endl;
cout << "2. Bubble" << endl;
cout << "3. Insertion" << endl;
cout << "4. Merge" << endl;
cout << "5. Quick" << endl;
cin >> num; cin >> num2;
sort_select(num, &word, count);//'&' is there because it won't work otherwise
sort_select(num2, &word, count);//'&' is there because it won't work otherwise
cout << endl;
cout << "Ok! Running algorithms..........." << endl;
}
the header file
#ifndef FLORE0900HEADER_H
#define FLORE0900HEADER_H
#include <iomanip>
#include <ctime>
#include <cstdlib>
#include <istream>
#include <fstream>
#include <string>
#include <iostream>
#include <sstream>
#include <vector>
#include <ostream>
/* some of the includes are not needed, I haven't removed the un-needed ones yet*/
using std::cout;
using std::cin;
using std::endl;
using std::string;
using std::vector;
void selection_sort(vector<string> a[], int size);
void bubble_sort(vector<string> a[], int size);
void insertion_sort(vector<string> a[], int size);
void merge_sort(vector<string> a[], int from, int to);
void quick_sort(vector<string> a[], int from, int to);
int text_select(int num);
void sort_select(int num, vector<string> a[], int size);
vector<string> catch_array(vector<string> a[]);
void merge(vector<string> a[], int from, int mid, int to);
int min_position(vector<string> a[], int from, int to);
int partition(vector<string> a[], int from, int to);
void swap(int& x, int& y);
void print(vector<string> a[], int size);
#endif
text_select function file
#include "flore0900header.h"
//#include <vector>
int text_select(int num)
{
int count = 0;
vector<string> words(100000);
//vector<string>* word2 = new vector<string>[count];
std::ifstream infile;
if (num == 1)
{
infile.open("blue_hotel.txt");
if (infile.is_open())
{
cout << "file is open" << endl;
getline(infile, words[count]);//string read error when using not using vector
while (!infile.eof())
{
infile >> words[count];
count++;
infile.ignore();
getline(infile, words[count]);
}
}
else
{
cout << "file didn't open" << endl;
exit(1);
}
}
else if (num == 2)
{
infile.open("2under.txt");
if (infile.is_open())
{
cout << "file is open" << endl;
getline(infile, words[count]);
while (!infile.eof())
{
infile >> words[count];
count++;
infile.ignore();
getline(infile, words[count]);
}
}
else
{
cout << "file didn't open" << endl;
exit(1);
}
}
else if (num == 3)
{
infile.open("2city10.txt");
if (infile.is_open())
{
cout << "file is open" << endl;
getline(infile, words[count]);
while (!infile.eof())
{
infile >> words[count];
count++;
infile.ignore();
getline(infile, words[count]);
}
}
else
{
cout << "file didn't open" << endl;
exit(1);
}
}
else
cout << "not a valid choice try again" << endl;
infile.close();
catch_array(&words);//if I don't use '&' the vector won't pass through
return count;
}
vector<string> catch_array(vector<string> a[])
{
return *a;//if I don't put '*' before the 'a' I get an error
}
sort_select file
#include "flore0900header.h"
void sort_select(int num, vector<string> a[], int size)
{
int from = 0;
if (num == 1)
{
selection_sort(a, size);
}
else if (num == 2)
{
bubble_sort(a, size);
}
else if (num == 3)
{
insertion_sort(a, size);
}
else if (num == 4)
{
merge_sort(a, from, size);
}
else if (num == 5)
{
quick_sort(a, from, size);
}
else
cout << "not a valid pick try again" << endl;
}
selection_sort file
#include "flore0900header.h"
void selection_sort(vector<string> a[], int size)
{
int next;
for (next = 0; next < size - 1; next++)
{
print(a, size);//to see what is being passed to the function
int min_pos = min_position(a, next, size - 1);
swap(a[next], a[min_pos]);
}
}
int min_position(vector<string> a[], int from, int to)
{
int min_pos = from;
for (int i = from + 1; i <= to; i++)
{
if (a[i] < a[min_pos])//read access violation happens here
{
min_pos = i;
}
}
return min_pos;
}
void print(vector<string> a[], int size)
{
for (int i = 0; i < size; i++)
{
cout << &a[i] << " ";//is printing memory locations instead of values
}
cout << endl;
}
bubble_sort file
#include "flore0900header.h"
void bubble_sort(vector<string> a[], int size)
{
for (int i = 0; i < size - 1; i++) //loop for recording no# of iteration needed to complete the sorting
{
int flagForSwap = 0; //creates a flag variable that accounts for wheather the swap function is called at all
//loop for counting comparisons
for (int j = 0; j < size - 1 - i; j++)
{
if (a[j] > a[j + 1]) //(read access violation happens here) compare adjacent array elements
{
swap(a[j], a[j + 1]); //completes the swap
flagForSwap = 1; // flag to 1 if swap is used
}
}
if (flagForSwap == 0) //breaks the iteration loop if inputed array is already sorted and no swap is needed
{
break;
}
}
}
void swap(int& x, int& y)
{
int temp = x; //creates a temp variable to store the value of the current element
x = y; // change the value of the current element to next element
y = temp; //assigns the value of temp to next element
}
insertion_sort file
#include "flore0900header.h"
void insertion_sort(vector<string> a[], int size)
{
for (int i = 1; i < size; i++)
{
vector<string> next = a[i];//read access violation happens here
int j = i;
while (j > 0 && a[j - 1] > next)
{
a[j] = a[j - 1];
j--;
}
a[j] = next;
}
}
merge_sort file
#include "flore0900header.h"
void merge_sort(vector<string> a[], int from, int to)
{
if (from == to)
{
return;
}
int mid = (from + to) / 2;
merge_sort(a, from, mid);
merge_sort(a, mid + 1, to);
merge(a, from, mid, to);
}
void merge(vector<string> a[], int from, int mid, int to)
{
int n = to - from + 1;
vector<string>* b = new vector<string>[n];
int i1 = from;
int i2 = mid + 1;
int j = 0;
while (i1 <= mid && i2 <= to)
{
if (a[i1] < a[i2])//read access violation happens here
{
b[j] = a[i1];
i1++;
}
else
{
b[j] = a[i2];
i2++;
}
j++;
}
while (i1 <= mid)
{
b[j] = a[i1];
i1++;
j++;
}
while (i2 <= to)
{
b[j] = a[i2];
i2++;
j++;
}
for (j = 0; j < n; j++)
{
a[from + j] = b[j];
}
delete[] b;
}
quick_sort file
#include "flore0900header.h"
void quick_sort(vector<string> a[], int from, int to)
{
if (from >= to)
{
return;
}
int p = partition(a, from, to);
quick_sort(a, from, p);
quick_sort(a, p + 1, to);
}
int partition(vector<string> a[], int from, int to)
{
vector<string> pivot = a[from];
int i = from - 1;
int j = to + 1;
while (i < j)
{
i++;
while (a[i] < pivot)//read access violation happens here
{
i++;
}
j--;
while (a[j] > pivot)
{
j--;
}
if (i < j)
{
swap(a[i], a[j]);
}
}
return j;
}
There is no such thing as "a vector array".
You can have arrays of vectors, but you don't.
Yet, here, your function is written as if it does:
int partition(vector<string> a[], int from, int to)
// ^^
I imagine this was done because, before you added the [] here and the & there, your functions appeared not to do anything.
That was because you were passing the vector by value, so changes in the function were made to a copy, and thus not reflected in the calling scope.
Your changes allowed the code to compile, and possibly even "work" in some obscure cases, but only by chance; the [INDEX] syntax is shared between vectors and arrays. But you don't have an array, so pretending to the function that you do is wrong. Most of your accesses go out of bounds.
Also note that if you didn't have a bool operator<(const vector<string>&, const vector<string>&) defined somewhere, it wouldn't compile.
Anyway, the solution to use your one vector is simple:
Get rid of that []
Get rid of that &
Change what is now vector<string> into vector<string>&. That & means "take a reference".

bubblesort not passing data or doesnt work

I'm writing a program for an assignment in which the program stores grades in array, has a function that inputs the grades and stores them in an array and returns the number of grades, handles up to 20 grades, has a function that sorts the array of grades, and has a separate function that takes the sorted array and returns the median. I have the code written but it is not sorting the array. Not sure what I am doing wrong. Any help would be greatly appreciated.
#include <iostream>
using namespace std;
int main();
void bubbleSort(double[], int); //Function prototypes
void swap(double &, double &);
void findMedian(double[], int, int, int, int, int);
int main()
{
int numgrades; // the number of grades in the array
double grades[20]; // array of grades
int first = 0,
last,
middle;
double medianeven; // median if # of elements are even
double medianodd; // median if # of elements are odd
bool isEven(int); // determines if the #of elements is even
cout << "Please enter the number of grades. ";
cin >> numgrades;
for (int index = 0; index <= numgrades - 1; index++)
{
cout << "Enter test score "
<< (index + 1) << ":";
cin >> grades[index];
}
void bubbleSort(double grades[], int numgrades);
for (int index = 0; index <= numgrades - 1; index++)
{
cout << grades[index];
}
(((last) = (numgrades - 1)));
(((middle) = (first + last) / 2));
if (isEven(numgrades))
{
(medianeven = ((grades[middle] + grades[middle + 1]) / 2));
cout << "The median grade is +" << medianeven << "." << endl;
}
else
{
((medianodd = grades[middle]));
cout << "The median grade is -" << (medianodd) << "." << endl;
}
return 0;
}
void bubbleSort(double array[], int numgrades)
{
int minIndex;
double minValue;
for (int start = 0; start < (numgrades - 1); start++)
{
minIndex = start;
minValue = array[start];
for (int index = start + 1; index < numgrades; index++)
{
if (array[index] < minValue)
{
minValue = array[index],
minIndex = index;
}
}
swap(array[minIndex], array[start]);
}
}
void swap(double &a, double &b)
{
double temp = a;
a = b;
b = temp;
}
bool isEven(int number)
{
bool status;
if (number % 2 == 0)
status = true;
else
status = false;
return status;
}
In main
void bubbleSort(double grades[], int numgrades);
is a forward declaration of the bubbleSort function, not a call to it.
bubbleSort(grades, numgrades);
will call the function.

Having problems with binary search c++ [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 7 years ago.
Improve this question
Im having a problem with a binary search function. It only seems to work when the randomly generated search key is already in the middle position of the array. Ive tried a lot of things but cant seem to figure out why it's doing this.
#include<iostream>
#include<ctime>
using namespace std;
void printarray(int[], int);
void fillarray(int[], int);
void descendingSort(int[], int);
int binarySearch(int[], int, int);
int main()
{
srand((unsigned int)time(0));
bool quit = false;
while (quit == false)
{
int key = rand() % 100 + 1;
const int size = 16;
int mainarray[size] = {};
fillarray(mainarray, size);
printarray(mainarray, size);
descendingSort(mainarray, size);
cout << endl;
cout << "Ordered array after selection sort:" << endl;
printarray(mainarray, size);
cout << endl;
int result = binarySearch(mainarray, size, key);
cout << "Searching for key value " << key << endl;
if (result >= 0)
{
cout << "Key value " << key << " found at position " << result << endl;
}
else
{
cout << "Key value " << key << " not found!" << endl;
}
cout << "Continue (y/n)? :";
char x;
cin >> x;
cout << endl;
if (x == 'y')
quit = false;
if (x == 'n')
quit = true;
}
return 0;
}
void printarray(int array[], int size)
{
for (int i = 0; i < size; i++)
{
cout << array[i] << " ";
}
}
void fillarray(int random[], int size)
{
for (int j = 0; j <= size - 1; j++)
{
random[j] = rand() % 100 + 1;
}
}
void descendingSort(int array[], int size)
{
int max, next;
for (int i = 0; i < size - 1; i++)
{
max = i;
for (int j = i + 1; j < size; j++)
{
if (array[max] < array[j])
max = j;
}
if (max!= i)
{
next = array[i];
array[i] = array[max];
array[max] = next;
}
}
}
int binarySearch(int array[], int size, int key)
{
int low = 0, high = size - 1;
int mid;
while (low <= high)
{
mid = (low + high) / 2;
if (key == array[mid])
{
return mid;
}
else if (key < array[mid])
{
high = mid - 1;
}
else
{
low = mid + 1;
}
}
return -1;
}
Since you are sorting in descending order, your case is backwards.
See code below where I replaces > with <
if (key == array[mid])
{
return mid;
}
else if (key > array[mid])
{
high = mid - 1;
}
else
{
low = mid + 1;
}
By adding some code above the if it allowed me to visualize what was going wrong.
cout << "Searching in: ";
for (int i = low; i < high + 1; i++)
{
cout << array[i] << " ";
}
cout << endl;

Bubble Sort not working correctly

I've been working on this for awhile and I have tried multiple different algorithms for the bubble sort that I have found online but none of them are working properly for me and I'm pretty close to giving up, but this is due tomorrow night. I'd really appreciate if someone could point out where im going wrong. I dont really understand this algorithm with the bool so ill try to find what i was trying before and edit it in
#include <iostream>
using namespace std;
void GetInfo(int[], int&);
void BubbleSort(int[], int);
void BinarySearch(int[], int);
int main()
{
int size;
int array[500];
GetInfo(array, size);
BubbleSort(array, size);
BinarySearch(array, size);
return 0;
}
void GetInfo(int array[], int& size)
{
cout << "Enter the number of naturals: ";
cin >> size;
cout << "Enter the natural numbers to sort: ";
for (int i = 0; i < size; i++)
{
cin >> array[i];
}
}
void BubbleSort(int array[], int size)
{
int temp;
bool check = true;
int end = 0;
while(check)
{
end++;
check = false;
for(int i = 0; i < size - end; i++)
{
if (array[i] > array[i+1]) //I'm positive this part is correct
{
temp = array[i];
array[i] = array[i+1];
array[i+1] = temp;
check = true;
}
}
}
cout << endl << "Numbers sorted in ascending order: " << endl;
for (int i = 0; i < size; i++)
{
cout << array[i] << ' ';
}
}
void BinarySearch(int array[], int size) //this doesnt work properly atm but
{ //should be good when the sort works
int index;
int top = size - 1;
int bottom = 0;
int middle = (top) / 2;
bool found = false;
int target;
cout << endl << "Enter the number to search: ";
cin >> target;
while (found == false)
{
if (target > array[middle])
{
bottom = middle + 1 ;
middle = ((top - bottom)/2) + bottom;
}
else if (target < array[middle])
{
top = middle - 1;
middle = ((top - bottom)/2) + bottom;
}
else
{
found = true;
index = middle;
}
}
cout << "Number " << target << " is found in position " << index << endl;
}
You might meant to swap a[i] with a[i+1] while you actually swapped a[size+1]
These lines are wrong:
array[i] = array[size+1];
array[size+1] = temp;
You need:
array[i] = array[i+1];
array[i+1] = temp;

Merge sort code debugging

I am trying to write a code for merge sort. I am not getting the correct output. I am following this pseudocode link Following is my code. I pass my unsorted array into merge_sort function and call merge function recursively to sort and combine the sub arrays.I know there are more simpler and efficient ways to write code for merge sort but I want to try on my own otherwise I won't learn. Thanks in advance.
int* merge_sort(int* a,int size)
{
//cout<<size;
//cout<<"hi";
if(size == 1)
{
//cout<<"less";
//cout<<a[0];
return a;
}
int* left;
int* right;
int middle = ceil(size/2);
left = new int(middle);
right = new int(middle);
for(int i=0;i<middle;i++)
{
left[i]=a[i];
//cout<<left[i];
}
cout<<"\t";
for(int j=middle;j<size;j++)
{
right[j]=a[j];
//cout<<right[j];
}
cout<<"\t";
left = merge_sort(left,middle);
//if(size==2)
//cout<<left[0];
right = merge_sort(right,middle);
//if(size==2)
//cout<<right[0];
return merge(left,right,middle);
}
int* merge(int* l,int* r,int m)
{
int* result;
result = new int(2*m); //to store the output
int lsize=m; // to keep track of left sub list
int rsize=m; // to keep track of right sub list
int counter = 0; // will use to index result
//cout<<m;
while(lsize>0 || rsize>0)
{
if(lsize>0 && rsize>0)
{
if(l[0]<=r[0])
{
result[counter]=l[0];
counter++; //to store next value in result
lsize--;
l=&l[1]; //decrementing the size of left array
}
else
{
result[counter]=r[0];
counter++;
rsize--;
r=&r[1]; //dec. size of right array
}
}
else if(lsize>0)
{
result[counter]=l[0];
counter++;
lsize--;
l=&l[1];
}
else if(rsize>0)
{
result[counter]=l[0];
counter++;
lsize--;
l=&l[1];
}
}
return result;
}
Your code:
int *left = new int(middle);
allocates a single integer initialized to middle. You need:
int *left = new int [middle];
which allocates an array of middle integers. Rinse and repeat for int *right. Actually, you need to use:
int *right = new int [size - middle];
This gets the correct size for the right array. You then have to modify the recursive call to merge_sort() for the right sub-array:
merge_sort(right, size - middle);
Finally, you have to rewrite merge() to take the size of the left array and the size of the right array independently, because they may be of different sizes. For example, if you sort 10 elements,
you then end up with a call to merge two arrays of 5 (which is fine), but at the next level you need to merge an array of 2 and an array of 3 elements (and you're hosed).
The allocation of result also has the () vs [] allocation problem. And there are some other as yet unresolved problems. But these are important steps in the right direction.
As mentioned in a comment to the question, you have a monumental memory leakage problem, too. What's more, it is not trivial to fix because merge_sort() does an early exit without allocating new memory, so it isn't as simple as 'delete the memory returned by merge_sort()'.
Copy and paste is wonderful until you forget to edit the pasted copy correctly:
else if (lsize > 0)
{
result[counter] = l[0];
counter++;
lsize--;
l = &l[1];
}
else if (rsize > 0)
{
result[counter] = l[0];
counter++;
lsize--;
l = &l[1];
}
Methinks you should be using r and rsize in the second of these blocks.
This still isn't the whole story...
And the residual problem (apart from memory management, which is still 100% leaky and problematic) is:
for(int j=middle;j<size;j++)
{
right[j]=a[j];
//cout<<right[j];
}
You're copying into parts of right that you've not allocated. You need something more like:
for(int j = 0; j < size - middle; j++)
{
right[j] = a[j + middle];
//cout<<right[j];
}
This code works as long as you always sort at least two items at the top level (you crash freeing unallocated space if you sort 1 item — that's part of the memory management problem).
#include <iostream>
using namespace std;
namespace {
int *merge(int *l, int m, int *r, int n);
void dump_array(int *a, int size)
{
int i;
cout << size << ": ";
for (i = 0; i < size; i++)
{
cout << ' ' << a[i];
if (i % 10 == 9)
cout << '\n';
}
if (i % 10 != 0)
cout << '\n';
}
};
int *merge_sort(int *a, int size)
{
cout << "-->> merge_sort:\n";
dump_array(a, size);
if (size <= 1)
{
cout << "<<-- merge_sort: early return\n";
return a;
}
int middle = size/2;
int *left = new int[middle];
int *right = new int[size - middle];
cout << middle << ": ";
for (int i = 0; i < middle; i++)
{
left[i] = a[i];
cout << ' ' << left[i];
}
cout << "\n";
cout << (size - middle) << ": ";
for (int j = 0; j < size - middle; j++)
{
right[j] = a[j + middle];
cout << ' ' << right[j];
}
cout << "\n";
cout << "MSL:\n";
int *nleft = merge_sort(left, middle);
cout << "NL: ";
dump_array(nleft, middle);
cout << "OL: ";
dump_array(left, middle);
cout << "OR: ";
dump_array(right, size - middle);
cout << "MSR:\n";
int *nright = merge_sort(right, size - middle);
cout << "NR: ";
dump_array(nright, size - middle);
cout << "NL: ";
dump_array(nleft, middle);
cout << "OL: ";
dump_array(left, middle);
cout << "OR: ";
dump_array(right, size - middle);
int *result = merge(nleft, middle, nright, size - middle);
cout << "<<-- merge_sort:\n";
dump_array(result, size);
return result;
}
namespace {
int *merge(int *l, int m, int *r, int n)
{
int *result = new int[m + n];
int lsize = m;
int rsize = n;
int counter = 0;
cout << "-->> merge: (" << m << "," << n << ")\n";
dump_array(l, m);
dump_array(r, n);
while (lsize > 0 || rsize > 0)
{
if (lsize > 0 && rsize > 0)
{
if (l[0] <= r[0])
{
result[counter] = l[0];
cout << "C: " << counter << "; L = " << l[0] << "; LS = " << lsize << '\n';
counter++;
lsize--;
l++;
}
else
{
result[counter] = r[0];
cout << "C: " << counter << "; R = " << r[0] << "; RS = " << rsize << '\n';
counter++;
rsize--;
r++;
}
}
else if (lsize > 0)
{
result[counter] = l[0];
cout << "C: " << counter << "; L = " << l[0] << "; LS = " << lsize << '\n';
counter++;
lsize--;
l++;
}
else if (rsize > 0)
{
result[counter] = r[0];
cout << "C: " << counter << "; R = " << r[0] << "; RS = " << rsize << '\n';
counter++;
rsize--;
r++;
}
}
cout << "<<-- merge:\n";
dump_array(result, m+n);
return result;
}
};
int main()
{
for (int i = 2; i <= 10; i++)
{
int array1[] = { 9, 3, 5, 7, 1, 8, 0, 6, 2, 4 };
cout << "\nMerge array of size " << i << "\n\n";
int *result = merge_sort(array1, i);
delete[] result;
}
return 0;
}
This is the debug-laden code. It's the level to which I went to get the result. I could perhaps have used a debugger. Were I on a machine where valgrind works, it might have helped too (but it does not work on Mac OS X 10.8.x, sadly).
There are still many, many ways to improve the code — including the memory management. You'd probably find it easiest to pass the input array to merge() for use as the result array (avoiding the memory allocation in that code). This would reduce the memory management burden.
When you remove the debug code, you'll need to call the dump_array() function in the main() program to get the before and after sorting array images.
Code converted to template functions and leak-free
I've simplified the code a fair bit, especially in the merge() function. Also, more as a matter of curiosity than anything else, converted it to a set of template functions, and then used them with 4 different array types (int, double, std::string, char). The amount of debugging has been dramatically reduced, and the main debugging is conditional on being compiled with -DTRACE_ENABLED now.
The code is now leak-free; valgrind on a Linux box (virtual machine) gives it a clean bill of health when there are no exceptions. It is not guaranteed exception-safe, though. In fact, given the naked uses of new and delete, it is pretty much guaranteed not to be exception-safe. I've left the namespace control in place, but I'm far from convinced it is really correct — indeed, I'd lay odds on it not being good. (I'm also curious if anyone has any views on how to layout code within a namespace { … }; block; it seems odd not indenting everything inside a set of braces, but …)
#include <iostream>
using namespace std;
namespace {
#if !defined(TRACE_ENABLED)
#define TRACE_ENABLED 0
#endif
enum { ENABLE_TRACE = TRACE_ENABLED };
template <typename T>
void merge(T *l, int m, T *r, int n, T *result);
template <typename T>
void dump_array(const char *tag, T *a, int size)
{
int i;
cout << tag << ": (" << size << ") ";
for (i = 0; i < size; i++)
{
cout << " " << a[i];
if (i % 10 == 9)
cout << '\n';
}
if (i % 10 != 0)
cout << '\n';
}
};
template <typename T>
void merge_sort(T *a, int size)
{
if (size <= 1)
return;
if (ENABLE_TRACE)
dump_array("-->> merge_sort", a, size);
int middle = size/2;
T *left = new T[middle];
T *right = new T[size - middle];
for (int i = 0; i < middle; i++)
left[i] = a[i];
for (int j = 0; j < size - middle; j++)
right[j] = a[j + middle];
merge_sort(left, middle);
merge_sort(right, size - middle);
merge(left, middle, right, size - middle, a);
delete [] left;
delete [] right;
if (ENABLE_TRACE)
dump_array("<<-- merge_sort", a, size);
}
namespace {
template <typename T>
void merge(T *l, int m, T *r, int n, T *result)
{
T *l_end = l + m;
T *r_end = r + n;
T *out = result;
if (ENABLE_TRACE)
{
cout << "-->> merge: (" << m << "," << n << ")\n";
dump_array("L", l, m);
dump_array("R", r, n);
}
while (l < l_end && r < r_end)
{
if (*l <= *r)
*out++ = *l++;
else
*out++ = *r++;
}
while (l < l_end)
*out++ = *l++;
while (r < r_end)
*out++ = *r++;
if (ENABLE_TRACE)
dump_array("<<-- merge", result, m+n);
}
};
#include <string>
int main()
{
for (size_t i = 1; i <= 10; i++)
{
int array1[] = { 9, 3, 5, 7, 1, 8, 0, 6, 2, 4 };
if (i <= sizeof(array1)/sizeof(array1[0]))
{
cout << "\nMerge array of type int of size " << i << "\n\n";
dump_array("Original", array1, i);
merge_sort(array1, i);
dump_array("PostSort", array1, i);
}
}
for (size_t i = 1; i <= 10; i++)
{
double array2[] = { 9.9, 3.1, 5.2, 7.3, 1.4, 8.5, 0.6, 6.7, 2.8, 4.9 };
if (i <= sizeof(array2)/sizeof(array2[0]))
{
cout << "\nMerge array of type double of size " << i << "\n\n";
dump_array("Original", array2, i);
merge_sort(array2, i);
dump_array("PostSort", array2, i);
}
}
for (size_t i = 1; i <= 10; i++)
{
std::string array3[] = { "nine", "three", "five", "seven", "one", "eight", "zero", "six", "two", "four" };
if (i <= sizeof(array3)/sizeof(array3[0]))
{
cout << "\nMerge array type std::string of size " << i << "\n\n";
dump_array("Original", array3, i);
merge_sort(array3, i);
dump_array("PostSort", array3, i);
}
}
for (size_t i = 1; i <= 10; i++)
{
char array4[] = "jdfhbiagce";
if (i <= sizeof(array4)/sizeof(array4[0]))
{
cout << "\nMerge array type char of size " << i << "\n\n";
dump_array("Original", array4, i);
merge_sort(array4, i);
dump_array("PostSort", array4, i);
}
}
return 0;
}