Quicksort for string array - c++

After looking through articles, tutorials and solutions everywhere, i haven't come across anything that explains how to use quicksort for string arrays. All examples I found are of either "int" or "char".
This is my edited code.
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <time.h>
#include <string>
#include <ctime>
#include <stdio.h>
using namespace std;
int count;
template <class T>
void printArray(T ar[], int sz);
template <class T>
void bubbleSort(T ar[], int sz);
void quickSortMain(string items[], int ct);
void quickSort(string items[], int left, int right);
//////////////////////////////////////////////////////////////////////////
// Main Function Implementation
//////////////////////////////////////////////////////////////////////////
int main() {
int numOfData = 50000;
string line, temp;
ofstream resultFile;
ofstream tableFile;
double data[100][2];
string patient[numOfData];
ifstream dataFile("shufflePatient.txt");
int i;
int SIZE = 0;
cout << "Program to shuffle data" << endl << endl;
cout << "This program will calculate swapping processes and running time.";
/*Storing data*/
cout << "Reading data in process.." << endl;
if (dataFile.is_open()) {
i=-1;
while (dataFile.good()) {
getline (dataFile, line);
if (i>=0) patient[i] = line;
i++;
}
dataFile.close();
}
SIZE = 5;
quickSortMain(patient, 5);
/*Writing to file*/
cout << "Writing to file.." << endl;
resultFile.open ("test.txt");
for (int i=0 ; i<numOfData ; i++) {
resultFile << patient[i] << "\n";
}
resultFile.close();
system("pause");
return 0;
}
void quickSortMain(string items[], int ct)
{
quickSort(items, 0, ct-1);
}
void quickSort(string items[], int left, int right)
{
int i, j;
char *x;
string temp[10];
i = left;
j = right;
x = items[(left+right)/2];
do {
while((strcmp(items[i],x) < 0) && (i < right)) {
i++;
}
while((strcmp(items[j],x) > 0) && (j > left)) {
j--;
}
if(i <= j) {
strcpy(temp, items[i]);
strcpy(items[i], items[j]);
strcpy(items[j], temp);
i++;
j--;
}
} while(i <= j);
if(left < j) {
quickSort(items, left, j);
}
if(i < right) {
quickSort(items, i, right);
}
}
//----------------------------------------------------------------------------
// prints array of size size
//----------------------------------------------------------------------------
template <class T>
void printArray(T patient[], int size)
{
for(int i = 0; i < size; i++)
cout << patient[i] << " ";
cout << endl;
}
//----------------------------------------------------------------------------
// sorts array of size size by Bubble Sort method
//----------------------------------------------------------------------------
template <class T>
void bubbleSort(T patient[], int size) //returning an int
{
bool noChange = true;
for(int i = size; i > 0; i--)
{
noChange = true;
for(int j = 1; j < i; j++)
{
if(patient[j] < patient[j - 1])
{
swap(patient[j], patient[j-1]);
count = count + 1;
noChange = false;
}
}
if (noChange)
return ;
}
}
The error i got was in this line:
x = items[(left+right)/2];
I changed
char x*; to string x;
I don't know if that was correct. Now the error im getting is that strcmp and strcpy are not declared. Any help on what i should do next?

string patient[numOfData];
vs.
template <class T>
void quickSortMain(char items[][10], int ct)
vs.
quickSortMain(patient, 5);
quickSortMain expects an array of char[10], not string[]. Not only this, but it also depends on a template parameter. Drop the template <class T> and replace char[][10] with string[].

Related

How do I access all elements to my array that i'm pointing at and change them during a mergeSort function call?

I have a mergeSort function that I have tested and it works when I have the function in main(). I'm trying to implement it into a class right now but when I print out the array elements after sorting it, they are not sorted. I think that my problem lies in how I'm accessing my array elements, and what I'm doing with them.
Main.cpp
#include <iostream>
#include "Sort.h"
using namespace std;
int main() {
Sort temp(10);
temp.InitArray();
cout << "Unsorted: ";
temp.Print();
temp.MergeSort(0, 9);
cout << "Sorted: ";
temp.Print();
cout << "end" << endl;
cin.get();
return 0;
}
Sort.h
#ifndef __SORT__
#define __SORT__
class Sort
{
public:
Sort(int arraySize);
~Sort();
void InitArray();
void MergeSort(int low, int high);
void Print();
private:
int *myArray;
int size;
void MergeSortRecursionHelper(int indexL, int indexM, int indexH);
};
#endif
Sort.cpp
#include <random>
#include <iostream>
#include "Sort.h"
Sort::Sort(int arraySize){
myArray = new int[arraySize];
size = arraySize;
}
Sort::~Sort(){
delete [] myArray;
}
void Sort::InitArray() {
for(int i = 0; i < size; i++){
myArray[i] = rand() % 100;
}
}
void Sort::MergeSort(int low, int high) {
//base case
if(myArray[high] <= myArray[low]){
return;
}
int mid = (low + high) / 2;
MergeSort(low, mid);
MergeSort(mid + 1, high);
MergeSortRecursionHelper(low, mid, high);
}
void Sort::MergeSortRecursionHelper(int indexL, int indexM, int indexH)
{
int mSize = indexH - indexL + 1;
int* mergedData = new int[mSize];
int mergedIndex = 0;
int rightInd = indexM + 1;
int leftInd = indexL;
while(leftInd <= indexM && rightInd <= indexH){
if(myArray[indexL] < myArray[rightInd]){
mergedData[mergedIndex++] = myArray[leftInd++];
}else{
mergedData[mergedIndex++] = myArray[rightInd++];
}
}
while(leftInd <= indexM){
mergedData[mergedIndex++] = myArray[leftInd++];
}
while(rightInd <= indexH){
mergedData[mergedIndex++] = myArray[rightInd++];
}
for(int i = indexL; i < indexH + 1; i++){
myArray[i] = mergedData[i - indexL];
}
delete[] mergedData;
}
void Sort::Print(){
for(int i = 0; i < size; i++){
std::cout << " " << myArray[i];
}
std::cout << std::endl;
}
Your first check in your if is not right. Just because, e.g. input {8,4,100,7}, doesn't mean it's sorted due to 7 < 8.
void Sort::MergeSort(int low, int high) {
//base case
if(myArray[high] <= myArray[low]){
return;
}

why this code giving error mismatch in strcpy

There is a mismatch error in strcpy() function. I'm new to the C++ language.
#include<iostream>
#include<cstring>
using namespace std;
#define max 5
class ss {
private:
char str[max][10];
public:
void get_str() {
for (int i = 0; i < max; i++)
cin >> str[i];
}
void disp() {
cout << "Entered strings are\n";
for (int i = 0; i < max; i++) {
if (strcmp(str[i], str[i + 1]) != 0)
cout << str[i] << endl;
}
}
/*
void sort()
{
char temp[max];
for (int i = 0; i < max - 1; i++)
for (int j = 0; j < (max - i - 1); j++)
{
if (strcmp(str[j], str[j + 1])>0)
{
strcpy(temp, str[j]);
strcpy(str[j], str[j + 1]);
strcpy(str[j + 1], temp);
}
}
disp();
}
*/
void qsort()
{
qs(str, 0, max - 1);
disp();
}
void qs(char *&str, int st, int e)
{
int pi = part(str, st, e);
qs(s, st, pi - 1);
qs(s, pi + 1, e);
}
int part(char *&s, int st, int e)
{
char pi[max], swap[max];
strcpy(pi, s[e]);
int pii = st;
int i = st;
for (i; i < e; i++) {
if ((strcmp(s[i], s[pii])) <= 0)
{
strcpy(swap, s[pii]);
strcpy(s[pii], s[i]);
strcpy(s[i], swap);
pii++;
}
}
strcpy(swap, str[e]);
strcpy(str[e], str[pii]);
strcpy(str[pii], swap);
}
};
main()
{
ss s;
cout << "Enter the strings\n";
s.get_str();
s.disp();
s.sort();
cout << "after the sort" << endl;
s.disp();
}
I found several problems with your code:
Arguments are passed to qs() and part() as char *&, not char ** or char [max][10].
s is undefined in qs() (did you mean str?).
ISO C++ forbids a definition of main() without a return value.
part() has a non-void return type and doesn't return a value.
Repaired code is shown below:
#include <iostream>
#include <cstring>
using namespace std;
#define max 5
class ss {
private:
char str[max][10];
public:
void get_str() {
for (int i = 0; i < max; i++)
cin >> str[i];
}
void disp() {
cout << "Entered strings are\n";
for (int i = 0; i < max; i++) {
if (strcmp(str[i], str[i + 1]) != 0)
cout << str[i] << endl;
}
}
void sort()
{
char temp[max];
for (int i = 0; i < max - 1; i++)
for (int j = 0; j < (max - i - 1); j++)
{
if (strcmp(str[j], str[j + 1])>0)
{
strcpy(temp, str[j]);
strcpy(str[j], str[j + 1]);
strcpy(str[j + 1], temp);
}
}
disp();
}
void qsort()
{
qs(reinterpret_cast<char **>(str), 0, max - 1);
disp();
}
void qs(char **str, int st, int e)
{
int pi = part(reinterpret_cast<char **>(str), st, e);
qs(str, st, pi - 1);
qs(str, pi + 1, e);
}
int part(char **s, int st, int e)
{
char pi[max], swap[max];
strcpy(pi, s[e]);
int pii = st;
int i = st;
for (; i < e; i++) {
if ((strcmp(s[i], s[pii])) <= 0)
{
strcpy(swap, s[pii]);
strcpy(s[pii], s[i]);
strcpy(s[i], swap);
pii++;
}
}
strcpy(swap, str[e]);
strcpy(str[e], str[pii]);
strcpy(str[pii], swap);
// NO RETURN VALUE?
return 0;
}
};
int main()
{
ss s;
cout << "Enter the strings\n";
s.get_str();
s.disp();
s.sort();
cout << "after the sort" << endl;
s.disp();
return 0;
}
Or, if you don't want to use reinterpret_cast<>(), you can use this:
...
void qsort()
{
qs(str, 0, max - 1);
disp();
}
void qs(char str[max][10], int st, int e)
{
int pi = part(str, st, e);
qs(str, st, pi - 1);
qs(str, pi + 1, e);
}
int part(char s[max][10], int st, int e)
...

Adding counter to bubblesort function

I need to calculate the total number of swapping process and sorting running time for my bubble sort function. For running time, I was successful. But for the total number of swapping processes, I couldn't really understand what to do. I thought of initializing "count" and then tried to call it into the main function. That was a failure.
This if my bubble sort function:
void bubbleSort(T patient[], int size)
{
bool noChange = true; // stop when a pass causes no change
for(int i = size; i > 0; i--)
{
noChange = true;
for(int j = 1; j < i; j++)
{
if(patient[j] < patient[j - 1])
{
swap(patient[j], patient[j-1]);
count = count + 1;
noChange = false;
} // end if
} // end for(j)
if (noChange)
return; // sorted--no need to continue
} // end for(i)
}
"count" seems to show no value when called into the main function. Any tips on what I should try so that I could get the total number of swapping process in this?
EDIT 3:
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <time.h>
#include <string>
#include <ctime>
using namespace std;
const int SIZE = 5;
template <class T>
void printArray(T ar[], int sz);
template <class T>
int bubbleSort(T ar[], int sz);
//////////////////////////////////////////////////////////////////////////
// Main Function Implementation
//////////////////////////////////////////////////////////////////////////
int main() {
int numOfData = 50000;
string line, temp;
ofstream resultFile;
string patient[numOfData];
ifstream dataFile("shufflePatient.txt");
int times,i,count;
cout << "Program to shuffle data" << endl << endl;
cout << "This program will calculate swapping processes and running time.";
/*Storing data*/
cout << "Reading data in process.." << endl;
if (dataFile.is_open()) {
i=-1;
while (dataFile.good()) {
getline (dataFile, line);
if (i>=0) patient[i] = line;
i++;
}
dataFile.close();
}
double start_s=clock();
bubbleSort(patient,SIZE);
double stop_s=clock();
cout << "time: " << (stop_s-start_s)/double(CLOCKS_PER_SEC) << endl;
count = bubbleSort(patient,SIZE) ;
cout << "swapping process : " << count ;
cin.get(); // hold window open
/*Writing to file*/
cout << "Writing to file.." << endl;
resultFile.open ("test.txt");
for (int i=0 ; i<numOfData ; i++) {
resultFile << patient[i] << "\n";
}
resultFile.close();
system("pause");
return 0;
}
//----------------------------------------------------------------------------
// prints array of size size
//----------------------------------------------------------------------------
template <class T>
void printArray(T patient[], int size)
{
for(int i = 0; i < size; i++)
cout << patient[i] << " ";
cout << endl;
}
//----------------------------------------------------------------------------
// sorts array of size size by Bubble Sort method
//----------------------------------------------------------------------------
template <class T>
int bubbleSort(T patient[], int size) //returning an int
{
int count = 0; //initializing count
bool noChange = true;
for(int i = size; i > 0; i--)
{
noChange = true;
for(int j = 1; j < i; j++)
{
if(patient[j] < patient[j - 1])
{
swap(patient[j], patient[j-1]);
count = count + 1;
noChange = false;
}
}
if (noChange)
return count; // returning count
}
return count; // returning count
}
This is my updated code. Count value returns to 0. I don't know if the code I've used is right or wrong (where i call the return value of count). Any thoughts?
PS
Also, after changing my functions from void to int, for some reason my code stops sorting the data alphabetically when its written into the "text" file. Whats up with this?
You are not using the return value from the function, why don't you make the function return int - and return the count of number of swaps:
int bubbleSort(T patient[], int size) //returning an int
{
int count = 0; //initializing count
bool noChange = true;
for(int i = size; i > 0; i--)
{
noChange = true;
for(int j = 1; j < i; j++)
{
if(patient[j] < patient[j - 1])
{
swap(patient[j], patient[j-1]);
count = count + 1;
noChange = false;
}
}
if (noChange)
return count; // returning count
}
return count; // returning count
}
PS
The problem in the original code could be where you declared or initialized count (which is not shown in the code snap).
Also, using local variable is usually a better practice than using global ones.

quicksort string array help c++

This is my code. I don't know how to get the code to run. Im having problems with quicksorting for string.
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <time.h>
#include <string>
#include <ctime>
#include <stdio.h>
using namespace std;
int count;
template <class T>
void printArray(T ar[], int sz);
template <class T>
void bubbleSort(T ar[], int sz);
void quickSortMain(string items[], int ct);
void quickSort(string items[], int left, int right);
//////////////////////////////////////////////////////////////////////////
// Main Function Implementation
//////////////////////////////////////////////////////////////////////////
int main() {
int numOfData = 50000;
string line, temp;
ofstream resultFile;
ofstream tableFile;
double data[100][2];
string patient[numOfData];
ifstream dataFile("shufflePatient.txt");
int i;
int SIZE = 0;
cout << "Program to shuffle data" << endl << endl;
cout << "This program will calculate swapping processes and running time.";
/*Storing data*/
cout << "Reading data in process.." << endl;
if (dataFile.is_open()) {
i=-1;
while (dataFile.good()) {
getline (dataFile, line);
if (i>=0) patient[i] = line;
i++;
}
dataFile.close();
}
SIZE = 5;
quickSortMain(patient, 5);
/*Writing to file*/
cout << "Writing to file.." << endl;
resultFile.open ("test.txt");
for (int i=0 ; i<numOfData ; i++) {
resultFile << patient[i] << "\n";
}
resultFile.close();
system("pause");
return 0;
}
void quickSortMain(string items[], int ct)
{
quickSort(items, 0, ct-1);
}
void quickSort(string items[], int left, int right)
{
int i, j;
char *x;
string temp[10];
i = left;
j = right;
x = items[(left+right)/2];
do {
while((strcmp(items[i],x) < 0) && (i < right)) {
i++;
}
while((strcmp(items[j],x) > 0) && (j > left)) {
j--;
}
if(i <= j) {
strcpy(temp, items[i]);
strcpy(items[i], items[j]);
strcpy(items[j], temp);
i++;
j--;
}
} while(i <= j);
if(left < j) {
quickSort(items, left, j);
}
if(i < right) {
quickSort(items, i, right);
}
}
//----------------------------------------------------------------------------
// prints array of size size
//----------------------------------------------------------------------------
template <class T>
void printArray(T patient[], int size)
{
for(int i = 0; i < size; i++)
cout << patient[i] << " ";
cout << endl;
}
//----------------------------------------------------------------------------
// sorts array of size size by Bubble Sort method
//----------------------------------------------------------------------------
template <class T>
void bubbleSort(T patient[], int size) //returning an int
{
bool noChange = true;
for(int i = size; i > 0; i--)
{
noChange = true;
for(int j = 1; j < i; j++)
{
if(patient[j] < patient[j - 1])
{
swap(patient[j], patient[j-1]);
count = count + 1;
noChange = false;
}
}
if (noChange)
return ;
}
}
The error i got was in this line:
x = items[(left+right)/2];
I changed
char x*; to string x;
I don't know if that was correct. Now the error im getting is that strcmp and strcpy are not declared. Any help on what i should do next?
That's correct, now change
strcmp(items[i],x) < 0
to
items[i] < x
and
strcmp(items[j],x) > 0
to
items[j] > x
and
strcpy(temp, items[i]);
to
temp = items[i];
etc.
But really this is a case of RTFM. If you're competent enough to write a quicksort routine you should be competent enough to look up how std::string works. Being able to access reference information is a very important skill for a programmer.

c++ permutations high numbers (convert code)

I am trying to convert this code that works for '0' - '3' strings to integer so that it will work for higher numbers
#include <string>
#include <iostream>
using namespace std;
void permutate(char[], int );
bool recurse(char[], int );
int main()
{
int strLength;
cout << "Enter your desired length: ";
cin >> strLength;
char strArray[strLength];
for (int i = 0; i<strLength; i++)
strArray[i] = '0';
permutate(strArray, sizeof(strArray));
return 0;
}
void permutate(char charArray[], int length)
{
string wait;
length--;
bool done = false;
while(!done)
{
for (int i = 0; i <= length; i++)
cout << charArray[i];
cout << endl;
if (charArray[length] == '3')
done = recurse(charArray, length);
else
charArray[length] = (char)(charArray[length]+1);
}
}
bool recurse(char charArray[], int length)
{
bool done = false;
int temp = length;
if (temp > 1)
{
charArray[temp] = '0';
if (charArray[temp-1] == '3')
{
temp--;
done = recurse(charArray, temp);
}
else
(charArray[temp-1] = (char)(charArray[temp-1] + 1));
}
else
{
charArray[temp] = '0';
if (charArray[temp-1] == '3')
done = true;
else
charArray[temp-1] = (char)(charArray[temp-1]+1);
}
return done;
}
I changed every char to int,
every '0' = 0, '3' = 3
every (charArray[temp-1] = (char)(charArray[temp-1] + 1)); to charArray[temp-1]++;
I tried to debug but I still can`t make it work :(
Manged to fix it( works for high numbers):
#include <string>
#include <iostream>
using namespace std;
void permutate(int[], int, int );
bool recurse(int[], int, int );
int main()
{
int strLength, nrElem;
cout << "Enter your desired length: ";
cin >> strLength;
cout << "Enter nr elem: ";
cin >> nrElem;
int strArray[strLength];
for (int i = 0; i<strLength; i++)
strArray[i] = 0;
permutate(strArray, strLength, nrElem );
cout << "\nSTOP";
return 0;
}
void permutate(int charArray[], int length, int nrElem)
{
// length--;
bool done = false;
while(!done)
{
for (int i = 0; i < length; i++)
cout << charArray[i] << " ";
cout << endl;
if (charArray[length - 1] == nrElem)
//done = true;
done = recurse(charArray, length, nrElem);
else
charArray[length - 1]++;
}
}
bool recurse(int charArray[], int length, int nrElem)
{
bool done = false;
int temp = length ;
if (temp > 1)
{
charArray[temp] = 0;
if (charArray[temp-1] == nrElem)
{
temp--;
done = recurse(charArray, temp, nrElem);
}
else
charArray[temp-1]++;
}
else
{
charArray[temp] = 0;
if (charArray[temp-1] == nrElem)
done = true;
else
charArray[temp-1]++;
}
return done;
}
In your permutate function, you're incrementing charArray[length] but checking to see if charArray[length - 1] is equal to nrElem, so you never end up calling recurse.
Here is a short piece of code to do the same (not an answer, however it did not look right in a comment field), not sure if you need the recursion, if you do not this code may be of interest:
#include <iostream>
#include <sstream>
using namespace std;
string output(int firstIntSize, int secondIntSize)
{
std::ostringstream oss;
for (int i = 0; i<firstIntSize; i++)
{
for (int j = 0; j< secondIntSize; j++)
{
oss << i << j << " ";
}
}
return oss.str();
}
int main()
{
cout << output(2,3);
return 0;
}
hmmm... Why not simply make a Permutations algorithm and then use a generic function to print whatever you are permutating. Here's how I would do it for strings:
#include <iostream>
#include <string>
template<class T>
void print(T * A, unsigned n){ //for printing purposes
for(unsigned i=0;i<n;i++){
std::cout<<A[i]<<" ";
}
std::cout<<std::endl;
}
void generate_permutations(unsigned k, std::string str, char *A, bool *U){
// k is the position that we need to fill, starts from 0 and goes to the end.
if(k<str.size()) //if k==str.size() then we will print it
for(unsigned i=0;i<str.size();i++){
if(U[i]==0){
A[k]=str[i]; U[i]=1;
generate_permutations(k+1, str, A,U);
U[i]=0; //after the recursion is finished and printed, we can release the letter.
}
}
else
print(A,str.size());
}
int main(){
std::string str;
std::cout<<"Enter the string to be permutated: \n";
std::cin>>str;
int n;
n = str.length(); // You don't really need to ask the user the size of the string he/she wants to enter.
bool *U; // we will keep track of the used letters with the help of this boolean vector
char *A; // we will copy the contents of str here, so that we keep the str intact
U = new bool[n];
for (int i=0;i<n;i++) U[i]=false;
A = new char[n];
for (int i=0;i<n;i++) A[i]=str[i];
generate_permutations(0,str,A,U);
return 0;
}
Now if you want to convert to numbers (ints), it's almost the same:
#include <iostream>
template<class T>
void print(T * A, int n){
for(int i=0;i<n;i++){
std::cout<<A[i]<<" ";
}
std::cout<<std::endl;
}
void generate_permutations(int k, int *A, bool *U, int n){
if(k==n)
print(A,n);
else {
for(int i=0;i<n;i++){
if(U[i]==0){
A[k]=i; U[i]=1;
generate_permutations(k+1,A,U,n);
U[i]=0;
}
}
}
}
int main(){
int n;
std::cout<<"Permutations of how many objects? \n";
std::cin>>n;
int * A;
bool *U;
A = new int[n];
U = new bool[n];
for (int i=0;i<n;i++) U[i]=false;
print(U, n);
generate_permutations(0,A,U,n);
return 0;
}