C++程序显示水平直方图。该程序的输入是非负整数,输出应该是显示每个项目频率的 ASCII 图表。例如,如果输入值为
0 1 1 4 3 1 1 0
the output is supposed to be:
4 |#
3 |#
2 |
1 |####
0 |##
\+----+----+
0 5 10
如果输入值为 x 和 y ,任何小于 x 或大于 y 的值都会导致打印 错误:值 z 超出范围 其中 z 是实际值。例如,如果说明符是 5 10,那么 4 将导致打印 错误:值 4 超出范围
目前,当使用上面的示例输入时,我得到的输出是:
1 |#
0 |-+
0 1 |#
0 |-+
0
这是我目前的代码:
#include <iostream>
#include <iomanip>
using namespace std;
const int MAX_VALUES = 501;
void readData(int array[], int& max_value) {
string input;
getline(cin, input);
istringstream iss(input);
iss >> max_value;
for (int i = 0; i < MAX_VALUES; i++) {
array[i] = 0;
}
int value;
while (iss >> value) {
array[value]++;
}
}
void histogram(int array[], int max_value) {
int max_frequency = 0;
for (int i = 0; i <= max_value; i++) {
if (array[i] > max_frequency) {
max_frequency = array[i];
}
}
for (int i = max_frequency; i >= 1; i--) {
cout << setw(2) << i << " |";
for (int j = 0; j <= max_value; j++) {
if (array[j] >= i) {
cout << "#";
} else {
cout << " ";
}
}
cout << endl;
}
cout << " 0 |";
for (int i = 0; i <= max_value; i++) {
cout << "-";
}
cout << "+" << endl;
cout << " ";
for (int i = 0; i <= max_value; i++) {
cout << setw(2) << i;
}
}
int greatestFrequency(int array[], int start_index, int stop_index) {
int max_index = start_index;
for (int i = start_index + 1; i <= stop_index; i++) {
if (array[i] > array[max_index]) {
max_index = i;
}
}
return max_index;
}
int axisWidth(int array[], int start_index, int stop_index) {
int max_value = greatestFrequency(array, start_index, stop_index);
int axis_width;
if (max_value < 10) {
axis_width = 10;
} else if (max_value % 10 == 0) {
axis_width = max_value;
} else {
axis_width = max_value + 10 - max_value % 10;
}
return axis_width;
}
void drawHorizontalAxis(int axis_width) {
int width = axis_width / 10;
cout << setw(4) << "";
for (int i = 0; i < width; i++) {
cout << setw(9) << "+";
}
cout << endl;
}
void labelHorizontalAxis(int axis_width) {
int width = axis_width / 10;
cout << setw(4) << "0";
for (int i = 1; i <= width; i++) {
if (i % 5 == 0) {
cout << setw(4) << i << setw(5) << "";
} else {
cout << setw(9) << "";
}
}
cout << endl;
}
void drawCount(int value, int quantity, int axis_width) {
cout << setw(4) << value << " |";
int num_hashes = quantity * 50 / axis_width;
for (int i = 0; i < num_hashes; i++) {
cout << "#";
}
cout << endl;
}
void writeChart(int array[], int max_value) {
int max_freq = 0;
for (int i = 0; i <= max_value; i++) {
if (array[i] > max_freq) {
max_freq = array[i];
}
}
for (int row = max_freq; row > 0; row--) {
cout << setw(2) << row << " |";
for (int col = 0; col <= max_value; col++) {
if (array[col] >= row) {
cout << "#";
} else {
cout << " ";
}
}
cout << endl;
}
cout << " 0 |";
for (int col = 0; col <= max_value; col++) {
cout << "-";
}
cout << "+\n";
cout << setw(3) << " ";
for (int col = 0; col <= max_value; col++) {
cout << col;
}
}
int main() {
int array[MAX_VALUES];
int max_value;
readData(array, max_value);
histogram(array, max_value);
writeChart(array, max_value);
return 0;
}
我不确定我遇到的问题是在我绘制图表的函数中还是在我读取输入时。
我也得到了这个伪代码:
// greatestFrequency should find, and return, index of the largest value > 0
// This assumes the array is a table of occurences; for example,
// array[10] is the number of times 10 appears in the input.
greatestFrequency(array, start_index, stop_index)
[standard code to find the maximum of an array, but looking only at
the region from start_index to stop_index]
// axisWidth: compute width of the axis needed to display the data in
// the given array (where the portion of the array being examined is
// from start_index to stop_index)
axisWidth(array, start_index, stop_index)
if greatestFrequency is less than 10
axisWidth = 10
else if greatestFrequency mod 10 is 0
axisWidth = greatestFrequency
else
axisWidth = greatestFrequency + 10 - greatestFrequency mod 10
return axisWidth
// drawHorizontalAxis should draw the horizontal axis up to,
// and including the largest increment of 10 that contains
// "axisWidth." There will be "+" tick marks every 5 values.
drawHorizontalAxis(axisWidth)
width = axisWidth
write spaces to align the first + with the vertical axis
write ----+----+ for width / 10 times
print a new line
// Label the horizontal axis, writing multiples of 5s and 10s
labelHorizontalAxis(axisWidth)
width = axisWidth
write spaces to align the first + with the vertical axis
(note the input allows up to three-digit values; if a larger number
is included, the rows may not line up nicely)
print a 0 aligned with the vertical axis
for index 0 to width
if a number is needed
print the index
if a number is NOT needed, and we are not right after a number
print a " "
(If an input value occurs more than 99 times, it is ok if the axis
labels get out of alignment)
print a new line
// drawCount takes a value and a quantity for the value and draws
// a single line for that value. For example, if the number
// is 12 and it occurs 5 times, print
// 12 |#####
drawCount(value, quantity)
print the quantity with enough spaces in front of it to line up 3-digit values
print " |"
Print "#" quantity times
Print a new line
// Add functions to read the data and call the above functions to
// print the charts