スレッド表示 | フラット表示〕 全トピック 920 件中 295 番目 次≫ ≪前

多次元配列のソートと重複の削除について

created: 2006-01-18 01:40 | modified: 2006-01-21 00:08 | reply: 4

[2861] 多次元配列のソートと重複の削除について

user: RRR | created: 2006-01-18 01:40
初めて投稿します。

まず、多次元配列のソートについて、
質問します。

過去ログ2492番からを読ませて頂き、
usort関数を使った
多次元配列の項目指定ソートの動作は、
実現する事ができたのですが、
肝心の理解ができません。

usort関数の"動き"について御教授願います。

以下ソースを記します。

<?php
//配列を以下のように定義します。
$arr=array();
$arr[0]["no"] = "0";
$arr[0]["name"] = "ZZZ";
$arr[0]["code"] = "0055";

$arr[1]["no"] = "1";
$arr[1]["name"] = "BBB";
$arr[1]["code"] = "0033";

$arr[2]["no"] = "2";
$arr[2]["name"] = "AAA";
$arr[2]["code"] = "0011";

$arr[3]["no"] = "3";
$arr[3]["name"] = "CCC";
$arr[3]["code"] = "0077";

//["name"]の昇順でソート用関数
function cmp($a, $b){

//確認のため表示させます。
print_r($a);echo "<br>";
print_r($b);echo "<br>";
echo strcmp($a["name"], $b["name"]) . "<br>";

//比較し数値を返す
return strcmp($a["name"], $b["name"]);
}

//最初の配列の表示
echo "最初の配列↓<pre>";print_r($arr);echo "</pre>";

//ソート
usort($arr, "cmp");

//ソート後配列の表示
echo "<br>ソート後配列↓<pre>";print_($arr);echo "</pre>";
?>


としたファイルを実行すると、中間部分で、

Array ( [no] => 1 [name] => BBB [code] => 0033 )
Array ( [no] => 0 [name] => ZZZ [code] => 0055 )
-1
Array ( [no] => 3 [name] => CCC [code] => 0077 )
Array ( [no] => 1 [name] => BBB [code] => 0033 )
1
Array ( [no] => 2 [name] => AAA [code] => 0011 )
Array ( [no] => 1 [name] => BBB [code] => 0033 )
-1
Array ( [no] => 3 [name] => CCC [code] => 0077 )
Array ( [no] => 0 [name] => ZZZ [code] => 0055 )
-1


と表示されます。
この中で、

1.配列のソートはどこで行われるのか?
 1であれば、下を上へ、
 -1であれば、上を下へ、
 0であれば、移動しない
 という動作はどこで行われるのでしょうか?

2.ユーザー定義関数cmpの引数$a,$bについて
 なぜ
 $a=Array ( [no] => 1 [name] => BBB [code] => 0033 )
 $b=Array ( [no] => 0 [name] => ZZZ [code] => 0055 )
 となるのか?
 呼び出し時は、usort($arr, "cmp");
 として、cmp関数の引数指定してないと思うのですが。

3.また、どこで配列の場合の数だけ比較が行われるか?
 場合の数を割り出し、
 ループして比較が行われていますが、
 それはどこで行われるのでしょうか?

そういうものと言われればそれまでですが、
以上、多次元配列のソートusrot関数について、
理解できておりません。
何卒、御教授よろしくお願いします。


次に、多次元配列の重複削除について、
その方法を御教授願います。

<?php
//配列を以下のように定義します。
$arr=array();
$arr[0]["no"] = "0";
$arr[0]["name"] = "ZZZ";
$arr[0]["code"] = "0055";

$arr[1]["no"] = "1";
$arr[1]["name"] = "BBB";
$arr[1]["code"] = "0033";

$arr[2]["no"] = "1";
$arr[2]["name"] = "BBB";
$arr[2]["code"] = "0033";

$arr[3]["no"] = "3";
$arr[3]["name"] = "CCC";
$arr[3]["code"] = "0077";
?>

この配列を

<?php
$arr[0]["no"] = "0";
$arr[0]["name"] = "ZZZ";
$arr[0]["code"] = "0055";

$arr[1]["no"] = "1";
$arr[1]["name"] = "BBB";
$arr[1]["code"] = "0033";

$arr[2]["no"] = "3";
$arr[2]["name"] = "CCC";
$arr[2]["code"] = "0077";
?>

としたいと思います。

上記ソートと組み合わせて、
重複削除・ソートを行いたいと考えております。

以上、配列に関してまだまだ未熟ではありますが、
何卒、御教授の程よろしくお願いします。
最終的には、クラスでのコーディングを希望しています。

環境:PHP5、Windows2000
reply: 2863 返信 編集 削除

[2863] バブルソート?

user: ごいんきょ。 | created: 2006-01-18 04:12
たぶんですけど、最も典型的なソート方法である、バブルソートが使われてるんだと思います。

http://www.ics.kagoshima-u.ac.jp/~fuchida/edu/algorithm/sort-algorithm/bubble-sort.html

質問1と3の、「どこで」というのが、どういう意味なのか、ちょっとはかりかねていますが...
たぶん、これでお答えになっていると思います。

引数を指定しなくても良い理由は...usort関数が勝手に配列を展開してくれているからです。
usortは、ソートを行うために、必要な回数だけ比較関数を呼び出してくれるものだと考えてください。

比較するある値とある値を比較関数に渡す。

必要ならば並べ替える。

次に比較するある値とある値を渡す。

必要ならば並べ替える





という繰り返しです。

重複削除もいろいろやり方はあると思います。

ソートした後で良いなら、
配列をループで回し、
前後の値を一時的な(連想配列ではない)配列として比較、
すべて一致したら、削除。
などが考えられます。

そこは、ご自分でいろいろ工夫してみるのが良いと思いますよ。

ただ、データの重複が許されない場合は、最初から重複して登録させない努力も必要です。

配列は、ほとんどのプログラミング言語の基本となります。
がんばってくださいね。
Parent: 2861  reply: 2867 返信 編集 削除

[2867] ありがとうございます。

user: RRR | created: 2006-01-18 22:15
ごいんきょ。さま

早速の御回答ありがとうございました。
お陰でソートのアルゴリズムが理解できました。

このusort関数は、
PHP組み込み関数で、
そのソースはPHPで記述されていないのでしょうか?

「どこで動く」という質問は、
PHPで使える関数とは、全て
function usort(..){
}
のような記述が、
PHPインストール時に作成されるファイル郡の
どこかにあり、
その記述に則って動作するものと考えておりました。

ところが組み込み関数については、
その記述が見えないと理解しましたが、
この認識は合っているのでしょうか?
(grep検索してもusort関数の実態はありませんでした)

さらに疑問は深まってしまいました。
もしよろしければ、この点御教授願います。

多次元配列の重複削除については、
自作にて何とか解決しました。

以上、よろしくお願いします。
Parent: 2863  reply: 2868 返信 編集 削除

[2868] ソースに載ってます

user: ach | created: 2006-01-19 00:21
Windows BinariesではなくComplete Source Codeに入っています。
ext/standard/array.c
Zend/zend_hash.c
Zend/zend_qsort.c
あたりを読むといいのかなぁ
たぶんクイックソートを使っています。(名前がzend_qsortだからってだけだけど・・・)

zend_qsortがソートアルゴリズム
zend_hash_sortはPHPソース側とのインターフェイスです。
usortとsortは内部的にはあまり差がないようです
(zend_hash_sortにユーザー関数を渡すか内部関数を渡すかの差)
Parent: 2867  reply: 2871 返信 編集 削除

[2871] ありがとうございます。

user: RRR | created: 2006-01-21 00:08
achさま。

ありがとうございました。

これで、PHPの組み込み関数の謎(仕組み)が解けました。
PHPはCで作られているんですね。

今後組み込み関数の動きが気になったら、
Complete Source Code
にて探すようにします。

返事が遅くなってしまいましたが、
大変参考になりました。
御指摘、誠にありがとうございました。
Parent: 2868  返信 編集 削除
スレッド表示 | フラット表示〕 全トピック 920 件中 295 番目 次≫ ≪前
ページの一番上へ
Googleグックマークに登録 Yahooグックマークに登録 livedoorクリップに登録 @niftyクリップに登録 はてなブックマークに登録 deliciousに登録 Buzzurlに登録 FC2ブックマークに登録
最近更新された掲示板トピックス
管理人Blog
Yahoo Search

最近更新したNote
PHPマニュアル
今日のブックマーク
PHPマニュアル関数検索
関数名を入力し検索ボタンをクリック↑