- PR -

重複排除のアルゴリズム

1
投稿者投稿内容
NV
ベテラン
会議室デビュー日: 2003/05/20
投稿数: 73
投稿日時: 2007-02-01 20:55
お世話になります。

質問ですが、下記のようなケースというものは、よくあることだと思います。

例えば、RDBから下記のような形を取得して

コード:

 | 1年 | 1組 | 小林 |
 | 1年 | 1組 | 山田 |
 | 1年 | 1組 | 田中 |
 | 1年 | 2組 | 佐藤 |
 | 2年 | 1組 | 中山 |
 | 2年 | 2組 | 小島 |




下記のツリーのように、上位の項目の重複の無い構造にしたい。

コード:

 | 1年 | 1組 | 小林 |
 |     |     | 山田 |
 |     |     | 田中 |
 |     | 2組 | 佐藤 |
 | 2年 | 1組 | 中山 |
 |     | 2組 | 小島 |




私自身、泥臭いべたな方法(if文のネストの連続)で変換してますが、何かスマートなアルゴリズムはありますでしょうか?

ご存知でしたら、よろしくお願い致します。
るぱん
ぬし
会議室デビュー日: 2003/08/01
投稿数: 1370
投稿日時: 2007-02-01 21:33
るぱんです。

OrderByかかってるなら、
一個前をもっておいて、
一個前と同じ場合、出力しないではダメ?
かつのり
ぬし
会議室デビュー日: 2004/03/18
投稿数: 2015
お住まい・勤務地: 札幌
投稿日時: 2007-02-01 22:59
総称型の宣言風に書くと、
TreeMap<年,TreeMap<組,TreeSet<名前>>>という構造でどうでしょう。
年、組、名前のそれぞれに適したComparatorを使用するといいと思います。

木構造のデータが欲しいのですか?
単にツリー風での出力が目的なら、るぱんさんの手法がベストかなと思います。
SUK2
ベテラン
会議室デビュー日: 2005/12/27
投稿数: 69
投稿日時: 2007-02-01 23:08
私は
コード:
Map gradeMap<String, Map<String, Map<String, String>>> = new TreeMap<String, TreeMap<String, List<String>>>();

while(resultSet.next()) {
String grade = resultSet.getString("GRADE");
Map<String, List<String>> classMap = gradeMap.get(grade);
if(classMap == null) {
classMap = new Map<String, Map<String, List<String>>();
gradeMap.put(grade, classMap);
}
String clazz = resultSet.getString("CLASS");
List<String> nameList = classMap.get(clazz);
if(nameList == null) {
nameList = new ArrayList<String>();
}
nameList.add(resultSet.getString("NMAME"));
}

と実装した事があります。

ネスト階層に依存するのがネックですが。

#現在お酒が入ってるのでコードに誤りがあったらスミマセン。
#丁度こないだ同じ様なコーディングをしたのでつい・・・。

#[追記]
#かつのり様とかぶりましたね・・・。むしろ若干光栄に思います(笑)

[ メッセージ編集済み 編集者: SUK2 編集日時 2007-02-01 23:10 ]
るぱん
ぬし
会議室デビュー日: 2003/08/01
投稿数: 1370
投稿日時: 2007-02-01 23:28
るぱんです。

えと、オブジェクトのプロパティにList入れてれば、何も問題おきないし、
Mapが流行ってるのかな? 汗
NV
ベテラン
会議室デビュー日: 2003/05/20
投稿数: 73
投稿日時: 2007-02-01 23:31
皆様ありがとうございます。

単純なものであれば、ルパンさんのおっしゃる通り、OrderByを前提として可能なのですが、もしかして、汎用的に作れるかなとの質問でした。

結構、頻繁に出現する構造なので、OrderByや階層の深さに関係なく、コレクションか何かを与えて、再帰か何かを利用して展開できないかなぁ?と思い質問させていただいました。

やはり、データや階層に依存してしまうのでしょうかね。

以上、ありがとうございます。
るぱん
ぬし
会議室デビュー日: 2003/08/01
投稿数: 1370
投稿日時: 2007-02-02 09:22
るぱんです。

できますよ?
リフレクションでカラム名を束で取ってきて、
グルッとまわせば汎用的。
前の行と全カラムをつき合わせることが出来ます。
あとは、それをやる行の数をint[]で渡してやればよいのでは?

でも、処理の負荷は高そう。笑
プロパティがいくつ以下で・・・って使用制限書いてあげないと、
ボトルネックになるかもね。

負荷テストで相当めんどくさそうだけどね。笑
カーニー
ぬし
会議室デビュー日: 2003/09/04
投稿数: 358
お住まい・勤務地: 東京
投稿日時: 2007-02-02 10:31
SELECT文でJoinしない、ってのはどうですか?

最初に「学年」テーブルをSELECT、結果セットのFORループの中で「組」テーブルをSELECT、また結果セットのFORループの中で「生徒」テーブルをSELECT。

SQLの効率的には良くないですが。
1

スキルアップ/キャリアアップ(JOB@IT)