第12講 様々な並び替えの方法
第8話 分類法ソースコードの解説
さて、お約束の通り第6話のソースコード
private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) {
int a[N];
int n=int::Parse(textBox1->Text);
ds(a,n);
if(n>9)Br(a,n);
Nb(a,n);
}
void Br(int* p,int n){
char i,j;
int w=0;
int max=0,min=100;
for(i=0;i<n;i++){
if(max<p[i])max=p[i];
if(min>p[i])min=p[i];
}
textBox3->Text=max.ToString();
textBox4->Text=min.ToString();
double hb;
hb=((double)max-(double)min)/(double)4;
char a[4][N];
char cn[4];
for(i=0;i<4;i++){
cn[i]=0;
for(j=0;j<n;j++){
if(i<3){
if(p[j]>max-(i+1)*hb && p[j]<=max-i*hb){
a[i][cn[i]]=p[j];
cn[i]++;
}
if(i==3){
if(p[j]>=max-(i+1)*hb && p[j]<=max-i*hb){
a[i][cn[i]]=p[j];
cn[i]++;
}
}
}
}
char ks=0;
for(i=0;i<M+1;i++){
if(cn[i]>0){
for(j=0;j<cn[i];j++){
p[ks]=a[i][j];
ks++;
}
}
}
}
void Nb(int* p,int n){
char i,j;
int w,cn;
for(i=0;i<n-1;i++){
cn=0;
for(j=0;j<n-1;j++){
if(p[j]<p[j+1]){
w=p[j];
p[j]=p[j+1];
p[j+1]=w;
cn++;
}
}
if(cn==0){
textBox6->Text=(i+1).ToString();
break;
}
}
String^ v=L"";
for(i=0;i<n;i++) v+=(p[i]).ToString()+L" ";
textBox5->Text=v;
}
void ds(int* p,int n){
int i;
String^ w=L"";
for(i=0;i<n;i++){
p[i]=rand() % 100;
w+=(p[i]).ToString()+L" ";
}
textBox2->Text=w;
}
の解説を行いましょう。
まず、int a[N];で配列を宣言しています。Nは冒頭で、 const int N=30;(第12講第5話)と宣言されていますので、
30です。つまり、要素数(0を含めた添え字数)30の整数型の1次元配列aを宣言したことになります。
2行目のint n=int::Parse(textBox1->Text);では、
textBox1より、値を取得しています。
int::Parse(*)は*を整数型に変換する命令でした。
textBox1->Textに入っているのは、見かけは数字でも実際には文字でしたよね。
例えば、textBox1に100と入力されている場合、これは数字の100ではなく、文字の100です。
理由は、textBoxには文字しか入れられないからです。
だから、文字型を強制的に整数型に変換しなければならないのです。
強制的に変換しているのが、int::Parse(textBox1->Text)というわけです。
ds(a,n);はデータ作成関数void ds(int* p,int n)へ飛びなさいという命令です。
その際の引数が、配列aの最初のアドレスと先のn=int::Parse(textBox1->Text);によって取得したデータ数nです。
データ作成関数void ds(int* p,int n)では、データの作成が行われます。
for(i=0;i<n;i++){
p[i]=rand() % 100;
w+=(p[i]).ToString()+L" ";
}
によって、nこのデータが作成されます。rand() % 100は100以下の正の整数をランダムに発生させます。
1000以下の正の整数をランダムに発生させたいなら、rand() % 1000と変更すればよいのです。
なぜ、rand() % 100で100以下の正の整数が発生するかというと、rand() は10万以下の整数をランダムに発せさせる関数であり、
その関数で発生した整数を% 100で100で割った余りに換算しているからです。
textBox2->Text=w;で
のデータの右のtextBox2に値を入力しています。
次の、if(n>9)Br(a,n);ではデータ数が10以上ならデータ分類関数void Br(int*
p,int n)を呼び出しなさいと命令しています。
データ数が少ない場合、分類してもメリットがないからです。
データ分類関数void Br(int* p,int n)が今回のメインです。
ここでは、データの最大値と最小値の差を求め、その差を4等分した幅で、データを4つの群に分けています。
int max=0,min=100;
for(i=0;i<n;i++){
if(max<p[i])max=p[i];
if(min>p[i])min=p[i];
}
textBox3->Text=max.ToString();
textBox4->Text=min.ToString();
の部分では、最大値と最小値を求めそれをに表示させています。
double hb;
hb=((double)max-(double)min)/(double)4;
においては、分類幅を計算させています。(double)は整数型を強制的に実数型に変換させています。
実数型に変換しないと、小数点以下が丸められ整数になってしまうからです。
そして、いよいよメインの中のメイン
for(i=0;i<4;i++){
cn[i]=0;
for(j=0;j<n;j++){
if(i<3){
if(p[j]>max-(i+1)*hb && p[j]<=max-i*hb){
a[i][cn[i]]=p[j];
cn[i]++;
}
if(i==3){
if(p[j]>=max-(i+1)*hb && p[j]<=max-i*hb){
a[i][cn[i]]=p[j];
cn[i]++;
}
}
}
}
に到りました。ここで、4群への分類が行われています。
cn[0]、cn[1]、cn[2]、cn[3]は4群のデータ数をカウントするための変数です。
for(j=0;j<n;j++){
if(i<3){
if(p[j]>max-(i+1)*hb && p[j]<=max-i*hb){
a[i][cn[i]]=p[j];
cn[i]++;
}
if(i==3){
if(p[j]>=max-(i+1)*hb && p[j]<=max-i*hb){
a[i][cn[i]]=p[j];
cn[i]++;
}
}
}
では、すべてのデータがどの群に属するかを決定し、群のデータ数もカウントしています。
データが41 67 34 0 69 24 78 58 62 64の場合で動きを追ってみましょう。
この場合最大値が78、最小値が0ですから、分類幅は(78−0)÷4=19.5
i=0のとき、cn[i]=0;からcn[0]は0と初期化されます。そして、
for(j=0;j<n;j++){
if(p[j]>max-(i+1)*hb && p[j]<=max-i*hb){
a[i][cn[i]]=p[j];
cn[i]++;
}
}
は、
for(j=0;j<n;j++){
if(p[j]>max-(0+1)*hb && p[j]<=max-0*hb){
a[i][cn[i]]=p[j];
cn[i]++;
}
}
により、
for(j=0;j<n;j++){
if(p[j]>max-hb && p[j]<=max){
a[i][cn[i]]=p[j];
cn[i]++;
}
}
となり、p[j]が78以下で、58.5より大きいなら第1群a[0]に入れていきます。
41 67 34 0 69 24 78 58 62 64の内、41 67 34 0 69 24 78 58 62 64のピンクが該当します。
ですから
a[i][cn[i]]=p[j];
cn[i]++;
によって、
(cn[i]=0;からcn[0]=0であったことに注意)a[0][0]=67、cn[0]=1→a[0][1]=69、cn[0]=2→a[0][2]=78、cn[0]=3→a[0][3]=62、cn[0]=4→a[0][4]=64、cn[0]=5
(cn[0]=5は使用されないが、第1群のデータ数が5個であること示している。
データの最後がa[0][4]=64であり、5と1個ずれるのは添え字が0から始まることによる。)
と動いていきます。
では、皆さんi=1、i=2、i=3の場合でトレース(コンピュータの動きを追うこと)してみましょう。
第11講第6話へ 第12講第7話へ 第12講第9話へ 第13講第1話へ
vc++講義第1部へ
vb講義へ
VB講義基礎へ
初心者のための世界で一番わかりやすいVisual Basic入門基礎講座へ
初心者のための世界で一番わかりやすいVisual C++入門基礎講座へ