[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]
『SORT(文字列)について』(てつ)
数年ぶりの質問です。会社で昔のプログラムをVB化しています。 そこで昔のプログラムでホストの並び順にSORTするプログラムがあります。 そのプログラムの作成方法について質問させてください。 IBMのEBCDIC順にソートするしたいのですが、WIKIPEDIAの順でもないので 自分で16進数(2桁)に変更してそれを並び替えようと考えてます。 その並び替え方ですが、クイックソートが早いと書いてますがネットのどれを 使えばよいかよくわかりません。
元のプログラムは COLSORT(1,1)(2,22) ←(1文字目から1文字、 2文字目から22文字でソート) という形です。 前工程でテキストファイルにしたものを読み込んでSORTする形式です。
エクセルに読み込んで区切り位置で区切り、それをエクセルの機能のSORTする手もあるかなって思いますが・・・ 今のところどうしてよいかさっぱりです・
今わからない点ですが、 ・上にも書きましたがクイックソートのSTRING型。 ・文字列を16進数化させる先(16進数化させた後、SORTし、普通の文字に戻すことはできそうですが・・・)
いろいろ書きましたが、わかりにくくてすいません。 要するにテキストファイルを読み込んで、変換テーブルで2文字の文字列(00からFF) に変換して、 変換後の文字列でSORTし、SORT結果を元の文字で書き出すプログラムです
・
昔は今ほど CPU 性能が良くなかったので、ソートのしかた一つをとっても いろいろと工夫を重ねたのですが、今やアルゴリズムの差を CPU 性能が補ってくれるので 数百程度のデータのソートであれば、ほとんど何を使っても差異がありません。
EXCEL の機能を使ってソートをしてもいいですし、バブルソートを使っても殆ど実行速度に 差は感じられないような気がします。
VBA を活用するなら、ご自身で書かれているように、A列にデータ、B、C列にソートキーを 書き出し、EXCEL でソートするといった方法もあります。
クイックソートは確かに早い方法ですけれど、アルゴリズムを理解して実装する手間を 考えると、頻繁に行う処理でもなければあえて使わないのも選択肢の一つかと思います。
まず、もとのテキストファイルの文字コードが何か。テキストの中身がアルファベットだけ なのか、漢字もあるのか。などが気になりますが、もしコード変換するなら http://support.microsoft.com/kb/216399/ja のあたりを参考にしてどうでしょうか。 (Mook)
上のリンクはよくわからなかったので、SELECT CASEで100個位CASEを設定し、 文字列を変換しB列、C列に書き出しエクセルの並び替えをしました。 最近どうもクイックソートの記事が少ないのはPC機能がよくなったからなんですね。 ありがとうございました。 まだまだ C言語等をVBに変換しなくてはいけないのでまたなんかあったらお願いします。(てつ)
よって、細かい箇所は、わかりませんが・・・・。
例えば、Ebcdicコードで A123 (hexでは c1f1f2f3) 123A (hexでは f1f2f3c1)
と文字列があった場合、
asciiでは、並び替えは 123A、A123の順で昇順ですが、
Ebcdicの場合、A123、123Aの順で昇順なのですよね?
並び替えは、A123、123Aの順で行いたいのですよね?
で、結果は、ascii(Windowsで表示できる文字列)で表現したいのですよね?
>自分で16進数(2桁)に変更してそれを並び替えようと考えてます。 >文字列を16進数化させる先 ファイルからデータを読み込むなら Byte変数の配列を使用して読み込めば、変換しなくても HEXでデータを得る事はできます。
>上にも書きましたがクイックソートのSTRING型。 これは、データが上か下かの判定をどうするか?ですよね? 漢字の上下の判定をどうするかの問題もありますが、
文字列の比較は、基本は頭から比較していきます。 Byte型の配列変数に読み込んで比較するなら、頭の1バイトから比較していきます。
1バイト目が同じだったら、2バイト目同士を比較、・・・・ 大小がはっきりしたところで比較終了です。
クイックソートのロジックに初めて携わるなら、一度は使ってみるのも悪くはないです。 クイックソートは、ランダムに並んでいるデータの真ん中のデータ(c)とその他のデータを比較し、 データをCより、上か下かで分けてく、これを何度も繰り返すことで、整列が完成するという方法です。
Cというデータと他のデータの大小を比較します。
数値なら、If a<c then ... else .... と簡単に算術比較演算子ですぐに判定できます。
ここを
>1バイト目が同じだったら、2バイト目同士を比較、・・・・ >大小がはっきりしたところで比較終了です。
というロジックで大小を比較する ということだと思います。
まずは、 >要するにテキストファイルを読み込んで コード体系が違うのですから、バイナリファイルを扱うのと同じです。
Ebcdicでは、テキストファイルの区切りコードって何ですか? 通常、Windowsでは、 &h0D0Aが区切り記号ですよね?
この辺りから調べて見ては?
http://ameblo.jp/blueskyame/entry-10244296193.html
クイックソートコード例、比較的わかりやすいと思います
ichinose
そうですね。 っせっかくですのでクイックソートも見てみます。 ちなみに Ebcdic といっても、会社独自のホスト?の並び順というものが あるらしく、記号類も含めて同じ順にソートする必要があるため、 ホストに16進数で00からFFまで入力したものの通常の表示文字をCASEで変換し B列に入力しました。 Case "." strg3 = "4B" Case "<" strg3 = "4C" Case "(" strg3 = "4D" ・・・という風に変換しています。(てつ)
>Case "." > strg3 = "4B" >Case "<" > strg3 = "4C" >Case "(" > strg3 = "4D"
これって、Ebcdic体系化で文字列をHEXコードに変換しているコードではないですか?
http://www.hitachi.co.jp/Prod/comp/soft1/manual/pc/d3J3820/ISUS0268.HTM
↑ここにEbcdicコードがありますが・・・、 .----&h4b <----&h4c (----&h4d
ですよね? つまり、提示されたコードは正に文字列をEbcdicコードに変換しているコードに見えるのですが、 違う点もあるのですか?
それとMookさんも投稿されていましたが、ソート件数は、大体何件程度なんですか?
ichinose
一晩考えて(夢で?)、私何か意味を間違えてました?
これ、Excelに普通入力された文字列をEbcdic配列で並び替えたい という事でしょうか?
だとしたら、Mookさんご紹介の変換プログラムをちょっと書き換えて・・・・。
'====================================================================== Function Translate(ByVal InText As Variant) As String Dim Temp As String, I As Long Temp = Space$(Len(InText) * 2) For I = 1 To Len(InText) Mid$(Temp, I * 2 - 1, 2) = Mid$(ASCII_To_EBCDIC_Table, Asc(Mid$(InText, I, 1)) * 2 + 1, 2) Next I Translate = Temp End Function
Function ASCII_To_EBCDIC_Table() As String ' ' Returns the following table as a string for use by the Translate ' function to translate an ASCII-ISO/ANSI string to an EBCDIC string. ' ' 00 01 02 03 37 2D 2E 2F 16 05 25 0B 0C 0D 0E 0F ' 10 11 12 13 3C 3D 32 26 18 19 3F 27 1C 1D 1E 1F ' 40 5A 7F 7B 5B 6C 50 7D 4D 5D 5C 4E 6B 60 4B 61 ' F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 7A 5E 4C 7E 6E 6F ' 7C C1 C2 C3 C4 C5 C6 C7 C8 C9 D1 D2 D3 D4 D5 D6 ' D7 D8 D9 E2 E3 E4 E5 E6 E7 E8 E9 AD E0 BD 5F 6D ' 79 81 82 83 84 85 86 87 88 89 91 92 93 94 95 96 ' 97 98 99 A2 A3 A4 A5 A6 A7 A8 A9 C0 4F D0 A1 07 ' 20 21 22 23 24 15 06 17 28 29 2A 2B 2C 09 0A 1B ' 30 31 1A 33 34 35 36 08 38 39 3A 3B 04 14 3E E1 ' 41 42 43 44 45 46 47 48 49 51 52 53 54 55 56 57 ' 58 59 62 63 64 65 66 67 68 69 70 71 72 73 74 75 ' 76 77 78 80 8A 8B 8C 8D 8E 8F 90 9A 9B 9C 9D 9E ' 9F A0 AA AB AC 4A AE AF B0 B1 B2 B3 B4 B5 B6 B7 ' B8 B9 BA BB BC 6A BE BF CA CB CC CD CE CF DA dB ' DC DD DE DF EA EB EC ED EE EF FA FB FC FD FE FF ' ASCII_To_EBCDIC_Table = _ "00010203372D2E2F1605250B0C0D0E0F101112133C3D322618193F271C1D1E1F" & _ "405A7F7B5B6C507D4D5D5C4E6B604B61F0F1F2F3F4F5F6F7F8F97A5E4C7E6E6F" & _ "7CC1C2C3C4C5C6C7C8C9D1D2D3D4D5D6D7D8D9E2E3E4E5E6E7E8E9ADE0BD5F6D" & _ "79818283848586878889919293949596979899A2A3A4A5A6A7A8A9C04FD0A107" & _ "202122232415061728292A2B2C090A1B30311A333435360838393A3B04143EE1" & _ "4142434445464748495152535455565758596263646566676869707172737475" & _ "767778808A8B8C8D8E8F909A9B9C9D9E9FA0AAABAC4AAEAFB0B1B2B3B4B5B6B7" & _ "B8B9BABBBC6ABEBFCACBCCCDCECFDADBDCDDDEDFEAEBECEDEEEFFAFBFCFDFEFF" End Function
例えば、
A B 1 123A =translate(a1) 2 A123 =translate(a2)
すれば、B1,B2はそれぞれ C1F1F2F3 F1F2F3C1 となります。
これをB列で並び替える方法では?
ichinose
回答がなかったのでスルーしていましたが、処理データの文字コードはそもそも何でしょうか。 データ内に漢字があるのですか?
EBCDIC では漢字を、各メーカーが独自にコードを実装しており、しかも制御コードにより 漢字区間を制御するタイプなのである部分の文字コードだけを見ても漢字かアルファベット かの区別がつかないケースもあります。 http://wiki.osdev.info/?plugin=attach&refer=%B4%C1%BB%FA%A5%B3%A1%BC%A5%C9&openfile=knj.txt
アルファベットと数字だけであれば(いわゆる ASCII 相当)、現在の範疇ですすめれば 良いと思いますが、まずそのあたりの前提を確認しておかないと後でご破算になりかね ませんので、ご注意ください。 http://kzworks.at.webry.info/200903/article_26.html
またこのあたりの話は多くの人が行いたい処理ですから、いちいち自分で実装せずとも、 ツールがある場合がありますので、まずはメインフレーム側(?)などに下記のような ものがないか探して見てはと思います(Windows でも探せばありそうですが)。 http://software.fujitsu.com/jp/manual/manualfiles/M080191/J2UZ7063/01Z2A/J7063-b-06-00.html (Mook)
そうなんですよ MOCKさんの言うとおり、ホスト形式と同一の順番にするためには ひとつずつ書き出してやらなきゃいけなかったんです。(うちの会社の仕様?) ただ普通のEBCDICと同じなのがほとんどなんですが・・・ 一応B列に書き出す方法で解決してますが、もう少し勉強をかねていろいろやってみます。 (てつ)
>ただ普通のEBCDICと同じなのがほとんどなんですが・・・ >一応B列に書き出す方法で解決してますが
ANKだけの変換でしかも「EBCDICと同じなのがほとんど」なら、
ASCII_To_EBCDIC_Table = _ "00010203372D2E2F1605250B0C0D0E0F101112133C3D322618193F271C1D1E1F" & _ "405A7F7B5B6C507D4D5D5C4E6B604B61F0F1F2F3F4F5F6F7F8F97A5E4C7E6E6F" & _ "7CC1C2C3C4C5C6C7C8C9D1D2D3D4D5D6D7D8D9E2E3E4E5E6E7E8E9ADE0BD5F6D" & _ "79818283848586878889919293949596979899A2A3A4A5A6A7A8A9C04FD0A107" & _ "202122232415061728292A2B2C090A1B30311A333435360838393A3B04143EE1" & _ "4142434445464748495152535455565758596263646566676869707172737475" & _ "767778808A8B8C8D8E8F909A9B9C9D9E9FA0AAABAC4AAEAFB0B1B2B3B4B5B6B7" & _ "B8B9BABBBC6ABEBFCACBCCCDCECFDADBDCDDDEDFEAEBECEDEEEFFAFBFCFDFEFF"
前回投稿の↑のこの値を独自コードの箇所だけ変更でよいと思いますが・・・。
これが出来ているなら、B列の整列で OKですよね? 尚、この状態なら、Excelのソートを使った方が良いですね
因みに、クイックソートを使うなら、Stringの比較は、Strcomp関数があります。
ichinose
[ 一覧(最新更新順) ]
YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki.
Modified by kazu.