2012-04-03 86 views
1

好吧,我正在嘗試從文件中的值製作垂直條形圖。下面的代碼工作,到一個點,並水平打印,但每行一個星號,這意味着有空格(顯然)。不尋找勺子的答案,只是在正確的方向推動。C++中的垂直條形圖

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"); 
} 
+1

您必須翻轉您的顯示器(或您的頭部)才能看到豎線爲豎線 – CapelliC 2012-04-03 06:40:10

回答

1

你應該閱讀你的數據到std::vector

使用兩個嵌套的循環:

  1. 循環線路上打印,其中第一行是 「0-> 10」,第二行「10 - > 20「等
  2. 如果變量大於(linecount-linenumber)*10,則打印" ",否則打印"*"

如果你的數據從0到100,linecount應該是10

行號是從第一循環的循環變量

你的數據是如何在文件中組織這是我不太清楚。如果您的數據文件不包含說明每列應具有多少個值的值,則應首先計算該值。

+0

該文件只是一個數字列表,每行1個。該文件本質上只是一個整數列表,這使得定義類型變得更加容易。 – 2012-04-03 06:56:02

+0

我假設如果我循環遍歷每一行(即打印0到10之間的所有數字的那一行),我需要某種形式的增量計數器,然後我將它打印出那在星號? – 2012-04-03 07:03:04

+0

我試圖詳細說明我的建議,但沒有給你解決方案 – Kleist 2012-04-03 13:32:09

0

我想只有一個循環,如果你寫的條件是足夠的。

我與克萊斯特同意循環超過變量和打印*爲每個變量

0

  1. (到克萊斯特的答案類似)使數組來定義y軸(或公式,根據索引)
  2. 從保存在容器中的文件中讀取數字,因此您還知道數值(x軸)
  3. 雙循環,1代表y軸,1代表x軸,並找出是否必須打印星號,基於1.

讓y軸計數器遞減,讓您的酒吧上升。

1

爲了讓您的酒吧垂直你需要:

  1. 得到所有的數字陣列中的
  2. 確定的範圍,即計算陣列的最大值和最小值
  3. 進行遍歷範圍,打印行時,在列上留下與空間相關聯的值低於當前行的值爲'正在描繪'。

這裏我假定步驟1 & 2爲完成,只是示出了環和掩蓋一些細節(注意代碼不使用分鐘,從0循環)

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; 
} 

這裏輸出

* 
    * 
    * 
    * 
* * 
* * 
* ** 
** ** 
***** 
2

你有兩個問題。突然想要構建直方圖,並且想要直觀顯示此直方圖。

直方圖 之一來構建直方圖方法需要你預先指定倉(均相寬度)的數量,最小值(含)和最大值(不含)。然後,您可以計算每個項目應分配到的垃圾箱索引。

下面是一個(未測試)實施例:

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描述的方法似乎是適當的。對於較大的料倉計數,您可能需要一些歸一化程序,即將值縮放到[0,10]或類似的範圍。

看一看這(未經測試)例如:

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一點點:

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 
+0

現在明白了,謝謝!我將相同的問題放在CodeGuru上,沒有人會幫助我...至少你們願意幫助一個學生! – 2012-04-04 05:23:18

+0

@JordanMoffat - 確保註冊有用的帖子,並接受答案,如果它解決了你的問題。 – moooeeeep 2012-04-04 07:16:20

1

只是有趣和練習:) 輸入任何數字序列,你想多達100個數字,然後按0停止,並使圖表:)

#include <iostream> 
#include <limits> 
using namespace std; 


int main() 
{ 
    const int MAX = 100; 
    int values[MAX]; 
    int input_number; 
    int total_number =0; 
    int largest_number = 0; 


    for (int i = 0; i < MAX; i++) 
    { 
     cin >> input_number; 
     if (input_number != 0) 
     { 
        total_number++; 
        values[i] = input_number; 
        } 
     else if (input_number == 0){ 
      for (int t = 0;t<total_number;t++){ 
       if(values[t]>largest_number) 
       largest_number = values[t]; 
       } 

      for (int j = 0; j <largest_number; ++j){ 
      for (int i = 0; i <total_number; ++i) 
       cout << (j+values[i] >= largest_number ? '*' : ' ') ; 
       cout << endl; 
      } 
      break; 
     } 

    } 



    system ("PAUSE"); 
    return 0; // everything ok 
}