// File: farray.C // // Implementation of FArray class #include #include #include #include #include #include #include "array2.h" #include "farray.h" // "Local" functions static void CrashOnNULL(const void *ptr, char *mesg) ; static void CrashOnNULL(const void *ptr, char *mesg) { if (ptr == NULL) { cerr << mesg << endl ; exit(1) ; } } // Default constructor // FArray::FArray() : fname(NULL) // init data member fname to NULL { #ifndef NDEBUG cerr << "FArray default constructor, this = " << this << endl ; #endif } // Alternate constructor // FArray::FArray(int n, long seed /* = 0 */ ) : Array(n, seed), // init inherited members with base alt constructor fname(NULL) // init data member fname to NULL { #ifndef NDEBUG cerr << "FArray alternate constructor, this = " << this << endl ; #endif } // Destructor // FArray::~FArray() { #ifndef NDEBUG cerr << "FArray destructor, this = " << this << endl ; #endif if (fname != NULL) free(fname) ; } // Copy Constructor // FArray::FArray(const FArray& B) : Array(B), // init inherited members with base copy constructor fname(NULL) // init data member fname to NULL { #ifndef NDEBUG cerr << "FArray copy constructor, this = " << this << endl ; #endif if (fname != NULL) free(fname) ; if (B.fname != NULL) { fname = strdup(B.fname) ; } else { fname = NULL ; } } // Assignment // FArray& FArray::operator=(const FArray& B) { // self assignment? if (this == &B) return *this ; Array::operator=(B) ; // do assignment for inherited members if (fname != NULL) free(fname) ; if (B.fname != NULL) { fname = strdup(B.fname) ; CrashOnNULL(fname, "Out of memory in FArray assignment!") ; } else { fname = NULL ; } return *this ; } // Constructor from a file // FArray::FArray(const char *ifname) { int r ; struct stat sbuf ; ifstream ifile ; #ifndef NDEBUG cerr << "FArray file constructor, this = " << this << endl ; #endif // compute array size // CrashOnNULL(ifname, "Bad input file name") ; fname = strdup(ifname) ; CrashOnNULL(fname, "Can't copy input filename!") ; r = stat(ifname, &sbuf) ; if (r != 0) { cerr << "Cannot get file size for file: " << ifname << endl ; exit(1) ; } size = sbuf.st_size / sizeof(DATA) ; ifile.open(ifname) ; CrashOnNULL(ifile, "Could not open input file") ; arr = new DATA[size] ; CrashOnNULL(arr, "Out of memory in FArray file constructor!") ; // read in the data ifile.read((char *) arr, size * sizeof(DATA)) ; ifile.close() ; } // Write array as a binary file // bool FArray::write(const char* ofname) { ofstream ofile ; if (ofname == NULL) return false ; ofile.open(ofname) ; CrashOnNULL(ofname, "Could not write to output file") ; ofile.write((char *) arr, size * sizeof(DATA)) ; if (ofile.good()) { ofile.close() ; return true ; } else { ofile.close() ; return false ; } } // Perform binary search // int FArray::bsearch(DATA key) { return bsearch(key, 0, size - 1) ; } int FArray::bsearch(DATA key, int low, int high) { // Search in empty section? if (low > high) return -1 ; int mid = (low + high) / 2 ; if (arr[mid] == key) { return mid ; } else if (arr[mid] < key) { return bsearch(key, mid+1, high) ; } else { return bsearch(key, low, mid-1) ; } } void FArray::sort() { quicksort(0, size-1) ; } int FArray::partition(int low, int high) { DATA x, temp ; int i, j ; i = low - 1; j = high + 1; x = arr[low] ; while (true) { // Find an element less than x do { j = j - 1; } while (arr[j] > x) ; // Find an element greater than x do { i = i + 1; } while (arr[i] < x); // swap smaller and bigger elements, if needed // if (i < j) { temp = arr[j] ; arr[j] = arr[i] ; arr[i] = temp ; } else { return j; } } } void FArray::quicksort(int low, int high) { int q ; if (low >= high) return ; q = partition(low, high) ; assert(q < high) ; quicksort(low, q) ; quicksort(q + 1, high) ; }