五十音順に並べ替えて番号をつけるには

解決


五十音  2014-11-20 01:50:18  No: 46884  IP: [192.*.*.*]

こんにちは。
クラスの生徒名にややこしいのがいて、五十音に並べ替えて番号をつける場合を考えてます。
------
バータ
パァータ
パオロ
------

1パァータ
2パオロ
3バータ

二文字目に'ー'が入っている場合、五十音では一番最後にして番号をつけたいのです。

編集    削除
通りすがり  2014-11-20 03:11:37  No: 46885  IP: [192.*.*.*]

これのことですかね

日本語文字列照合順番 - Wikipedia
http://ja.wikipedia.org/wiki/%E6%97%A5%E6%9C%AC%E8%AA%9E%E6%96%87%E5%AD%97%E5%88%97%E7%85%A7%E5%90%88%E9%A0%86%E7%95%AA

編集    削除
五十音  2014-11-20 03:45:42  No: 46886  IP: [192.*.*.*]

そうですね。
コンピュータに指示するのって難しいです。

編集    削除
igy  2014-11-20 04:17:59  No: 46887  IP: [192.*.*.*]

TStringListに格納している場合、Sort メソッドを使わず、CustomSortを使って、
比較する処理を自前で実装すれば、よさそうな気がします。

編集    削除
いけぴ  2014-11-20 04:20:59  No: 46888  IP: [192.*.*.*]

並べ替えの方法はこちらを参照してみてください。
「IComparerを継承したクラスで比較方法を指定してソートする」で
比較方法を指定できるので、そこは自分で書くことになります。
http://www.gesource.jp/weblog/?p=6043

編集    削除
五十音  2014-11-20 04:51:40  No: 46889  IP: [192.*.*.*]

返信の皆様ありがとうございます。
いけぴさん。
初歩的な質問かもしれません。リンク先のページでuses System.Generics.Collections
delphi7を使用しているのですが、見つかりません。

番号をつける場合は、たとえば5名としてnumber:array[0..4]of integer;
並べ替えた名簿にnumberの配列を利用するとかできるのでしょうか。

編集    削除
 2014-11-20 07:03:55  No: 46890  IP: [192.*.*.*]

TStringListのSortメソッドを使うとよいかもしれません。

ソートするキーはひらがなのみで構成されているようですので、
とりあえず「ー」を「ん」よりも後の文字(例えば適当な漢字
など)にいったん置き換えてソートし、終わったらその文字を
元に戻して、頭に番号を振っていってやればよいと思います。

編集    削除
 2014-11-20 07:25:11  No: 46891  IP: [192.*.*.*]

少しイメージが付きやすいよう、コードを書いてみました。
生徒が5人だけいることを前提としています。

処理としては、生徒1人1人の情報をすべて別々のStringListに格納して、
そのStringListを、ソート用のStringListにAddObjectして登録し、ソート
をかけるというものです。

コンパイルが通るものでもないですが、イメージは少しつかんでもらえると
思います。

    SL1 := TStringList.Create;
    for i := 1 to 5 do begin
      SL2 := TStringList.Create;
      SL2.Add(生徒名i);
      SL2.Add(生徒カナ名i);
      SL2.Add(性別i);
      SL1.AddObject(置換後の生徒カナ名i, SL2); // ←ここのカナ名は、例えば「ー」を「亜」などに置き換えたもの。
    end;
    SL1.Sort;

    for i := 0 to SL1.Count - 1 do begin
      SL2 := TStringList(SL1.Objects[i]);
      ShowMessage(IntToStr(i) + '番目の生徒の名前は' + SL2[0] + 'で、性別は' + SL2[1] 'です。'); // 必要ならここで番号を振るなどする。
      SL2.Free;
    end;
    SL1.Free;

編集    削除
deldel  2014-11-20 18:07:13  No: 46892  IP: [192.*.*.*]

「あ」さんと同じ考えですが、単純にこんなのでもいいのかなと。
  ListBox1.Items.Add('バータ');
  ListBox1.Items.Add('パァータ');
  ListBox1.Items.Add('パオロ');

  ListBox1.Items.Text := StringReplace(ListBox1.Items.Text, 'ー', '魑', [rfReplaceAll]);
  ListBox1.Sorted := True;
  ListBox1.Sorted := False;
  ListBox1.Items.Text := StringReplace(ListBox1.Items.Text, '魑', 'ー', [rfReplaceAll]);

編集    削除
五十音  2014-11-21 00:29:49  No: 46893  IP: [192.*.*.*]

返信の皆様ありがとうございます。
stringlist
listbox
などのコードで処理するんですね。五十音ということでarrayの配列
にして順番を決めるのかと思っていました。

listboxに表示されたデータの前にlistboxのcount番号をつけて
番号と名前を表示させるのはどのようにするのでしょうか。
ソートした後に
for i:=listbox1.count-1 do begin
  listbox1.items.add(i);
end;
で数字だけでも表示させようと思ったのですが、よくわからない数字が表示
されるので教えてください。

編集    削除
deldel  2014-11-21 01:13:53  No: 46894  IP: [192.*.*.*]

for i := 0 to Pred(ListBox1.Items.Count) do begin
  ListBox1.Items[i] := IntToStr(i) + ListBox1.Items[i];
end;

とか?

編集    削除
五十音  2014-11-21 05:20:06  No: 46895  IP: [192.*.*.*]

ソートした後のListBox1.Items[i] := IntToStr(i) + ListBox1.Items[i];
は数字がソート前の数字も表示されます。
showmessage(Listbox1.items[i]);にするとソート前の状態になっているのが
原因かなと思うのですが・・・

ここまで教えていただいたのであと少しです。。
解決はほぼできました。
ありがとうございます。

編集    削除