• ベストアンサー

配列の並びかえごにFor文使用

いつもお世話になっております。 今回、配列の要素数に応じて順番を並び替へ、要素数の多いのから少ないものへのforループに挑戦することにしたのですがルーチンが思い浮かばず投稿させていただきました。 DBから 条件1で検索し、その条件でヒットしたid列の値を$hairetu1に格納しております。 条件2で検索し、その条件でヒットしたid列の値を$hairetu2に格納しております。 条件3で検索し、その条件でヒットしたid列の値を$hairetu3に格納しております。 条件4で検索し、その条件でヒットしたid列の値を$hairetu4に格納しております。 条件5で検索し、その条件でヒットしたid列の値を$hairetu5に格納しております。 最大5つの条件で検索できるようにしております。($hairetu変数は全て配列変数として使用しております) 条件1で検索した再に、$hairetu1には、1,2,4という値(id値)が入っており、 条件2で検索した再には、$hairetu2に、1,4という値が入っています。 条件3で検索した再には、$hairetu3に、1,2,3,4という値が入っています。 条件4で検索した再には、$hairetu4に、9999という値が入っています。 条件3で検索した再には、$hairetu5に、1,2という値が入っています。 ※各条件で検索した際に、ヒットしたid数が0の場合、nullが入らないように初期化の時点で9999をセットしております。$hairetu=array(9999); 今回、[条件1 and 条件2 and 条件3 and 条件4 and 条件5] の結果、1と2を最終的に$result_hairetuに格納したいのです。 考えた方法は、 For(i){ for(j){ for(k){ for(l){for(m){ if(hairetu[i]==hairetu[j] && hairetu[i]==hairetu[k]・・・,hairetu[l] ==hairetu[m]){array_push($result_hairetu,hairetu[i])}}}}}} ※i・・・ (i=0;i<count(hairetu1);i++) という方法で、5つのfor文でループし、ifで比較し同じであればresult_hairetuに格納するという手法をとろうとしたのですが、条件2で検索した結果が、1,2の二つであるため、二つ目のfor文を二回走ったところで抜けてしまい処理が途中で終わってしまいます。 途中で抜けるのを防ぐために以下のように配列を並び替えて、 For分で使用するという流れを作りたいのです。 また、今回、hairetu2と5の要素数が同じなのときはどのようにセットしたらよいかもわかりません。要素数が同じである場合はどちらが先でもかまいません。 for(hairetu4){for(hairetu2){for(hairetu5){for(hairetu1){for(hairetu3)}}}} このループの作り方がわかる方がいらっしゃいましたらご教授のほうお願いできないでしょうか?よろしくお願いします。

  • PHP
  • 回答数2
  • ありがとう数1

質問者が選んだベストアンサー

  • ベストアンサー
回答No.2

基本的にforの入れ子にする必要性があまり無いような気がします。 for(i=0;i<hairetu3要素数;i++){  for(j=0;j<hairetu1要素数;j++){   for(k=0;k<hairetu2要素数;k++){    for(l=0;l<hairetu4要素数;l++){     for(m=0;m<hairetu5要素数;m++){      if(hairetu3[i]==hairetu1[j] && hairetu3[i]==hairetu2[j] && hairetu3[i]==hairetu4[j] && hairetu3[i]==hairetu5[j]){ array_push(result_hairetu,hairetu3[i]); }     }    }   }  } } この処理は、つまり 「全ての条件に該当した場合のみIDを返す」 という状態になっていると思います。 これはSQLで WHERE word = '条件1' AND word = '条件2' AND word = '条件3' AND word = '条件4' AND word = '条件5' とやっていることと同じだと思います。 仮にforの入れ子が5個あり、各要素に100個の検索結果が入った場合、繰り返し処理数は100の5乗に近いものとなり、間違いなく無駄な負荷になります。 行いたいことは実現できると思いますが、他の方法を考えることをお勧めします。

ShiftTail
質問者

お礼

なるほど。ありがとうございます。 ちょっと別の方法を考えて見ます。

その他の回答 (1)

  • yambejp
  • ベストアンサー率51% (3827/7415)
回答No.1

要素数の少ない順にforをつくる意義がわからないです。 どのような効果を期待して要素数順にするかがポイントでしょう。 不可能ではないとは思いますが、やる意味がないのであれば やらずに済ませるに越したことはありません。

ShiftTail
質問者

補足

2点間違っておりました。 ●条件4で検索した結果には、$hairetu4に、9999だけではなく、1も入っております。(1,9999が、はいっています。) ●今回、[条件1 and 条件2 and 条件3 and 条件4 and 条件5] ここの記述が間違っており、 →[各条件で絞り込んだ時の最大のヒット数配列(今回ならヒット数4のhairetu3) and 二番目のヒット数配列(hairetu1) and 3番目のヒット数配列(hairetu2) and 4番目のヒット数配列(hairetu4) and 5番目のヒット数配列(hairetu5)]で共通をidを探し、 なければ、 [各条件で絞り込んだ時の最大のヒット数配列(今回ならヒット数4のhairetu3) and 二番目のヒット数配列(hairetu1) and 3番目のヒット数配列(hairetu2) and 4番目のヒット数配列(hairetu4)] というように 後ろの一つのhairetuを削り4つで共通idを探す。これでもなければ、3つ、2つ、2つの検索結果で共通idがないときは、各条件で絞り込んだ時の最大のヒット数配列(今回ならヒット数4のhairetu3) を result_hairetuに格納し、その内容を表示させるということをしたいのです。よって、コレをさせるためには、要素数の多いものから小さいmのへのループを作る必要があると思ったのです。 <要素の多いものから少ないものへのループにしたい> for(i=0;i<hairetu3要素数;i++){  for(j=0;j<hairetu1要素数;j++){   for(k=0;k<hairetu2要素数;k++){    for(l=0;l<hairetu4要素数;l++){     for(m=0;m<hairetu5要素数;m++){      if(hairetu3[i]==hairetu1[j] && hairetu3[i]==hairetu2[j] && hairetu3[i]==hairetu4[j] && hairetu3[i]==hairetu5[j]){ array_push(result_hairetu,hairetu3[i]); }     }    }   }  } } ただ、この各hairetuの配列変数に入るidの個数はきまっておらず、0個のときもあれば10個のときもあるのです。 つまり、毎回各配列の数を数えて、hairetuの要素数が多いものを基準に、小さいものと比べるという処理もいるのだと考えているのです。 並び替えずに、hairetu3をいつも一番外のループにしてしまうと、条件3で検索した結果がヒット数0であり、hairetu1(条件1で絞り込んだ結果数)とhairetu4(条件4で絞り込んだ結果数)での場合、hairetu3に格納されたidが0個のため、ループが走らないのです。

関連するQ&A

  • 配列のことでなのですが

    配列で先頭から順番に文字列を格納していきたいのですがどのような方法があるでしょうか? ただforループなどで順番に繰り返すのではなくて、文字列を入力する度に配列の最後尾に文字列を格納していきたいのですが、 例えば for(i=0;i<=10;i++){ scanf("%s",hairetu[i]) } のような方法ではなく配列の中に文字列を前から順番に格納したいです。 詳しい方は知識をかしていただけるとありがたいです。

  • for文を簡単な処理に書き変えたい

    いま、配列を作る作業をしているのですが、for文を使うと、forをいくつ書けば良いのか分からない状態です。 作ろうとしている配列が、A[X][Y]で、Xの要素数は固定で良いのですが、Yの要素数が実験のたびに変動するためです。そして、処理したいのが、この配列の各列の値を適当な値(このfor文の前に値が決まっています)を代入することです。 例えば、for文だと、Y=3のときには for(i=0;i<○;i++){ for(j=0;j<○;j++){ for(k=0;k<○;k++){ A[line][0] = C[i];//(Cという配列のi成分) A[line][1] = B[j]; A[line][2] = E[k]; } } } のように書くような内容なのですが、Yが増えると、for文も増やさないといけません。 ここで、再帰処理のような方法をつかってうまく書きたいのですが、どう書いたら良いのか分かりません。 一般的なfor文の書き換え方みたいなことでも良いので、教えて頂けませんか?宜しくお願いします。

  • 配列でデータが入っている要素を求める方法

    dim hairetu(1000,1000) と宣言した後に、 (0,0)から(x,y)までデータを入れるとします。 このときのデータが入っている要素数xとyの値を求めたいのですが、 inboundやUboundだとemptyも含めた要素数を求めることになり使えません。 forを使わない方法があれば教えてください、

  • 配列の要素でmysqlに問い合わせ

    フォームから送信されたデータを配列として取得し、その配列の1つの要素に対してそれぞれmysqlにselectで問い合わせてageというカラムの値を取得したいと思っています。 配列の要素の数がその都度変わるので、要素が5つある場合には5回selectでデータベースに問い合わせてデータを5つ取得したいのですが、それは可能でしょうか? ためしに下記のようにしてみたのですが、うまく取得できませんでした。 $hairetu = $_POST; for($i=0; $i< count($hairetu) ; $i++){ $sql = "SELECT * FROM member where age = '$hairetu[i]';"; $res = mysql_query($sql, $conn) or die("エラー"); $row = mysql_fetch_array($res, MYSQL_ASSOC); $age = $row["age"]; echo $age; } $ageの値をcount($hairetu)の回数分表示したいのですが、どのように処理していいのか分かりません。 また、根本的におかしな点もあると思いますがよろしくお願いします。

    • ベストアンサー
    • MySQL
  • 2次元のJSON形式の配列の展開

    JSON形式で受け取った2次元配列をHTMLに書き出そうとしています。 配列を指定するカラム名?を変数にしたいのですがうまくできません。 var hoge = "abc"; var len = result.length; for (i = 0; i < len; i++){  objResult.append("<li><a href=" + result[i].ID + ">" + result[i].hoge + "</a></li>"); } ※objResultはul要素を変数に収めたものです。 JSONデータは1列目のカラム名は『ID』で固定ですが2列目は変動する為、上記の『hoge』の部分にはJSONデータを受け取る前にカラム名を別処理で取得して格納しています。 ご教授の程よろしくお願いします。

  • データベースから取得したデータを配列に格納

    データベースから取得したデータを配列に格納することができません。 唯一、以下の方法で格納できたのですが、この場合データベースの項目の数が、あらかじめ分かっている場合にしか使用できません。googleで検索して出てくるサンプルは全てループ内でprintしているので参考になりませんでした。 やりたいことは単純で、データベースにクエリーを発行した結果の複数レコードをそのまま配列に格納することです。perlに詳しい方がおられましたらよろしくお願いします。 _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ ■データベース内のデータ id=1,subid=1,data1=aaa id=1,subid=2,data1=bbb id=1,subid=3,data1=ccc ■期待する結果 @result = ("1","1","aaa", "1","2","bbb", "1","3","ccc", ) _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ ■実際のソース ********************************************************** use DBI; #//■DB接続 $db = DBI->connect("DBI:mysql:$DbName:$DbHost", $DbUser, $DbPass); $sth = $db->prepare($sql); $sth->execute; $cnt = $sth->rows; for($i=0; $i<$cnt; $i++){ @work = $sth->fetchrow_array; @result[$i] = ([$work[0],$work[1],$work[2],]); } #//■CLOSE $sth->finish; $db->disconnect; for($i=0; $i<$cnt; $i++){ print "<p>".$result[$i][0]."/".$result[$i][1]."/".$result[$i][2]."</p>\n"; } **********************************************************

    • ベストアンサー
    • Perl
  • VB.NET 配列の格納

    VB.NET 配列の格納 エクセルから任意の列の値を格納したいのですが・・・ 現在、値の取得は以下のようなFor文ループを書いています。 各値を一時記憶(格納)したいのですが、どう書けばいいのでしょうか。 また、各列内で重複する値があった場合、重複を避けて値を取得したいのですが どう書いていいかわかりません。 初歩的な質問で申し訳ありませんが、宜しくお願いします。 PN()→G列の各セルの値の変数 JN()→H列の各セルの値の変数 の変数GYO→シートの最終行 j = 1 For i = 1 To GYO '【リストのG列から部品番号を取得】 PN(j) = xlSheet.Cells(i, 7).Value '【リストのH列から部品和名を取得】 JN(j) = xlSheet.Cells(i, 8).value Next

  • 配列受け渡し

    要素数nであるint型配列xから値がkである要素の添え字を返却する関数(ただし、値がkである要素が存在しなければ-1を返却するものとし、そのような要素が複数存在する場合は、先頭側の最も小さい添え字を返却する)を作成しています。 #include<iostream.h> #include<iomanip.h> int search(int x[],int n,int k) { int i,j; int result=-1; for(i=0;i<n;i++){ if(x[i]==k){ result=i; return(result); } else return(-1); } } int main(void) { const int ninzu = 5; int height[ninzu]; cout << ninzu << "要素:\n"; int i; for (i = 0; i < ninzu; i++) { cout << setw(2) << i+1 << "番目:"; cin >> height[i]; } cout << "検索要素は?:"; int target; cin >> target; int result=search(height, ninzu, target); if(result==-1) cout<<"ないよ"<<endl; else cout<<result+1<<"番目が"<<target<<endl; return (0); } このようにしたのですが、うまくいきません。また、複数の要素が発生したときの返却の仕方がわかりません。 どなたかアドバイス等よろしくお願いします。

  • Rubyで配列を使ったfor文の中に条件つきif文

    Rubyで配列を使ったfor文の中に条件付きのif文を入れてループさせたいのですが、基本的な構文が分かりません。 for i in array     if i == 9       array[i] << 'ア'     end end という雰囲気で書きたいのですが、どうしたらよいでしょうか。 i番目のループまで、配列のarrayを走査するにはどうすればよいでしょうか。 基礎的な質問ですみません。よろしくお願いします。

  • カウンタを使用した配列の格納について

    EXCEL VBAについての質問です。 どなたか添削願えないでしょうか? A1からE40までSingle形式のデータが入っています。 ただし、A列はすべて見出し、行には5行おきに1,6,11...行目に見出しが入っています。 4x4のデータが8個ある計算です。 見出しを除くデータをすべて(8,4,4)の配列に格納しようと思い、下記のコードをSheet(1)に 書きましたが、「インデックスが有効範囲にありません」と出てうまく格納できません。 上の「Next j」を生かして、下の「Next j」を殺し、イミディエイトウインドウで確認したところ、 ネストの外ではうまくループしているようですが、入れ子にするとデータがうまく入りません。 jのループ完了後には  j=36  データ番号=8 が入っているはずですが、j がうまく格納されないようで、値がすべて0になります。 上の「Next j」と直下の2行をいかした場合、きちんと値が入り、うまく機能するようです。 色々考えましたが、手詰まりになってしまったので、何がおかしいのか教えてもらえません でしょうか?よろしくお願いします。 Option Base 1 Const データ数 As Integer = 8 Const 列数 As Integer = 4 Const 行数 As Integer = 4 Dim データ番号 As Integer Sub 換算値格納() ReDim 換算値(データ数, 行数, 列数) As Single For j = 1 To 36 Step 5 '(例)j=1→データ番号1、j=6→データ番号2、.... データ番号 = (j - 1) / 5 + 1 Debug.Print "データ番号=" & データ番号 & " j=" & j 'Next j 'データ番号 = 8'<任意に変えてみてください> 'j = (データ番号 - 1) * 5 + 1 For i = 4 To 19 '列定義 'カウンタを4で割って1を足したものが0になる (例)14÷4=3...2 → 2+1=3 列 = i Mod 4 + 1 '行定義 'カウンタがちょうど割り切れたら行をひとつ増やす (例)i=4,8,12...にて列=1,2,3 If i Mod 4 = 0 Then 行 = 行 + 1 換算値(データ番号, 行, 列) = Cells(行 + j, 列 + 1).Value Debug.Print "(" & データ番号 & "," & 行 & "," & 列 & ")は" & 換算値(データ番号, 行, 列) Next i Next j End Sub

専門家に質問してみよう