Should process (at least) the following record types: integer-valued keys string
ID: 3603505 • Letter: S
Question
Should process (at least) the following record types:
integer-valued keys
string-valued keys
ordered pairs of string-valued and integer-valued keys
Provide a comparison method for each record type.
When we sort our records we will first perform replacement selection then merge.
The number of entries in the k-way tournament sort (k) will be the number of sorted runs.
Write the following statistics to a log file:
an identification of which file the (input) unsorted records are from,
an identification of which file the (output) sorted records are placed in,
the number of records that can fit in memory,
the number of records,
the number of runs,
the smallest, largest and arithmetic mean number or records in all of the runs,
A sorted file of records will be generated for each of our categories of record.
Write a program that demonstrates that your file sorter works for a sufficiently large count of records in memory.
Implement in C++ a back-to-back, dual heap, replacement selection algorithm.
Initialize: a vector to serve as the replacement selection container.
Once the vector size (defaulting to 8 fixed-size records) has been set, the vector size will be fixed at that value for its lifetime.
The vector's type should be templated.
Files:
a file to receive a sequence of sorted lists.
a file to receive the byte offsets (or RRNs) of the sequence of sorted lists.
a heap direction flag.
If TRUE, the active heap's head is on the left end, and the pending heap's head is on the right end.
Else if FALSE, the active heap's head is on the right end, and the pending heap's head is on the left end.
The default value is TRUE
While the replacement selection vector is not full:
heapify a new element (if there is one)
While there's a new element:
Pop the root of the current heap, adding it to the current sorted list.
If the new element is (for a min-heap) greater than or equal to the last element popped, push it onto the current heap
If the new element is (for a min-heap) less than the last element popped,
push it onto the pending heap
decrement the current heap size counter, and increment the pending heap size counter.
If the current heap size is zero,
terminate the current sorted list
initialize a new sorted list
toggle the heap direction flag
you will have current_heap_push(), current_heap_pop(), and pending_heap_push() methods, as they'll operate differently.
When the input is exhausted, pop the remaining elements of the active heap into the current list and then (if not empty) pop the remaining elements of the pending heap into the final list.
Finishing (consistency checks):
Verify that the count of records in the entry-sequenced file is equivalent to the count of records in the set of sorted lists file.
Verify that each sorted list is monotonically ordered.
Explanation / Answer
#include <iostream>
#include <cstdlib>
#include <string>
#include <cstring>
#include <vector>
#include <cmath>
#include <stdexcept>
#include <algorithm>
int randInt(const int lo, const int hi) {
return (rand() % std::abs(hi-lo+1)) + lo;
}
template<typename T>
void print2DVector(std::vector< std::vector<T> > values, std::string linePretext = "Subvector", int lineWidth = 10, bool verbose = true) {
int runLengthSum = 0
, numElementsSum = 0;
T val
, previousElement;
bool isSorted = true
, sortDirection = (values[0][0] < values[0][1]); //true = ascending
for (int jj = 0; jj < values.size(); jj++) {
//add pretext
if (verbose) {
std::cout << linePretext << jj << ": ";
}
runLengthSum += values[jj].size();
for (int kk = 0; kk < values[jj].size(); kk++) {
val = values[jj][kk];
//count elements
numElementsSum++;
//determine if all vectors are sorted in the same direction
if (kk == 0) {
previousElement = val;
} else if (sortDirection && previousElement > val && isSorted) {
isSorted = false;
}
if (verbose) {
//split lines
if (kk % lineWidth == 0 && kk < values[jj].size() - 1) {
std::cout << " ";
}
//output value
std::cout << val;
//add commas
if (kk != values[jj].size() - 1) {
std::cout << ',';
}
}
}
if (verbose) {
std::cout << " ";
}
}
std::cout << "Total number of elements: " << std::to_string(numElementsSum) << std::endl;
std::cout << "Average run length: " << std::to_string(runLengthSum / values.size()) << std::endl;
std::cout << "All runs are " << (isSorted ? "" : "NOT ") << "sorted!" << std::endl;
}
template <class T>
class DualHeap
{
private:
std::vector<T> _V; //holds both heaps
int current_heap_head
, current_heap_tail
, pending_heap_head
, pending_heap_tail
, capacity;
bool heapDirection //true => active heap = "fwd" heap
, sortDirection; //true => sort ascending
int realLeftHeapIndex(const int virtualIndex) {
return virtualIndex - 1;
}
int realRightHeapIndex(const int virtualIndex) {
return capacity - virtualIndex;
}
int virtualLeftHeapIndex(const int realIndex) {
return realIndex + 1;
}
int virtualRightHeapIndex(const int realIndex) {
return capacity - realIndex;
}
int virtualIndex(const int realIndex) {
if (isInLeftHeap(realIndex)) {
return virtualLeftHeapIndex(realIndex);
} else if (isInRightHeap(realIndex)) {
return virtualRightHeapIndex(realIndex);
} else {
throw std::runtime_error("index out of range (" + std::to_string(realIndex) + ')');
}
}
int realLeftHeapTailIndex() {
return (heapDirection ? realLeftHeapIndex(current_heap_tail) : realLeftHeapIndex(pending_heap_tail));
}
int realLeftHeapHeadIndex() {
return 0;
}
int realRightHeapTailIndex() {
return (heapDirection ? realRightHeapIndex(pending_heap_tail) : realRightHeapIndex(current_heap_tail));
}
int realRightHeapHeadIndex() {
return capacity - 1;
}
bool isInLeftHeap(const int realIndex) {
return (realIndex <= realLeftHeapTailIndex());
}
bool isInRightHeap(const int realIndex) {
return (realIndex >= realRightHeapTailIndex());
}
bool hasChildren(const int realParentIndex) {
if ( isInLeftHeap(realParentIndex) ) {
return ( virtualIndex(realParentIndex) * 2 <= virtualIndex(realLeftHeapTailIndex()) );
}
else if ( isInRightHeap(realParentIndex) ) {
return ( virtualIndex(realParentIndex) * 2 <= virtualIndex(realRightHeapTailIndex()) );
}
else {
return false;
}
}
int realLeftChildIndex(const int realParentIndex) {
int leftChildIndex = -1
, candidateLeftChild;
if ( isInLeftHeap(realParentIndex) ) {
candidateLeftChild = realLeftHeapIndex( virtualLeftHeapIndex(realParentIndex) * 2 );
if ( isInLeftHeap(candidateLeftChild) ) {
leftChildIndex = candidateLeftChild;
}
} else if ( isInRightHeap(realParentIndex) ) {
candidateLeftChild = realRightHeapIndex( virtualRightHeapIndex(realParentIndex) * 2 );
if ( isInRightHeap(candidateLeftChild) ) {
leftChildIndex = candidateLeftChild;
}
}
return leftChildIndex;
}
int realRightChildIndex(const int realParentIndex) {
int rightChildIndex = -1
, candidateRightChild;
if ( isInLeftHeap(realParentIndex) ) {
candidateRightChild = realLeftHeapIndex( virtualLeftHeapIndex(realParentIndex) * 2 + 1 );
if ( isInLeftHeap(candidateRightChild) ) {
rightChildIndex = candidateRightChild;
}
} else if ( isInRightHeap(realParentIndex) ) {
candidateRightChild = realRightHeapIndex( virtualRightHeapIndex(realParentIndex) * 2 + 1 );
if ( isInRightHeap(candidateRightChild) ) {
rightChildIndex = candidateRightChild;
}
}
return rightChildIndex;
}
int realParentIndex(const int realChildIndex) {
int parentIndex = -1;
if (isInLeftHeap(realChildIndex) && virtualLeftHeapIndex(realChildIndex) != 1) {
parentIndex = realLeftHeapIndex(virtualLeftHeapIndex(realChildIndex) / 2);
}
else if (isInRightHeap(realChildIndex) && virtualRightHeapIndex(realChildIndex) != 1) {
parentIndex = realRightHeapIndex(virtualRightHeapIndex(realChildIndex) / 2);
}
return parentIndex;
}
void swapHeaps() {
int temp;
//swap heads
temp = current_heap_head;
current_heap_head = pending_heap_head;
pending_heap_head = temp;
//swap tails
temp = current_heap_tail;
current_heap_tail = pending_heap_tail;
pending_heap_tail = temp;
}
void swapByRealIndex(const int realIndex1, const int realIndex2) {
T temp = _V[realIndex1];
_V[realIndex1] = _V[realIndex2];
_V[realIndex2] = temp;
}
bool shouldSwapByRealIndex(const int realChildIndex, const int realParentIndex) {
if (sortDirection) {
//minheap
return _V[realChildIndex] < _V[realParentIndex];
} else {
//maxheap
return _V[realChildIndex] > _V[realParentIndex];
}
}
void heapifyUpByRealIndex(const int realIndex) {
int childIndex = realIndex
, parentIndex = realParentIndex(childIndex);
if (parentIndex != -1) {
if (shouldSwapByRealIndex(childIndex, parentIndex)) {
swapByRealIndex(childIndex, parentIndex);
heapifyUpByRealIndex(parentIndex);
}
}
}
void heapifyDownByRealIndex(const int realIndex) {
if ( hasChildren(realIndex) ) {
int parentIndex = realIndex
, leftChildRealIndex = realLeftChildIndex(realIndex)
, rightChildRealIndex = realRightChildIndex(realIndex)
, potentialSwapIndex = -1;
if (leftChildRealIndex != -1) {
if (rightChildRealIndex != -1) {
if (sortDirection) {
potentialSwapIndex = (_V[leftChildRealIndex] < _V[rightChildRealIndex] ? leftChildRealIndex : rightChildRealIndex);
} else {
potentialSwapIndex = (_V[leftChildRealIndex] > _V[rightChildRealIndex] ? leftChildRealIndex : rightChildRealIndex);
}
} else {
potentialSwapIndex = leftChildRealIndex;
}
if (shouldSwapByRealIndex(potentialSwapIndex, parentIndex)) {
swapByRealIndex(potentialSwapIndex, parentIndex);
heapifyDownByRealIndex(potentialSwapIndex);
}
} else {
//no children: done
}
} else {
//no children: done
}
}
public:
DualHeap(const int totalcapacity, const bool _sortDirection = true, const bool _heapDirection = true) {
//set the total combined capacity of both heaps
capacity = totalcapacity;
_V.reserve(capacity);
//initialize to zeroes (arbitrary)
// for (int ii = 0; ii < capacity; ii++) {
// _V[ii] = 0;
// }
//set initial virtual head and tail indices
current_heap_head = pending_heap_head = 1;
current_heap_tail = pending_heap_tail = 0;
sortDirection = _sortDirection; //true = right
heapDirection = _heapDirection; //left heap first = right
}
int get_size() {
return current_heap_size() + pending_heap_size();
}
int get_capacity() {
return capacity;
}
int current_heap_size() {
return (current_heap_tail == 0 ? 0 : std::abs(current_heap_head - current_heap_tail) + 1);
}
int pending_heap_size() {
return (pending_heap_tail == 0 ? 0 : std::abs(pending_heap_head - pending_heap_tail) + 1);
}
void current_heap_push(const T element) {
if ( (current_heap_size() + pending_heap_size()) < capacity ) {
int realTailIndex = -1;
//increase current heap size by 1
current_heap_tail += 1;
if (heapDirection) {// active heap = left
realTailIndex = realLeftHeapIndex(current_heap_tail);
} else { //active heap = right
realTailIndex = realRightHeapIndex(current_heap_tail);
}
//store new element at the left heap's tail
_V[realTailIndex] = element;
//heapify the left heap
heapifyUpByRealIndex(realTailIndex);
}
}
void pending_heap_push(const T element) {
reverse_direction();
current_heap_push(element);
reverse_direction();
}
T current_heap_pop() {
if (current_heap_size() > 0){
T returnElement;
if (heapDirection) { //left heap is current
// pop head
returnElement = _V[realLeftHeapIndex(current_heap_head)];
//replace with tail
_V[realLeftHeapIndex(current_heap_head)] = _V[realLeftHeapIndex(current_heap_tail)];
//reduce size by 1
current_heap_tail -= 1;
//heapify down
heapifyDownByRealIndex(realLeftHeapIndex(current_heap_head));
} else {
// pop head
returnElement = _V[realRightHeapIndex(current_heap_head)];
// replace with tail
_V[realRightHeapIndex(current_heap_head)] = _V[realRightHeapIndex(current_heap_tail)];
// reduce size by 1
current_heap_tail -= 1;
//heapify down
heapifyDownByRealIndex(realRightHeapIndex(current_heap_head));
}
//return head
return returnElement;
} else {
throw std::runtime_error("Empty heap!");
}
}
T pending_heap_pop() {
T returnElement;
reverse_direction();
returnElement = current_heap_pop();
reverse_direction();
return (returnElement);
}
std::string stringify() {
int leftHeapSize = (heapDirection ? current_heap_size() : pending_heap_size());
std::string returnString = "";
for (int ii = 0; ii < capacity; ii++) {
if (
ii == realRightHeapIndex(heapDirection ? pending_heap_tail : current_heap_tail) ||
ii == realLeftHeapIndex(heapDirection ? current_heap_tail : pending_heap_tail) + 1
) {
returnString += " | ";
} else {
if (ii > 0) {
returnString += ", ";
}
}
returnString += ' ' + _V[ii];
}
return returnString;
}
void reverse_direction() {
heapDirection = !heapDirection;
swapHeaps();
}
}; //DualHeap
template <class T>
class ReplacementSelectionSort
{
private:
public:
static std::vector< std::vector<T> > sort(
const std::vector<T> vectorToBeSorted,
const int heapSize = 10,
const bool sortDirection = true,
const bool DEBUG = false
)
{
if (heapSize < 1) {
throw std::runtime_error("Heap must be of size 1 or greater");
}
std::vector< std::vector<T> > *returnVector = new std::vector< std::vector<T> >;
DualHeap<T> *myDualHeap = new DualHeap<T>( heapSize, sortDirection );
//While the replecement selection vector is not full, heapify a new element
T el;
int totalCapacity = myDualHeap->get_capacity();
int nextItemToSort;
if(DEBUG){std::cout << "adding: ";}
for (int ii = 0; ii < totalCapacity && ii < vectorToBeSorted.size(); ii++) {
el = vectorToBeSorted[ii];
if(DEBUG){
std::cout << el;
if (ii < totalCapacity - 1) {
std::cout << ",";
}
}
myDualHeap->current_heap_push( el );
nextItemToSort = ii + 1;
}
if (DEBUG) {
std::cout << std::endl;
std::cout << myDualHeap->stringify() << std::endl;
}
int currentList = 0;
T lastElementPopped
, nextElement;
std::vector<T> *row = new std::vector<T>;
while (nextItemToSort < vectorToBeSorted.size() || myDualHeap->get_size() > 0) {
if(DEBUG){std::cout << " heap: " << myDualHeap->stringify() << std::endl;}
lastElementPopped = myDualHeap->current_heap_pop();
if(DEBUG){std::cout << "pop: " << lastElementPopped << std::endl;}
row->push_back( lastElementPopped );
if ( nextItemToSort < vectorToBeSorted.size() ) {
nextElement = vectorToBeSorted[nextItemToSort];
nextItemToSort++;
if(DEBUG){std::cout << "add: " << nextElement << std::endl;}
if (sortDirection) {
if (nextElement < lastElementPopped) {
myDualHeap->pending_heap_push( nextElement );
} else {
myDualHeap->current_heap_push( nextElement );
}
} else {
if (nextElement > lastElementPopped) {
myDualHeap->pending_heap_push( nextElement );
} else {
myDualHeap->current_heap_push( nextElement );
}
}
}
if (myDualHeap->current_heap_size() == 0) {
//std::cout << "Reversing Direction..." << std::endl;
myDualHeap->reverse_direction();
currentList++;
returnVector->push_back( *row );
row = new std::vector<T>;
}
}
delete myDualHeap;
return *returnVector;
}
}; //ReplacementSelectionSort
template <typename T>
void DualHeapTest() {
std::cout << "Beginning DualHeap exercise/test" << std::endl;
std::cout << "Creating DualHeap(6)" << std::endl;
DualHeap<T> *myDualHeap = new DualHeap<T>(6, true);
std::cout << myDualHeap->stringify() << std::endl;
std::cout << "pending_heap_push(11): ";
myDualHeap->pending_heap_push(11);
std::cout << myDualHeap->stringify() << std::endl;
std::cout << "pending_heap_push(12): ";
myDualHeap->pending_heap_push(12);
std::cout << myDualHeap->stringify() << std::endl;
std::cout << "pending_heap_push(10): ";
myDualHeap->pending_heap_push(10);
std::cout << myDualHeap->stringify() << std::endl;
std::cout << "current_heap_push(4): ";
myDualHeap->current_heap_push(4);
std::cout << myDualHeap->stringify() << std::endl;
std::cout << "current_heap_push(5): ";
myDualHeap->current_heap_push(5);
std::cout << myDualHeap->stringify() << std::endl;
std::cout << "current_heap_push(3): ";
myDualHeap->current_heap_push(3);
std::cout << myDualHeap->stringify() << std::endl;
std::cout << "current_heap_push(9): ";
myDualHeap->pending_heap_push(9);
std::cout << myDualHeap->stringify() << std::endl;
std::cout << "current_heap_push(2): ";
myDualHeap->current_heap_push(2);
std::cout << myDualHeap->stringify() << std::endl;
std::cout << "pending_heap_pop() => " << myDualHeap->pending_heap_pop() << ": " << myDualHeap->stringify() << std::endl;
std::cout << "current_heap_pop() => " << myDualHeap->current_heap_pop() << ": " << myDualHeap->stringify() << std::endl;
std::cout << "pending_heap_pop() => " << myDualHeap->pending_heap_pop() << ": " << myDualHeap->stringify() << std::endl;
std::cout << "current_heap_pop() => " << myDualHeap->current_heap_pop() << ": " << myDualHeap->stringify() << std::endl;
std::cout << "pending_heap_pop() => " << myDualHeap->pending_heap_pop() << ": " << myDualHeap->stringify() << std::endl;
std::cout << "current_heap_pop() => " << myDualHeap->current_heap_pop() << ": " << myDualHeap->stringify() << std::endl;
try {
std::cout << "(!) pending_heap_pop(): " << myDualHeap->pending_heap_pop() << std::endl;
}
catch (std::runtime_error& e) {
std::cout << e.what() << std::endl;
}
delete myDualHeap;
myDualHeap = nullptr;
}
template <typename T>
void replacementSelectionSortTest(const std::vector<T> SAMPLE_DATA,
const int HEAP_SIZE,
const bool verbose = false,
const bool ultra_verbose = false) {
std::vector< std::vector<T> > results = ReplacementSelectionSort<T>::sort( SAMPLE_DATA, HEAP_SIZE, true, false );
std::cout << "Least to Greatest: " << std::endl;
print2DVector(results, "Run #", 10, verbose);
results = ReplacementSelectionSort<T>::sort( SAMPLE_DATA, HEAP_SIZE, false, false );
std::cout << "Greatest to Least: " << std::endl;
print2DVector(results, "Run #", 10, verbose);
}
template <typename T>
void replacementSelectionSortTest(const int SAMPLE_SIZE,
const int HEAP_SIZE,
const int SAMPLE_MIN,
const int SAMPLE_MAX,
const int SAMPLE_OFFSET,
const bool verbose = false,
const bool partialSort = false,
const bool fullSort = false,
const bool sortDirection = true,
const bool ultra_verbose = false)
{
std::vector<T> sampleData;
T val;
//generate sample data
for (int ii = 0; ii < SAMPLE_SIZE; ii++) {
val = SAMPLE_OFFSET + randInt(SAMPLE_MIN, SAMPLE_MAX);
sampleData.push_back(val);
}
//sort if flagged
if (fullSort) {
std::sort (sampleData.begin(), sampleData.end());
if (!sortDirection) {
std::reverse(sampleData.begin(), sampleData.end());
}
} else if (partialSort) {
std::partial_sort (sampleData.begin(), (sampleData.begin() + sampleData.size()/2), sampleData.end());
if (!sortDirection) {
std::reverse(sampleData.begin(), sampleData.end());
}
}
//show contents
if (ultra_verbose) {
for (int jj = 0; jj < sampleData.size(); jj++) {
std::cout << sampleData[jj];
if (jj < SAMPLE_SIZE - 1) {
std::cout << ",";
}
}
std::cout << std::endl;
}
replacementSelectionSortTest<T>(sampleData, HEAP_SIZE, verbose, ultra_verbose);
}
char* getArgVal(char* arg) {
return std::strtok(NULL, std::strtok(arg, "="));
}
//sample data item type
enum ItemType
{
INT,
CHAR,
STRING
};
int main(int argc, char* argv[]) {
std::vector<std::string> sampleData;
sampleData.push_back("apples");
sampleData.push_back("oranges");
sampleData.push_back("bananas");
sampleData.push_back("cucumbers");
sampleData.push_back("ducks");
sampleData.push_back("iguanas");
sampleData.push_back("zebras");
sampleData.push_back("porcupines");
sampleData.push_back("quills");
sampleData.push_back("fingers");
sampleData.push_back("toes");
sampleData.push_back("bows");
sampleData.push_back("arrows");
sampleData.push_back("swords");
sampleData.push_back("helmets");
sampleData.push_back("cheese");
int SAMPLE_SIZE = 100
, HEAP_SIZE = 10
, SAMPLE_MIN = 0
, SAMPLE_MAX = 10
, SAMPLE_OFFSET = 0;
ItemType type;
bool verbose = false
, ultra_verbose = false
, PARTIAL_SORT = false
, FULL_SORT = false
, SORT_DIRECTION = true;
//experimenting with command line arguments
for (int ii = 1; ii < argc; ii++) {
//run test with integers
if (!std::strncmp(argv[ii], "-int", 4)) {
type = INT;
}
//run test with chars
if (!std::strncmp(argv[ii], "-char", 5)) {
type = CHAR;
}
if (!std::strncmp(argv[ii], "-string", 7)) {
type = STRING;
}
if (!std::strncmp(argv[ii], "-v", 2)) {
verbose = true;
}
if (!std::strncmp(argv[ii], "-vv", 3)) {
ultra_verbose = true;
verbose = true;
}
if (!std::strncmp(argv[ii], "-sort", 5)) {
FULL_SORT = true;
PARTIAL_SORT = false;
}
if (!std::strncmp(argv[ii], "-sortpartial", 12)) {
FULL_SORT = false;
PARTIAL_SORT = true;
}
if (!std::strncmp(argv[ii], "-fwd", 4) ||
!std::strncmp(argv[ii], "-forward", 8)) {
SORT_DIRECTION = true;
}
if (!std::strncmp(argv[ii], "-rev", 4) ||
!std::strncmp(argv[ii], "-reverse", 8)) {
SORT_DIRECTION = false;
}
if (!std::strncmp(argv[ii], "-samplesize=", 12) || !std::strncmp(argv[ii], "-sample=", 8)) {
SAMPLE_SIZE = std::atoi(getArgVal(argv[ii]));
}
if (!std::strncmp(argv[ii], "-heapsize=", 10) || !std::strncmp(argv[ii], "-heap=", 6)) {
HEAP_SIZE = std::atoi(getArgVal(argv[ii]));
}
if (!std::strncmp(argv[ii], "-samplemin=", 11) || !std::strncmp(argv[ii], "-min=", 5)) {
SAMPLE_MIN = std::atoi(getArgVal(argv[ii]));
}
if (!std::strncmp(argv[ii], "-samplemax=", 11) || !std::strncmp(argv[ii], "-max=", 5)) {
SAMPLE_MAX = std::atoi(getArgVal(argv[ii]));
}
if (!std::strncmp(argv[ii], "-sampleoffset=", 14) || !std::strncmp(argv[ii], "-off=", 5)) {
SAMPLE_OFFSET = std::atoi(getArgVal(argv[ii]));
}
}
if (argc == 1) {
std::cout << " Please specify a type (-int or -char) ";
} else {
if (type == INT) {
std::cout << " Running with sample size:" << SAMPLE_SIZE << ", ";
std::cout << "heap size:" << HEAP_SIZE << ", ";
std::cout << "minimum sample size:" << SAMPLE_MIN << ", ";
std::cout << "maximum sample size:" << SAMPLE_MAX << ", ";
std::cout << "sample offset:" << SAMPLE_OFFSET << " ";
replacementSelectionSortTest<int>(
SAMPLE_SIZE,
HEAP_SIZE,
SAMPLE_MIN,
SAMPLE_MAX,
SAMPLE_OFFSET,
verbose,
PARTIAL_SORT,
FULL_SORT,
SORT_DIRECTION,
ultra_verbose);
}
if (type == CHAR) {
if (SAMPLE_OFFSET == 0 && SAMPLE_MIN == 0) { SAMPLE_OFFSET = 65; SAMPLE_MAX = 25; };
std::cout << " Running with sample size:" << SAMPLE_SIZE << ", ";
std::cout << "heap size:" << HEAP_SIZE << ", ";
std::cout << "minimum sample:" << (char)(SAMPLE_OFFSET + SAMPLE_MIN) << ", ";
std::cout << "maximum sample:" << (char)(SAMPLE_OFFSET + SAMPLE_MAX) << ", ";
std::cout << "(sample offset:" << SAMPLE_OFFSET << ") ";
replacementSelectionSortTest<char>(
SAMPLE_SIZE,
HEAP_SIZE,
SAMPLE_MIN,
SAMPLE_MAX,
SAMPLE_OFFSET,
verbose,
PARTIAL_SORT,
FULL_SORT,
SORT_DIRECTION,
ultra_verbose);
}
if (type == STRING) {
std::cout << " Running with arbitrary string data" << std::endl;
replacementSelectionSortTest<std::string>(sampleData, 10, true, true);
}
}
return 0;
}
Related Questions
drjack9650@gmail.com
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.