// C++ system include files #include #include #include using namespace std; // C library system include files #include #include // Local interface include files #include "utility.h" #include "sort.h" enum sortType {NOSORT, INSERTION, MERGE}; const int NUMSORT = 3; const string sortNames[NUMSORT] = {"NOSORT", "INSERTION", "MERGE"}; const char * optString = "n:m:i:f:o:tvxc:s:h?"; const string stdinout[2] = {"cin", "cout"}; /** * Global Parameters governing the overall operation of the sorts program */ struct globals { int N; ///< Input length int max; ///< Max value on randomly generated input sequence int seed; ///< Random seed value for ramdomly generated input sequence bool streamInput; ///< Input from a streamp; otherwise must be random istream *sin; ///< Pointer to input stream (file or cin or NULL) string inFileName; ///< Either cin or file name for input stream bool streamOutput; ///< Output to a streamp; otherwise no sorted sequence gen'd ostream *sout; ///< Pointer to output stream (file or cout or NULL) string outFileName; ///< Either cout or file name for output stream bool timing; ///< Generate timing information? bool verbose; ///< Generate diagnostic print statements to stderr? bool check; int count; ///< Number of times to execute sort algorithm string sortName; ///< Name of sort to perform sortType sort; ///< Enum of sort type string command; ///< argv[0] used for program invocation }; /** * Function to print usage message and exit */ void print_usage( struct globals &Args ///< Reference parameter for Global Program Parameters ) { cerr << "Usage: " << Args.command << " -n -m -i -f -o -t -c -s -h" << endl; exit(EXIT_FAILURE); } /** * Function to set of default values for global program parameters */ void initArgs( struct globals &Args ///< Reference parameter for Global Program Parameters ) { Args.N = 100; Args.max = -1; Args.seed = -1; Args.sin = NULL; Args.streamInput = false; Args.sout = NULL; Args.streamOutput = false; Args.timing = false; Args.verbose = false; Args.check = false; Args.count = 1; Args.sortName.assign("NOSORT"); Args.sort = NOSORT; } /** * Utility function to print to an output stream the global program parameters */ void printArgs( struct globals &Args, ///< Reference parameter for Global Program Parameters ostream &out ///< Ref parameter for output stream ) { out << "N: " << Args.N << endl; out << "max: " << Args.max << endl; out << "seed: " << Args.seed << endl; if (Args.streamInput) { out << "In source: " << Args.inFileName << endl; } else { out << "In source: random" << endl; } if (Args.streamOutput) { out << "Out dest: " << Args.outFileName << endl; } else { out << "Out dest: none" << endl; } if (Args.timing) { out << "Timing: TRUE" << endl; } else { out << "Timing: FALSE" << endl; } if (Args.verbose) { out << "Verbose: TRUE" << endl; } else { out << "Verbose: FALSE" << endl; } if (Args.check) { out << "Check: TRUE" << endl; } else { out << "Check: FALSE" << endl; } out << "Rep Count: " << Args.count << endl; out << "Sort Type: " << Args.sortName << endl; } /** * Iterate over command line arguments, setting global program parameters */ void processCommandLine( int &argc, ///< ref param for argument count char **argv, ///< vector of argument strings struct globals &Args ///< ref param for global program params ) { int opt = 0; opt = getopt(argc, argv, optString); while (opt != -1) { switch (opt) { case 'n': sscanf(optarg, "%d", &(Args.N)); break; case 'm': sscanf(optarg, "%d", &(Args.max)); break; case 'i': sscanf(optarg, "%d", &(Args.seed)); break; case 'f': Args.inFileName.assign(optarg); Args.streamInput = true; break; case 'o': Args.outFileName.assign(optarg); Args.streamOutput = true; break; case 't': Args.timing = !Args.timing; break; case 'v': Args.verbose = !Args.verbose; break; case 'x': Args.check = !Args.check; break; case 'c': sscanf(optarg, "%d", &(Args.count)); break; case 's': Args.sortName.assign(optarg); break; case 'h': default: print_usage(Args); break; } opt = getopt(argc, argv, optString); } if (Args.streamOutput) { if (Args.outFileName.compare(stdinout[1]) == 0) { Args.sout = &cout; } else { Args.sout = new ofstream(Args.outFileName.c_str()); } if (!(*(Args.sout))) { cerr << "Error opening output file" << endl; printArgs(Args,cerr); print_usage(Args); } } if (Args.streamInput) { if (Args.inFileName.compare(stdinout[0]) == 0) { Args.sin = &cin; } else { Args.sin = new ifstream(Args.inFileName.c_str()); } if (!(*(Args.sin))) { cerr << "Error opening input file" << endl; printArgs(Args,cerr); print_usage(Args); } } for (int i=0; i < NUMSORT; i++) { if (Args.sortName.compare(sortNames[i]) == 0) { Args.sort = (sortType)i; break; } } } int main(int argc, char **argv) { struct globals G; int * inarray; int * A; int retval; double startTime; double endTime; initArgs(G); G.command.assign(argv[0]); processCommandLine(argc, argv, G); if (G.verbose) { printArgs(G, cerr); } if (!G.streamInput) { if (G.max == -1) { G.max = 2 * G.N; } retval = randomintarray(G.N, G.max, inarray); if (retval < 0) { cerr << "Error generating array" << endl; exit(EXIT_FAILURE); } } else { retval = readintarray(G.sin, G.N, G.max, inarray); if (retval < 0) { cerr << "Error generating array" << endl; exit(EXIT_FAILURE); } } A = new int[G.N]; double sumTime = 0.0; for (int i=0; i 1) { cerr << G.count << ", " << sumTime/G.count << endl; } if (G.check) { bool sorted = true; int i = 0; while (sorted && i < G.N - 1) { if (A[i] > A[i+1]) { sorted = false; } i += 1; } if (!sorted) { cerr << "FAILURE of " << G.sortName << endl; } else { if (G.verbose) { cerr << "SUCCESS of " << G.sortName << endl; } } } if (G.streamOutput) { *G.sout << G.N << endl; for (int i=0; i < G.N; i++) { *G.sout << A[i] << " " << endl; } } }