- PR -

文字列配列のソートにて

投稿者投稿内容
まさ
ベテラン
会議室デビュー日: 2002/11/15
投稿数: 74
投稿日時: 2003-06-12 15:57
お世話になっております。
まさです。


文字列の配列をソートするプログラムを作っています。

コード:
String[] listData = new String {
        "aaa100",
        "aaa20",
        "aaa3",
    };



上記のような文字列配列を Arrays.sort( ) などを使用してソートすると

"aaa100"
"aaa20"
"aaa3"

の順になりますが、これを

"aaa3"
"aaa20"
"aaa100"

といったように文字部分が一致している場合には
数値部分でソートしたいと思っているんですが...

1文字ずつ調べて、数値部分と文字部分で分割して
数値部分を数値に変換してからソートする
というようなことをしないとだめでしょうか?

何かよい手はありませんでしょうか?
うのきち
ベテラン
会議室デビュー日: 2003/02/17
投稿数: 55
投稿日時: 2003-06-13 01:03
コンパレータを自分で作ってやれば良いのでは?
おっきー
大ベテラン
会議室デビュー日: 2003/05/01
投稿数: 104
投稿日時: 2003-06-13 01:21
Array.sort()にセットするComparatorを自分で定義することで
自由にソート順が設定できます。私もはじめて知りました

適当にサンプルを作ってみました。
どうでしょう?
コード:

import java.util.Arrays;
import java.util.Comparator;

public class Sample {

public static void main(String[] arg) {
String[] listData = {
"aaa100",
"aaa20",
"aaa3",
};
Comparator c = new StrCompare();
Arrays.sort(listData, c);
for (int i = 0; i < listData.length; i++) {
System.out.println(listData[i]);
}
}
}

class StrCompare implements Comparator {
public int compare(Object a, Object b) {
if (a == b) return 0;
if (a instanceof String
&& b instanceof String) {
String sa = (String)a;
String sb = (String)b;
if (sa.length() == sb.length()) {
return sa.compareTo(sb);
} else if (sa.length() < sb.length()) {
return -1;
} else {
return 1;
}
} else {
// FIX ME (^^
throw new RuntimeException("Not String");
}
}
}



[ メッセージ編集済み 編集者: おっきー 編集日時 2003-06-13 01:24 ]
おっきー
大ベテラン
会議室デビュー日: 2003/05/01
投稿数: 104
投稿日時: 2003-06-13 01:34
あ、これだと"aaa000" と "aaa1" なんかがうまくソートできないですね・・・。

比較の部分は自分で工夫してみてください

ではでは。

[ メッセージ編集済み 編集者: おっきー 編集日時 2003-06-13 19:52 ]
MMX
ぬし
会議室デビュー日: 2001/10/26
投稿数: 861
投稿日時: 2003-06-13 15:32
このデータの形に限定したものでしたら、文字列操作の前後処理でも可能です。

1.数値の前に桁数とスペースを入れる。(指数の付加)、桁数は9までとして
2.整列する
3.付加した指数を取り除く。

無理すると 0001と1の対応も可能でしょう。
まさ
ベテラン
会議室デビュー日: 2002/11/15
投稿数: 74
投稿日時: 2003-06-14 00:01
まさです。お世話になります!

質問の仕方が不適切だったようですね。

おっきーさんより
引用:
比較の部分は自分で工夫してみてください



この「比較部分」について、
「何かよい手はありませんでしょうか? 」
と言う質問でございました。
お手数をおかけして申し訳ないです。

MMX さんより
引用:
1.数値の前に桁数とスペースを入れる。(指数の付加)、桁数は9までとして



と言うのは数値部分を桁合わせしろってことでしょうか?
ソートしたい文字列は特に書式が決まってるわけではなくて、
しかも可変なんですよ…
やっぱり1文字ずつ調べないとだめそうですかねぇ?
Izumi, Y.
ベテラン
会議室デビュー日: 2002/03/19
投稿数: 77
お住まい・勤務地: 東京
投稿日時: 2003-06-14 19:56
引用:
やっぱり1文字ずつ調べないとだめそうですかねぇ?


基本的には1文字ずつ調べないとだめだと思います。1文字ずつ調べるとはいっても,それほど大したコードにはならないはずです(計算量的にも)。
コード:
// 数字列がはじまる位置を返す。数字がないときは str.length()。
private int parse(String str) {
  for(int i = str.length() - 1; i >= 0; i--) {
    if(str.charAt(i) < '0' || str.charAt(i) > '9')
      return i + 1;
  }
  return 0;
}



正規表現が利用できるのであれば(JDK 1.4 など),それを利用して分割する方法もあります(速度はやや遅くなりますが)。
MMX
ぬし
会議室デビュー日: 2001/10/26
投稿数: 861
投稿日時: 2003-06-16 11:25
10進指数表現みたいな物を使ってSORTできませんか

aaa100 <=> aaa3100
aaa20 <=> aaa220
aaa3 <=> aaa13

桁数が9以上なら2重指数表現とか、区切り記号を使って対応します。
0001と1の同一視は?実験は容易です。エディタですぐ

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