首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C++中的垂直条形图

C++中的垂直条形图
EN

Stack Overflow用户
提问于 2012-04-03 14:30:52
回答 6查看 8.4K关注 0票数 2

好的,我正在尝试从文件中的值制作一个垂直条形图。下面的代码可以正常工作,并且水平打印,但是每行有一个星号,这意味着有空格(很明显)。不是在寻找一个填鸭式的答案,只是在正确的方向上推动。

代码语言:javascript
复制
using namespace std;

int main()  
{
int counter;
cout<<"Please enter a number"<< "\n";
counter=0;

char *fname = "C:/Users/Jordan Moffat/Desktop/coursework/problem2.txt";
int x;

ifstream infile(fname);

while (infile >> x)
{ 
    if (x==0 && x<=10){
        cout<<"*"<<"\t"<<"\t"<<"\t"<<"\t"<<"\t"<<"\t"<<"\t"<<"\t"<<"\t"<<"\n";
        }
    else if (x>=10 && x<=20){
        cout<<"\t"<<"*"<<"\t"<<"\t"<<"\t"<<"\t"<<"\t"<<"\t"<<"\t"<<"\t"<<"\n";
    }
    else if (x>=20 && x<=30){
        cout<<"\t"<<"\t"<<"*"<<"\t"<<"\t"<<"\t"<<"\t"<<"\t"<<"\t"<<"\t"<<"\n";
    }
    else if (x>=30 && x<=40){
        cout<<"\t"<<"\t"<<"\t"<<"*"<<"\t"<<"\t"<<"\t"<<"\t"<<"\t"<<"\t"<<"\n";
    }
    else if (x>= 40 && x<=50){
        cout<<"\t"<<"\t"<<"\t"<<"\t"<<"*"<<"\t"<<"\t"<<"\t"<<"\t"<<"\t"<<"\n";
    }
    else if (x>=50 && x<=60){
        cout<<"\t"<<"\t"<<"\t"<<"\t"<<"\t"<<"*"<<"\t"<<"\t"<<"\t"<<"\t"<<"\n";
    }
    else if (x>=60 && x<=70){
        cout<<"\t"<<"\t"<<"\t"<<"\t"<<"\t"<<"\t"<<"*"<<"\t"<<"\t"<<"\t"<<"\n";
    }
    else if (x>=70 && x<=80){
        cout<<"\t"<<"\t"<<"\t"<<"\t"<<"\t"<<"\t"<<"\t"<<"*"<<"\t"<<"\t"<<"\n";
    }
    else if (x>=80 && x<=90){
        cout<<"*"<<"\t"<<"\t"<<"\t"<<"\t"<<"\t"<<"\t"<<"\t"<<"*"<<"\t"<<"\n";
    }
    else if (x>=90 && x<=100){
        cout<<"\t"<<"\t"<<"\t"<<"\t"<<"\t"<<"\t"<<"\t"<<"\t"<<"\t"<<"*"<<"\n";

    }

}
cout<<"====================================================================================="<< "\n";   
cout<<"0-9"<<"10-19"<<"20-29"<<"30-39"<<"40-49"<<"50-59"<<"60-69"<<"70-79"<<"80-89"<<"90-100"<<"\n";
system("PAUSE");
 }
EN

回答 6

Stack Overflow用户

发布于 2012-04-03 17:45:09

你有两个问题。显然,你想要构建一个直方图,并且你想要可视化这个直方图。

直方图构建直方图的一种方法要求您预先指定柱状图的数量(均匀宽度)、最小值(包含)和最大值(非包含)。然后,您可以计算每个项目应分配到的bin的索引。

下面是一个(未经测试的)示例:

代码语言:javascript
复制
const int nbins = 10;
const double minval = .0, maxval = 100.;
std::vector<int> bins(nbins, 0);
for (double x; infile >> x; ) {
  if (x >= minval && x < maxval) {
    // note that integer rounding is probably towards zero, not towards -inf
    int idx = floor((x-minval)/(maxval-minval)*nbins);
    bins[idx]++;
  }
  else {
    // handle outlier
  }
}

可视化 this answer中描述的方法似乎是合适的。对于较大的bin计数,您可能需要一些标准化过程,即将值缩放到[0,10]或类似的范围。

看一下这个(未经测试的)示例:

代码语言:javascript
复制
const int chart_height = 10;
const int max_count = *std::max_element(bins.begin(), bins.end());
for (int current_height = chart_height; current_height > 0; --current_height) {
    for (int count : bins) {
        const int bar_height = (count*chart_height)/max_count;
        if (bar_height < current_height)
            std::cout << "     "; // we're still above the bar
        else if (bar_height == current_height)
            std::cout << "  _  "; // reached the top of the bar
        else // bar_height > current_height
            std::cout << " | | "; // now the rest of the bar ...
    }
    std::cout << '\n';
}

通过一点小技巧和格式化,您还可以对其进行扩展,以生成边界灵活的可视化效果,如this

代码语言:javascript
复制
   11 |              _______    _______                                   
      |             |       |  |       |                                  
      |             |       |  |       |                                  
      |             |       |  |       |                                  
      |             |       |  |       |   _______                        
    5 |             |       |  |       |  |       |                       
      |             |       |  |       |  |       |                       
      |             |       |  |       |  |       |              _______  
      |   _______   |       |  |       |  |       |   _______   |       | 
      |  |       |  |       |  |       |  |       |  |       |  |       | 
      +------v----------v----------v----------v----------v----------v-----
         3.7 - 4.3  4.3 - 4.9  4.9 - 5.6  5.6 - 6.2  6.2 - 6.8  6.8 - 7.4 
票数 3
EN

Stack Overflow用户

发布于 2012-04-03 14:40:47

您应该将数据读取到std::vector

使用两个嵌套循环:

  1. 循环遍历打印的行,其中第一行是"0->10",第二行是"10->20“,依此类推。

变量循环遍历vector,如果

  1. 大于(linecount-linenumber)*10,则打印" ",否则打印" "

如果您的数据从0到100,则linecount应为10。

linenumber是第一个循环中的循环变量

我不清楚您的数据在文件中是如何组织的。如果您的数据文件中没有指定每列应该有多少个*的值,那么您应该首先计算该值。

票数 1
EN

Stack Overflow用户

发布于 2012-04-03 16:27:21

要垂直制作条形图,您需要:

  1. 获取范围内的所有数字,即计算数组的最大值和最小值
  2. 在范围内进行循环,打印行,在列上留出与低于当前行的值相关联的空格。

这里我假设步骤1和2已经完成,只是显示了一些细节上的循环和注解(注意代码没有使用min和循环从0开始)

代码语言:javascript
复制
int values[] = {2,5,1,9,3}, cols = 5, max = 9;

for (int r = 0; r < max; ++r) {
    for (int c = 0; c < cols; ++c)
        cout << (r + values[c] >= max ? '*' : ' ');
    cout << endl;
}

下面是输出

代码语言:javascript
复制
   * 
   * 
   * 
   * 
 * * 
 * * 
 * **
** **
*****
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9988196

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档