This question already has an answer here:
This is for a programming assignment for my Data Structures class, and the program is not complete. I have been testing it in pieces while implementing though and up until now everything was working. I have researched this quite a bit, and all of the answers I have found don't seem to be the problem with my specific situation. My exact errors are: "Undefined reference to 'void Sorter::bubbleSort(int*, int)" "Undefined reference to 'void Sorter::mergeSort(int*, int, int)"
The weird thing is, I originally had included "Sorter.cpp" instead of "Sorter.h" in my PA04.cpp file. At that point things worked fine. I then added the report() function to log some things while sorting, once I tried to compile with that I would get the following: "multiple definition of 'Sorter::report(std::__cxx11::basic_string, std::allocator >, long, long)'"
Researching that I found out that I should be including Sorter.h instead of Sorter.cpp in my PA04.cpp file, However once I change that I get the undefined reference errors above...
Not sure what to do to fix either of the errors. Any help or insight will be greatly appreciated, in addition to any criticism of my code since I know I'm probably not coding in the best way to begin with.
PA04.cpp
#include <iostream>
#include <random>
#include <fstream>
#include "Sorter.cpp"
void createUnsortedData(int size);
std::string getFileName(int size, int i);
void readFileIntoArray(std::string file);
void printSorted(int * array, std::string file, int q);
int *values;
const int MIN_SIZE = 10;
const int MAX_SIZE = 1000;
int main()
{
std::string fileName;
createUnsortedData(MIN_SIZE);
Sorter sort;
// Do this outside loop 3 times, used to load quantity value helping to specify which file should be sorted
for (int n = MIN_SIZE; n <= MAX_SIZE; n*=10)
{
sort.MAX_SIZE = n;
// Do this inside loop 10 times since there are 10 different files within each quantity category to be sorted
for (int j = 0; j < 10; j++)
{
fileName = "./UNSORTED/" + getFileName(n, j); // Specify the file to be sorted
values = new int[n];
readFileIntoArray(fileName); // Read the randomized file into values array
sort.bubbleSort(values, n); // Sort with bubble sort
readFileIntoArray(fileName); // Reset array to unsorted state
sort.mergeSort(values, 0, n - 1); // Sort with merge sort
//readFileIntoArray(fileName); // Reset array to unsorted state
//Sorter::radixSort(values, quantity); // Sort with radix sort
fileName = "./SORTED/" + getFileName(n, j);
printSorted(values, fileName, n);
delete [] values;
}
}
}
/**
* @brief Creates 30 files of random integers in the range of 1 - 1000000
*
* @pre A pre defined size is passed to the function
*
* @post 30 files of randomized integers are created
*/
void createUnsortedData(int size)
{
std::random_device randNum;
std::mt19937 gen(randNum());
std::uniform_int_distribution<> dis(1, 1000001);
std::string fileName;
for (int i = 0; i < 10; i++)
{
fileName = "./UNSORTED/" + getFileName(size, i);
std::ofstream fout(fileName.c_str());
for(int j = 0; j < size; j++)
{
unsigned long x;
x = dis(gen);
fout << x <<std::endl;
}
fout.close();
}
if(size < MAX_SIZE)
createUnsortedData((size * 10));
}
/**
* @brief Gets a filename
*
* @pre A size and file number i are passed to the function
*
* @post The file name of the ith file containing the number of integers specified by size is returned
*/
std::string getFileName(int size, int i)
{
std::string file;
std::string fileNumber = std::to_string(i+1);
if(i<9)
fileNumber = "0" + fileNumber;
file = std::to_string(size) + "RandomNumbers_" + fileNumber + ".txt";
return file;
}
void readFileIntoArray(std::string file)
{
int i = 0;
std::string line;
std::ifstream fin(file.c_str());
if (fin.is_open())
{
while (getline(fin, line))
{
if (line != "")
{
values[i] = std::stoi(line);
i++;
}
}
}
fin.close();
}
void printSorted(int * array, std::string file, int q)
{
std::ofstream fout(file);
for(int i = 0; i < q; i++)
{
fout << array[i] << std::endl;
}
fout.close();
}
Sorter.cpp
#include <string>
#include <ctime>
#include <iomanip>
#include "Sorter.h"
template <class ItemType>
void Sorter::bubbleSort(ItemType valueArray[], int n)
{
time(&startTime);
bool sorted = false;
int pass = 1;
while (!sorted && (pass < n))
{
// At this point, valueArray[n+1-pass...n-1] is sorted
// and all of its entries are > the entries in valueArray[0...n-pass]
sorted = true; // Assume sorted
for (int index = 0; index < n - pass; index++)
{
// At this point, all entries in valueArray[0...index-1]
// are <= valueArray[index]
int nextIndex = index + 1;
if (valueArray[index] > valueArray[nextIndex])
{
// Exchange entries
std::swap(valueArray[index], valueArray[nextIndex]);
sorted = false; // Signal exchange
} // end if
} // end for
// Assertion: valueArray[0...n-pass-1] < valueArray[n-pass]
pass++;
} // end while
time(&finishTime);
//report("Bubble sort", startTime, finishTime);
} // end bubbleSort
template <class ItemType>
void Sorter::merge(ItemType valueArray[], int first, int mid, int last)
{
ItemType tempArray[MAX_SIZE]; // Temporary array
// Initialize local indices to indicate the subarrays
int first1 = first; // Beginning of first subarray
int last1 = mid; // End of first subarray
int first2 = mid + 1; // Beginning of second subarray
int last2 = last; // End of second subarray
// While both subarrays are not empty, copy the
// smaller item into the temporary array
int index = first1;
while ((first1 <= last1) && (first2 <= last2))
{
// At this point, tempArray[first...index-1] is in order
if (valueArray[first1] <= valueArray[first2])
{
tempArray[index] = valueArray[first1];
first1++;
}
else
{
tempArray[index] = valueArray[first2];
first2++;
} // end if
index++;
} // end while
// Finish off first subarray if necessary
while (first1 <= last1)
{
// At this point, tempArray[first...index-1] is in order
tempArray[index] = valueArray[first1];
first1++;
index++;
} // end while
// Finish off the second subarray if necessary
while (first2 <= last2)
{
// At this point, tempArray[first...index-1] is in order
tempArray[index] = valueArray[first2];
first2++;
index++;
} // end while
// Copy the result back into the original array
for (index = first; index <= last; index++)
valueArray[index] = tempArray[index];
} // end merge
template <class ItemType>
void Sorter::mergeSort(ItemType valueArray[], int first, int last)
{
time(&startTime);
if (first < last)
{
// Sort each half
int mid = first + (last - first) / 2; // index of midpoint
// Sort left half valueArray[first...mid]
mergeSort(valueArray, first, mid);
// Sort right half valueArray[mid+1...last];
mergeSort(valueArray, mid + 1, last);
// Merge the two halves
merge(valueArray, first, mid, last);
} // end if
time(&finishTime);
//report("Merge sort", startTime, finishTime);
} // end mergeSort
template <class ItemType>
void Sorter::radixSort(ItemType valueArray[], int n)
{
}
void Sorter::report(std::string sortName, time_t start, time_t finish)
{
struct tm * begin;
struct tm * end;
std::string completionTime = std::to_string(difftime(finish, start)) + " seconds";
char buffer [80];
begin = localtime (&start);
end = localtime (&finish);
logOutput.open("sort.log.txt", std::ofstream::app);
logOutput << std::setw(25) << sortName;
strftime (buffer,80,"%X",begin);
logOutput << std::setw(25) << buffer;
strftime (buffer,80,"%X",end);
logOutput << std::setw(25) << buffer;
logOutput << std::setw(25) << completionTime;
logOutput << std::setw(25) << swapCount;
logOutput << std::setw(25) << comparisonCount << std::endl;
logOutput.close();
// Reset swap and comparison counters for next use
swapCount = 0;
comparisonCount = 0;
}
Sorter.h
#include <fstream>
/**
* @file Sorter.h
*
* @brief Specification file for Sorter
*
* @author Adrian Davis
*
* @details Specifies all member functions of the Sorter class
*
* @version 1.00
*
* @note All member functions are declared static and therefore can be called without instantiating an object of this class
*/
class Sorter
{
public:
int comparisonCount = 0;
int swapCount = 0;
int MAX_SIZE = 0;
time_t startTime;
time_t finishTime;
std::ofstream logOutput;
/**
* @brief Bubble sort
*
* @pre An unsorted file of integers is passed to the function
*
* @post The integers in the file are sorted and output to a sorted file
*/
template <class ItemType>
void bubbleSort(ItemType valueArray[], int n);
/**
* @brief Merges two halves of an array
*
* @pre An unsorted file of integers is passed to the function
*
* @post The integers in the file are sorted and output to a sorted file
*/
template <class ItemType>
void merge(ItemType valueArray[], int first, int mid, int last);
/**
* @brief Merge sort
*
* @pre An unsorted file of integers is passed to the function
*
* @post The integers in the file are sorted and output to a sorted file
*/
template <class ItemType>
void mergeSort(ItemType valueArray[], int first, int last);
/**
* @brief Radix sort
*
* @pre An unsorted file of integers is passed to the function
*
* @post The integers in the file are sorted and output to a sorted file
*/
template <class ItemType>
void radixSort(ItemType valueArray[], int n);
void report(std::string sortName, time_t start, time_t finish);
};
and my makefile looks like this:
CC = g++
DEBUG = -g
CFLAGS = -Wall -c $(DEBUG) -g
LFLAGS = -Wall $(DEBUG)
SortTest : Sorter.o PA04.o
$(CC) $(LFLAGS) -std=c++11 -o SortTest Sorter.o PA04.o
Sorter.o : Sorter.cpp Sorter.h
$(CC) $(CFLAGS) -std=c++11 Sorter.cpp
PA04.o : PA04.cpp Sorter.h
$(CC) $(CFLAGS) -std=c++11 PA04.cpp
clean :
rm *.o SortTest
rm -rf UNSORTED/*
rm -rf SORTED/*
Aucun commentaire:
Enregistrer un commentaire