331 lines
7.7 KiB
C++
331 lines
7.7 KiB
C++
#include "sorts.h"
|
|
#include <chrono>
|
|
#include <fstream>
|
|
#include <iostream>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
// Initialization function for Sorter class
|
|
Sorter::Sorter()
|
|
{
|
|
lineCount = 0;
|
|
currentType = INSERTION;
|
|
defaultFile = 0;
|
|
defaultOnly = 1;
|
|
fileGiven = 0;
|
|
allLists = 0;
|
|
sortGiven = 0;
|
|
}
|
|
|
|
// Sets the current filename
|
|
void Sorter::SetFilename(std::string newName)
|
|
{
|
|
this->filename = newName;
|
|
}
|
|
|
|
// Returns the current filename
|
|
std::string Sorter::GetFilename(void)
|
|
{
|
|
return this->filename;
|
|
}
|
|
|
|
// Sets word list found in file into vector
|
|
void Sorter::SetWordList(void)
|
|
{
|
|
std::string bufferStr;
|
|
std::ifstream file(this->filename);
|
|
if (!file.is_open())
|
|
{
|
|
std::cout << "Failed opening file: " << this->filename << '\n';
|
|
exit(1);
|
|
}
|
|
while (getline(file, bufferStr))
|
|
{
|
|
originalWordList.push_back(bufferStr);
|
|
lineCount++;
|
|
}
|
|
return;
|
|
}
|
|
|
|
// Main function for calling all sort categories
|
|
void Sorter::RunSorts(void)
|
|
{
|
|
if (defaultOnly || fileGiven)
|
|
{
|
|
SetWordList();
|
|
__RunSorts__();
|
|
}
|
|
if (allLists)
|
|
SortAll();
|
|
return;
|
|
}
|
|
|
|
// Sorts all default files if allLists is set
|
|
void Sorter::SortAll(void)
|
|
{
|
|
int fileCount = 10;
|
|
std::string newFilename;
|
|
for (int i = 1; i <= fileCount; i++)
|
|
{
|
|
lineCount = 0;
|
|
newFilename = "test/SORTED/sorted";
|
|
newFilename += std::to_string(15*i);
|
|
newFilename += "K.txt";
|
|
SetFilename(newFilename);
|
|
SetWordList();
|
|
__RunSorts__();
|
|
originalWordList.clear();
|
|
}
|
|
}
|
|
|
|
// Function for starting sort functions
|
|
void Sorter::__RunSorts__(void)
|
|
{
|
|
if (!sortGiven)
|
|
currentType = INSERTION;
|
|
if (currentType == INSERTION)
|
|
{
|
|
newWordList = originalWordList;
|
|
InsertionSort();
|
|
OutputResult();
|
|
}
|
|
if (!sortGiven)
|
|
currentType = MERGE;
|
|
if (currentType == MERGE)
|
|
{
|
|
newWordList = originalWordList;
|
|
MergeSort();
|
|
OutputResult();
|
|
}
|
|
if (!sortGiven)
|
|
currentType = HEAP;
|
|
if (currentType == HEAP)
|
|
{
|
|
newWordList = originalWordList;
|
|
HeapSort();
|
|
OutputResult();
|
|
}
|
|
}
|
|
|
|
// Main function for printing results
|
|
void Sorter::OutputResult(void)
|
|
{
|
|
switch(currentType)
|
|
{
|
|
case INSERTION:
|
|
PrintSortTime("IS");
|
|
PrintToFile("IS");
|
|
break;
|
|
case MERGE:
|
|
PrintSortTime("MS");
|
|
PrintToFile("MS");
|
|
break;
|
|
case HEAP:
|
|
PrintSortTime("HS");
|
|
PrintToFile("HS");
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Prints sort time to the screen
|
|
void Sorter::PrintSortTime(std::string outputFilename)
|
|
{
|
|
std::string sortSizeString = std::to_string(lineCount / 1000);
|
|
std::cout << outputFilename << sortSizeString;
|
|
std::cout << " took " << sortTime.count() << " s" << std::endl;
|
|
return;
|
|
}
|
|
|
|
// Prints result of sort operation to file
|
|
void Sorter::PrintToFile(std::string outputFilename)
|
|
{
|
|
std::string sortSizeString = std::to_string(lineCount / 1000);
|
|
std::string outputPath = "test/OUTPUT/";
|
|
outputPath += outputFilename + sortSizeString + "K.txt";
|
|
std::ofstream file(outputPath);
|
|
if (!file.is_open())
|
|
{
|
|
std::cout << "Failed opening file\n";
|
|
exit(1);
|
|
}
|
|
for (unsigned int i = 0; i < lineCount; i++)
|
|
file << newWordList[i] << '\n';
|
|
file.close();
|
|
}
|
|
|
|
// Main function for insertion sort
|
|
void Sorter::InsertionSort(void)
|
|
{
|
|
auto start = std::chrono::system_clock::now();
|
|
int i;
|
|
std::string key;
|
|
for (int j = 1; j < lineCount; j++)
|
|
{
|
|
key = newWordList[j];
|
|
i = j - 1;
|
|
while ((i >= 0) && (newWordList[i] > key))
|
|
{
|
|
newWordList[i + 1] = newWordList[i];
|
|
i = i - 1;
|
|
}
|
|
newWordList[i + 1] = key;
|
|
}
|
|
auto end = std::chrono::system_clock::now();
|
|
sortTime = end - start;
|
|
}
|
|
|
|
// Main function for merge sort
|
|
void Sorter::MergeSort(void)
|
|
{
|
|
auto start = std::chrono::system_clock::now();
|
|
__MergeSort__(0, lineCount - 1);
|
|
auto end = std::chrono::system_clock::now();
|
|
sortTime = end - start;
|
|
return;
|
|
}
|
|
|
|
// Merge sort function child
|
|
void Sorter::__MergeSort__(int p, int r)
|
|
{
|
|
if (p < r)
|
|
{
|
|
int q = (p + r) / 2;
|
|
__MergeSort__(p, q);
|
|
__MergeSort__(q+1, r);
|
|
__Merge__(p, q, r);
|
|
}
|
|
return;
|
|
}
|
|
|
|
// Merge sort function child
|
|
void Sorter::__Merge__(int p, int q, int r)
|
|
{
|
|
int n1 = q - p + 1;
|
|
int n2 = r - q;
|
|
const int leftTmpSize = n1 + 1;
|
|
const int rightTmpSize = n2 + 1;
|
|
std::string leftTmp[leftTmpSize];
|
|
std::string rightTmp[rightTmpSize];
|
|
for (int i = 0; i < n1; i++)
|
|
leftTmp[i] = newWordList[p + i];
|
|
for (int i = 0; i < n2; i++)
|
|
rightTmp[i] = newWordList[q + i + 1];
|
|
leftTmp[n1] = "ZZZZZ";
|
|
rightTmp[n2] = "ZZZZZ";
|
|
int i = 0;
|
|
int j = 0;
|
|
for (int k = p; k <= r; k++)
|
|
{
|
|
if (leftTmp[i] <= rightTmp[j])
|
|
{
|
|
newWordList[k] = leftTmp[i];
|
|
i++;
|
|
} else {
|
|
newWordList[k] = rightTmp[j];
|
|
j++;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Main function for heap sort
|
|
void Sorter::HeapSort(void)
|
|
{
|
|
auto start = std::chrono::system_clock::now();
|
|
__HeapSort__();
|
|
auto end = std::chrono::system_clock::now();
|
|
sortTime = end - start;
|
|
return;
|
|
}
|
|
void Sorter::__HeapSort__(void)
|
|
{
|
|
std::string tempStr;
|
|
// Build Max Heap
|
|
heapSize = newWordList.size();
|
|
for (int i = ((newWordList.size() / 2) - 1); i >= 0; i--)
|
|
__Heapify__(i);
|
|
// Heap Sort
|
|
for (int i = (newWordList.size() - 1); i >= 0; i--)
|
|
{
|
|
tempStr = newWordList[i];
|
|
newWordList[i] = newWordList[0];
|
|
newWordList[0] = tempStr;
|
|
heapSize = i;
|
|
__Heapify__(0);
|
|
}
|
|
return;
|
|
}
|
|
|
|
void Sorter::__Heapify__(int i)
|
|
{
|
|
std::string tempStr;
|
|
int largest = i;
|
|
int leftIndex = __LEFT__(i);
|
|
int rightIndex = __RIGHT__(i);
|
|
if ((leftIndex < heapSize) && (newWordList[leftIndex] > newWordList[largest]))
|
|
largest = leftIndex;
|
|
if ((rightIndex < heapSize) && (newWordList[rightIndex] > newWordList[largest]))
|
|
largest = rightIndex;
|
|
if (largest != i)
|
|
{
|
|
tempStr = newWordList[i];
|
|
newWordList[i] = newWordList[largest];
|
|
newWordList[largest] = tempStr;
|
|
__Heapify__(largest);
|
|
}
|
|
}
|
|
|
|
int Sorter::__LEFT__(int i)
|
|
{
|
|
return ((2 * i) + 1);
|
|
}
|
|
|
|
int Sorter::__RIGHT__(int i)
|
|
{
|
|
return ((2 * i) + 2);
|
|
}
|
|
|
|
// Checks for command line arguments
|
|
void CheckArguments(int argc, char* arguments[], Sorter* sortObj)
|
|
{
|
|
std::string tempStr;
|
|
for (int i = 0; i < argc; i++)
|
|
{
|
|
tempStr = arguments[i];
|
|
if ((tempStr == "-a") || (tempStr == "--all"))
|
|
{
|
|
sortObj->defaultOnly = 0;
|
|
sortObj->allLists = 1;
|
|
|
|
}
|
|
if ((tempStr == "-f") || (tempStr == "--filename"))
|
|
{
|
|
sortObj->SetFilename(arguments[i + 1]);
|
|
sortObj->defaultOnly = 0;
|
|
sortObj->fileGiven = 1;
|
|
}
|
|
if ((tempStr == "-d") || (tempStr == "--default"))
|
|
{
|
|
sortObj->SetFilename("test/PERM/perm15K.txt");
|
|
sortObj->defaultFile = 1;
|
|
}
|
|
if ((tempStr == "-s") || (tempStr == "--sort-type"))
|
|
{
|
|
sortObj->sortGiven = 1;
|
|
tempStr = arguments[i + 1];
|
|
if (tempStr == "insertion")
|
|
sortObj->currentType = INSERTION;
|
|
if (tempStr == "merge")
|
|
sortObj->currentType = MERGE;
|
|
if (tempStr == "heap")
|
|
sortObj->currentType = HEAP;
|
|
if (tempStr == "all")
|
|
sortObj->sortGiven = 0;
|
|
}
|
|
}
|
|
if (sortObj->defaultOnly)
|
|
sortObj->SetFilename("test/PERM/perm15K.txt");
|
|
return;
|
|
}
|