前提・実現したいこと
C++で、visual studio code を使って書いております。
ベクトルの5つの数字をランダムで挿入し、(0から1の間)
それぞれの中央値、最小値、最大値を計算して、
最小値と最大値を使って、ヒストグラムをつくるというプログラムを書いています。
RandomVector(int size, double max_val = 1) (constructor): ベクトルの初期化、double で、0から1の間で size 個分の要素を、入れる。
double mean() returns 上のベクトルの中央値の計算
double max() returns 上のベクトルの最大値の計算
double min() returns 上のベクトルの最小値の計算
void print() prints ベクトルを表示する
void printHistogram(int bins) ヒストグラムを、最小値、最大値の間を、binsで分けて計算をする。
例えば、size 20, bins 5 のときは、
$ ./random_vector 0.458724 0.779985 0.212415 0.0667949 0.622538 0.999018 0.489585 0.460587 0.0795612 0.185496 0.629162 0.328032 0.242169 0.139671 0.453804 0.083038 0.619352 0.454482 0.477426 0.0904966 Mean: 0.393617 Min: 0.0667949 Max: 0.999018 Histogram: *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
のような表示になるものがつくりたいです。
現在、私のソースコードは、
該当のソースコード
main.cpp
#include <cstdlib> // required for srand #include <iostream> #include "random_vector.h" int main(){ // initialize rand with constant seed for reproducibility std::srand(314159); //RandomVector rv(20); RandomVector rv(4); rv.print(); std::cout << "Mean: " << rv.mean() << std::endl; std::cout << "Min: " << rv.min() << std::endl; std::cout << "Max: " << rv.max() << std::endl; std::cout << "Histogram:" << std::endl; rv.printHistogram(5); std::cout << std::endl; }
random_vector.cpp
cpp
1#include "random_vector.h" 2#include <cstdlib> 3#include <vector> 4 5 6 7RandomVector::RandomVector(int size, double max_val) { 8 9 int double_size = size; 10 std::cout << "Vector size: " << vec.size() << std::endl; 11 std::srand(314159); 12 for (auto i = 1; i <= double_size; ++i) 13 vec.push_back(((double)rand() / RAND_MAX)*max_val); 14 std::cout << "Vector size 2: " << vec.size() << std::endl; 15 16 17} 18 19void RandomVector::print(){ 20 21 std::cout << "Vector elements: "; 22 for (auto &elem: vec){ 23 std::cout << elem << " "; 24 } 25 std::cout << std::endl; 26} 27 28double RandomVector::mean(){ 29 30 double total; 31 for (auto &elem: vec){ 32 total += elem; 33 } 34 std::cout << total << " "; 35 return total/vec.size(); 36} 37 38double RandomVector::max(){ 39 40 double max_num=0; 41 for (auto &elem: vec){ 42 if ( max_num < elem){ 43 max_num = elem; 44 } 45 } 46 return max_num; 47} 48 49double RandomVector::min(){ 50 51 double min_num=1; 52 for (auto &elem: vec){ 53 if ( min_num > elem){ 54 min_num = elem; 55 } 56 } 57 return min_num; 58} 59 60void RandomVector::printHistogram(int bins){ 61 62 //double separation = 1 / bins; 63 64 double max_num_hist=0; 65 for (auto &elem: vec){ 66 if ( max_num_hist < elem){ 67 max_num_hist = elem; 68 } 69 } 70 71 72 double min_num_hist=1; 73 for (auto &elem: vec){ 74 if ( min_num_hist > elem){ 75 min_num_hist = elem; 76 } 77 } 78 79 //std::cout << "max" << max_num_hist << " "; 80 //std::cout << "min" << min_num_hist << " "; 81 82 double separation = (max_num_hist - min_num_hist) / bins; 83 //std::cout << "min" << separation << " "; 84 85 std::vector<int> vect_his; 86 for (auto i = 1; i <= bins; ++i){ 87 vect_his.push_back(0); 88 } 89 90 for (auto &elem: vec){ 91 92 for (auto i = 0; i < bins; ++i){ 93 if (i==0){ 94 if ( min_num_hist+separation*(i+1) >= elem){ 95 vect_his.at(i) += 1; 96 } 97 } 98 99 else if ( min_num_hist+separation*(i+1) >= elem && min_num_hist+separation*(i) < elem ) 100 { 101 vect_his.at(i) += 1; 102 } 103 } 104 105 } 106 107 double max_num_freq=0; 108 for (auto &elem: vect_his){ 109 if ( max_num_freq < elem){ 110 max_num_freq = elem; 111 } 112 } 113 std::cout << std::endl; 114 for (auto i = max_num_freq; i > 0; --i){ 115 for (auto j = 0; j < bins; ++j){ 116 if (i <= vect_his.at(j) ){ 117 std::cout << "*** "; 118 } 119 else{ 120 std::cout << " "; 121 } 122 } 123 std::cout << std::endl; 124 } 125 126 127std::cout << "elements: "; 128 for (auto &elem: vect_his){ 129 std::cout << elem << " "; 130 //std::cout << vect_his.at(2) << " "; 131 } 132 std::cout << std::endl; 133 134 135 136}
random_vector.h
1#include <iostream> 2#include <vector> 3 4class RandomVector{ 5 std::vector<double> vec; 6 7 public: 8 RandomVector(int size, double max_val = 1); 9 void print(); 10 double mean(); 11 double max(); 12 double min(); 13 void printHistogram(int bins); 14};
と3つあり、random_vector.cpp 内の、
void RandomVector::printHistogram(int bins){ //double separation = 1 / bins; double max_num_hist=0; for (auto &elem: vec){ if ( max_num_hist < elem){ max_num_hist = elem; } } double min_num_hist=1; for (auto &elem: vec){ if ( min_num_hist > elem){ min_num_hist = elem; } } //std::cout << "max" << max_num_hist << " "; //std::cout << "min" << min_num_hist << " "; double separation = (max_num_hist - min_num_hist) / bins; //std::cout << "min" << separation << " "; std::vector<int> vect_his; for (auto i = 1; i <= bins; ++i){ vect_his.push_back(0); } for (auto &elem: vec){ for (auto i = 0; i < bins; ++i){ if (i==0){ if ( min_num_hist+separation*(i+1) >= elem){ vect_his.at(i) += 1; } } else if ( min_num_hist+separation*(i+1) >= elem && min_num_hist+separation*(i) < elem ) { vect_his.at(i) += 1; } } } double max_num_freq=0; for (auto &elem: vect_his){ if ( max_num_freq < elem){ max_num_freq = elem; } } std::cout << std::endl; for (auto i = max_num_freq; i > 0; --i){ for (auto j = 0; j < bins; ++j){ if (i <= vect_his.at(j) ){ std::cout << "*** "; } else{ std::cout << " "; } } std::cout << std::endl; } std::cout << "elements: "; for (auto &elem: vect_his){ std::cout << elem << " "; //std::cout << vect_his.at(2) << " "; } std::cout << std::endl; }
の中で、他の関数の値、min_num, max_num (最小値と最大値) の値を使いたいとき、どのように宣言すればよいでしょうか。。
私の結果のアウトプットは、printHistgram の中で、もう一度最小値と最大値を計算しているため、大変非効率だと感じております。
また、引数は変えられないという条件があり、printHistgram内で、min(),max() を呼び出したいです。
何か、計算が繰り返しにならない、いい方法はないでしょうか。。
よろしくお願いいたします。
試したこと
ここに問題に対して試したことを記載してください。
補足情報(FW/ツールのバージョンなど)
Ubuntu18.04
visual studio code
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/01/24 10:48
2021/01/24 11:38
2021/01/24 11:46