Updated README.md, fixed merge sort, added checking output with bash script, and added sort arguments

This commit is contained in:
TriantaTV 2023-02-11 19:22:37 -06:00
parent 266104fc4b
commit d544974809
9 changed files with 267 additions and 36 deletions

View File

@ -1,13 +1,18 @@
INC := -I include INC := -I include
STD := -std=c++11
main: compile link main: compile link
compile: compile:
g++ $(INC) -c -o build/main.o src/main.cpp g++ $(INC) $(STD) -c -o build/main.o src/main.cpp
g++ $(INC) -c -o build/sorts.o src/sorts.cpp g++ $(INC) $(STD) -c -o build/sorts.o src/sorts.cpp
link: link:
g++ -o bin/main.out build/*.o g++ -o bin/main.out build/*.o
test: main
bin/main.out -a > test/SortTimes.txt
test/CheckSortedOutputs.sh
clean: clean:
rm build/*.o bin/*.out test/OUTPUT/*.txt rm build/*.o bin/*.out test/OUTPUT/*.txt

View File

@ -0,0 +1,42 @@
# Sorting
A program written to test the time complexity of insertion, merge, and heap sort
# Author
Gregory Crawford
# Compiling
Run `make` to compile the project.
Output files get placed into test/SORTED
# Running
Run `bin/main.out` with chosen arguments to run program
# Commands
## bin/main.out [-a | -f filename | -d]
Ex: `bin/main.out -f test/PERM/perm15K.txt -s merge`
# Arguments
## File selection
> -a OR --all
- Runs through all the original files (perm15K.txt - perm150K.txt)
- *EX: bin/main.out -a*
> -f path/to/file.txt OR --filename path/to/file.txt
- Runs a specific file to sort
- *EX: bin/main.out -f perm15K.txt*
> -d OR --default (**default**)
- Runs sort only on the default test file (perm15K.txt)
- *EX: bin/main.out -d*
## Sorting type selection
> -s | --sort-type
- Selects a sort type
- Options:
- insertion
- *EX: bin/main.out -s insertion*
- merge
- *EX: bin/main.out -s merge*
- heap
- *EX: bin/main.out -s heap*
- all (**default**)
- *EX: bin/main.out -s all*
# Notes

Binary file not shown.

Binary file not shown.

View File

@ -1,6 +1,7 @@
#ifndef SORTS_H #ifndef SORTS_H
#define SORTS_H #define SORTS_H
#include <chrono>
#include <string> #include <string>
#include <vector> #include <vector>
@ -12,15 +13,20 @@ private:
std::string filename; std::string filename;
int lineCount; int lineCount;
std::vector<std::string> originalWordList; std::vector<std::string> originalWordList;
std::vector<std::string> newWordList; std::chrono::duration<double> sortTime;
SortType currentType;
public: public:
Sorter(std::string newFilename); Sorter();
std::vector<std::string> newWordList;
bool defaultOnly, fileGiven, allLists, sortGiven;
SortType currentType;
std::string GetFilename(void); std::string GetFilename(void);
void SetFilename(std::string newName); void SetFilename(std::string newName);
void SetWordList(void); void SetWordList(void);
void SortAll(void);
void RunSorts(void); void RunSorts(void);
void __RunSorts__(void);
void OutputResult(void); void OutputResult(void);
void PrintSortTime(std::string outputFilename);
void PrintToFile(std::string outputFilename); void PrintToFile(std::string outputFilename);
void InsertionSort(void); void InsertionSort(void);
void MergeSort(void); void MergeSort(void);
@ -29,4 +35,6 @@ public:
void HeapSort(void); void HeapSort(void);
}; };
void CheckArguments(int argc, char* arguments[], Sorter* sortObj);
#endif #endif

View File

@ -1,8 +1,9 @@
#include "sorts.h" #include "sorts.h"
int main(int argc, char** argv) int main(int argc, char* argv[])
{ {
Sorter newSort(argv[1]); Sorter newSort;
CheckArguments(argc, argv, &newSort);
newSort.RunSorts(); newSort.RunSorts();
return 0; return 0;
} }

View File

@ -1,34 +1,41 @@
#include "sorts.h" #include "sorts.h"
#include <iostream> #include <chrono>
#include <fstream> #include <fstream>
#include <iostream>
#include <string> #include <string>
#include <vector> #include <vector>
Sorter::Sorter(std::string newFilename) // Initialization function for Sorter class
Sorter::Sorter()
{ {
lineCount = 0; lineCount = 0;
currentType = INSERTION; currentType = INSERTION;
SetFilename(newFilename); defaultOnly = 0;
SetWordList(); fileGiven = 0;
allLists = 0;
sortGiven = 0;
} }
// Sets the current filename
void Sorter::SetFilename(std::string newName) void Sorter::SetFilename(std::string newName)
{ {
this->filename = newName; this->filename = newName;
} }
// Returns the current filename
std::string Sorter::GetFilename(void) std::string Sorter::GetFilename(void)
{ {
return this->filename; return this->filename;
} }
// Sets word list found in file into vector
void Sorter::SetWordList(void) void Sorter::SetWordList(void)
{ {
std::string bufferStr; std::string bufferStr;
std::ifstream file(this->filename); std::ifstream file(this->filename);
if (!file.is_open()) if (!file.is_open())
{ {
std::cout << "Failed opening file\n"; std::cout << "Failed opening file: " << this->filename << '\n';
exit(1); exit(1);
} }
while (getline(file, bufferStr)) while (getline(file, bufferStr))
@ -39,32 +46,81 @@ void Sorter::SetWordList(void)
return; return;
} }
// Main function for calling all sort categories
void Sorter::RunSorts(void) 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/PERM/perm";
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; newWordList = originalWordList;
InsertionSort(); InsertionSort();
OutputResult(); OutputResult();
}
if (!sortGiven)
currentType = MERGE; currentType = MERGE;
if (currentType == MERGE)
{
newWordList = originalWordList; newWordList = originalWordList;
MergeSort(); MergeSort();
OutputResult(); OutputResult();
}
if (!sortGiven)
currentType = HEAP; currentType = HEAP;
if (currentType == HEAP)
{
newWordList = originalWordList; newWordList = originalWordList;
HeapSort(); HeapSort();
OutputResult(); OutputResult();
} }
}
// Main function for printing results
void Sorter::OutputResult(void) void Sorter::OutputResult(void)
{ {
switch(currentType) switch(currentType)
{ {
case INSERTION: case INSERTION:
PrintSortTime("IS");
PrintToFile("IS"); PrintToFile("IS");
break; break;
case MERGE: case MERGE:
PrintSortTime("MS");
PrintToFile("MS"); PrintToFile("MS");
break; break;
case HEAP: case HEAP:
PrintSortTime("HS");
PrintToFile("HS"); PrintToFile("HS");
break; break;
default: default:
@ -72,12 +128,21 @@ void Sorter::OutputResult(void)
} }
} }
// 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) void Sorter::PrintToFile(std::string outputFilename)
{ {
std::string sortSizeString = std::to_string(lineCount / 1000);
std::string outputPath = "test/OUTPUT/"; std::string outputPath = "test/OUTPUT/";
outputPath += outputFilename; outputPath += outputFilename + sortSizeString + "K.txt";
outputPath += std::to_string(lineCount / 1000);
outputPath += "K.txt";
std::ofstream file(outputPath); std::ofstream file(outputPath);
if (!file.is_open()) if (!file.is_open())
{ {
@ -89,8 +154,10 @@ void Sorter::PrintToFile(std::string outputFilename)
file.close(); file.close();
} }
// Main function for insertion sort
void Sorter::InsertionSort(void) void Sorter::InsertionSort(void)
{ {
auto start = std::chrono::system_clock::now();
int i; int i;
std::string key; std::string key;
for (int j = 1; j < lineCount; j++) for (int j = 1; j < lineCount; j++)
@ -104,14 +171,21 @@ void Sorter::InsertionSort(void)
} }
newWordList[i + 1] = key; newWordList[i + 1] = key;
} }
auto end = std::chrono::system_clock::now();
sortTime = end - start;
} }
// Main function for merge sort
void Sorter::MergeSort(void) void Sorter::MergeSort(void)
{ {
auto start = std::chrono::system_clock::now();
__MergeSort__(0, lineCount - 1); __MergeSort__(0, lineCount - 1);
auto end = std::chrono::system_clock::now();
sortTime = end - start;
return; return;
} }
// Merge sort function child
void Sorter::__MergeSort__(int p, int r) void Sorter::__MergeSort__(int p, int r)
{ {
if (p < r) if (p < r)
@ -124,19 +198,21 @@ void Sorter::__MergeSort__(int p, int r)
return; return;
} }
// Merge sort function child
void Sorter::__Merge__(int p, int q, int r) void Sorter::__Merge__(int p, int q, int r)
{ {
int n1 = q - p + 1; int n1 = q - p + 1;
int n2 = r - q; int n2 = r - q;
// L[i - 1] R[j - 1] const int leftTmpSize = n1 + 1;
std::vector<std::string> leftTmp; const int rightTmpSize = n2 + 1;
std::vector<std::string> rightTmp; std::string leftTmp[leftTmpSize];
std::string rightTmp[rightTmpSize];
for (int i = 0; i < n1; i++) for (int i = 0; i < n1; i++)
leftTmp.push_back(newWordList[p + i]); leftTmp[i] = newWordList[p + i];
for (int i = 0; i < n2; i++) for (int i = 0; i < n2; i++)
rightTmp.push_back(newWordList[q + i + 1]); rightTmp[i] = newWordList[q + i + 1];
leftTmp.push_back("ZZZZZ"); leftTmp[n1] = "ZZZZZ";
rightTmp.push_back("ZZZZZ"); rightTmp[n2] = "ZZZZZ";
int i = 0; int i = 0;
int j = 0; int j = 0;
for (int k = p; k <= r; k++) for (int k = p; k <= r; k++)
@ -145,16 +221,63 @@ void Sorter::__Merge__(int p, int q, int r)
{ {
newWordList[k] = leftTmp[i]; newWordList[k] = leftTmp[i];
i++; i++;
} } else {
else
{
newWordList[k] = rightTmp[j]; newWordList[k] = rightTmp[j];
j++; j++;
} }
} }
} }
// Main function for heap sort
void Sorter::HeapSort(void) void Sorter::HeapSort(void)
{ {
auto start = std::chrono::system_clock::now();
; ;
auto end = std::chrono::system_clock::now();
sortTime = end - start;
}
// 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->allLists = 1;
return;
}
if ((tempStr == "-f") || (tempStr == "--filename"))
{
sortObj->SetFilename(arguments[i + 1]);
sortObj->fileGiven = 1;
return;
}
if ((tempStr == "-d") || (tempStr == "--default"))
{
sortObj->SetFilename("test/PERM/perm15K.txt");
sortObj->defaultOnly = 1;
return;
}
if ((tempStr == "-s") || (tempStr == "--sort-type"))
{
sortObj->sortGiven = 1;
tempStr = arguments[i + 1];
std::cout << tempStr << '\n';
if (tempStr == "insertion")
sortObj->currentType = INSERTION;
if (tempStr == "merge")
sortObj->currentType = MERGE;
if (tempStr == "heap")
sortObj->currentType = HEAP;
if (tempStr == "all")
sortObj->sortGiven = 0;
}
}
sortObj->SetFilename("test/PERM/perm15K.txt");
sortObj->defaultOnly = 1;
return;
} }

22
test/CheckSortedOutputs.sh Executable file
View File

@ -0,0 +1,22 @@
#!/bin/bash
for ((i=1;i<=10;i++));do
diff -w test/OUTPUT/IS$((i*15))K.txt test/SORTED/sorted$((i*15))K.txt &>/dev/null
if [[ $? -eq 0 ]]; then
echo "IS$((i*15))K passed"
else
echo "IS$((i*15))K failed"
fi
diff -w test/OUTPUT/MS$((i*15))K.txt test/SORTED/sorted$((i*15))K.txt &>/dev/null
if [[ $? -eq 0 ]]; then
echo "MS$((i*15))K passed"
else
echo "MS$((i*15))K failed"
fi
diff -w test/OUTPUT/HS$((i*15))K.txt test/SORTED/sorted$((i*15))K.txt &>/dev/null
if [[ $? -eq 0 ]]; then
echo "HS$((i*15))K passed"
else
echo "HS$((i*15))K failed"
fi
echo ""
done

30
test/SortTimes.txt Normal file
View File

@ -0,0 +1,30 @@
IS15 took 2.06461 s
MS15 took 0.0154898 s
HS15 took 5.4e-08 s
IS30 took 8.38467 s
MS30 took 0.0324445 s
HS30 took 7.2e-08 s
IS45 took 18.9657 s
MS45 took 0.0506499 s
HS45 took 5.3e-08 s
IS60 took 34.2814 s
MS60 took 0.069865 s
HS60 took 4.7e-08 s
IS75 took 54.3642 s
MS75 took 0.0892599 s
HS75 took 6.4e-08 s
IS90 took 80.1745 s
MS90 took 0.110413 s
HS90 took 6e-08 s
IS105 took 111.424 s
MS105 took 0.130451 s
HS105 took 6.8e-08 s
IS120 took 149.645 s
MS120 took 0.15206 s
HS120 took 5.7e-08 s
IS135 took 196.821 s
MS135 took 0.169646 s
HS135 took 6.4e-08 s
IS150 took 250.343 s
MS150 took 0.194482 s
HS150 took 1.18e-07 s