// Oldham, Jeffrey D. // 2000 Mar 20 // CS3352 // Histogram That Buckets Data // This program read in data and the desired number of buckets, // determines the minimum and maximum range of values, and then // prints, for each bucket, a typical bucket entry and the number of // items in each bucket. // Implementation // Data is stored in a map, which is a class in the Standard Template // Library (http://www.sgi.com/Technology/STL/). Conceptually, a map // is a collection of pairs (key, value), sorted according to keys. // We use a map map, i.e., it contains pairs // of objects with type "inputType" and "unsigned long". "inputType" // represents the type of the input data, e.g., int, string, double. // "unsigned long" represents the number of occurrences of a particular // item. // We assume inputType is numeric so we can compute bucket sizes. typedef int inputType; // type of input data // Change this if necessary. #include #include #include // has EXIT_SUCCESS #include // has errno template // bucket type and smallest difference class bucket { public: bucket(const T bucketBegin, const T width, const unsigned long total) : bucketWidth(width), bucketEd(bucketBegin+bucketWidth), totalNuItems(total), count(0) {} void incrementEnd(void) { bucketEd += bucketWidth; count = 0; return; } T bucketEnd(void) const { return bucketEd; } bucket& operator+=(const unsigned long cnt) { count += cnt; return *this; } friend ostream& operator<<(ostream& out, const bucket & b) { return out << static_cast(b.bucketEd-Teps - b.bucketWidth/2) << '\t' << b.count / static_cast(b.totalNuItems*b.bucketWidth) << endl; } private: const T bucketWidth; T bucketEd; const unsigned long totalNuItems; unsigned long count; }; int main(int argc, char *argv[]) { // Determine the number of buckets. unsigned long nuBuckets = 0; if (argc > 2) { cerr << argv[0] << ": [number-of-buckets]\n"; return EXIT_FAILURE; } else if (argc == 2) { errno = 0; char *tail; nuBuckets = strtoul(argv[1], &tail, 0); if (errno || *tail != '\0') { cerr << argv[0] << ": [number-of-buckets]\n"; return EXIT_FAILURE; } } // Read the data. unsigned long count = 0; map histogramMap; inputType i; while (cin >> i) { ++histogramMap[i]; // increase element i's count ++count; } // Print the results. map::const_iterator ender = histogramMap.end(); --ender; map::const_iterator pos; bucket b((*histogramMap.begin()).first, nuBuckets == 0 ? 1 : (ender->first - (*histogramMap.begin()).first + 1 /* Teps */) / static_cast(nuBuckets), count); for (pos = histogramMap.begin(); pos != histogramMap.end(); ++pos) if (pos->first >= b.bucketEnd()) { cout << b; b.incrementEnd(); b += pos->second; } else b += pos->second; cout << b; return EXIT_SUCCESS; }