Comments
Description
Transcript
の中での末尾数字を意識した ファイル ・ソート
岡山大学経済学会雑誌 3 1 ( 3 ), 1 9 9 9,2 5 5 -2 6 4 LZH の中で の末尾数字 を意識 した フ ァイル ・ソー ト 藤 本 喬 雄 フ ァイルを次 々,LZH ファイル ( 吉崎栄寿氏の LHA ( ver . 2. 13:1991 午) に よって圧縮 された フ ァイル) の中へ追加保有 してい くと,時折 ソー ト した くな る。各月 ごとの LZH フ ァイルを構成す る場合 ,各週 ごとに作成 さ れた フ ァイルが追加 され る。その際 ,フ ァイル名で ソー トしたいのだが ,普 通 の ソー ト ・プ ログラムは ,各文字 ごとに比較 してい くので ,昇順 の場 合 , " AAAI O. DOC"の方が " AAA2. DOC" よ り前に きて しま うO 末尾 の数字 を全体 として数 とみな し,後者を前に お きた いの で ,プ ログ ラムを作成 し 985 年 に Bo r l and ( 現在 の I npr i s e) よ り発売 された , た。使用 した言語 は ,1 Tur boPas calver . 3である。DOS上で汎用的で ,Wi ndo wsで も,DOSに抜 ければ使用 で きるQ メモ リが ,6 4 KB,1 2 8KB の時代 なので ,データ型 と し て ,Wo r dや Longi ntがない。以下 ,プ ログラムの要点を説 明す る。 ( 1 ) フ ァイル名 リス トには , レコー ド型 ( Fi l eCont ent ) の配 列 を用 いた。 フ ァイル名 と,LZH フ ァイルの中での,開始バイ トと長 さを含む。この配 00 0 個 のフ ァイルを含む ことがで きる。個 々のフ ァイル用の動的な 列は ,2 メモ リ配 分 はや め て ,最初 か ら, ヒープ ・エ リアに 2000個 分 の メモ リ 40 KB を とった。現在 の普通の メモ リ量な ら数万個 を扱 えるが ,20 00個 で 充分であろ う。 ( 2 ) 元のフ ァイルのタイ ム ・スタンプを変 えないために ,I NT 21h ( AH57h) を使 って ,DOS の フ ァ ン ク シ ョン ・コール を 行 った 。 Tur bo - 255- 6 2 2 Pa s c alver . 4の ,Set FTi me と異な り,フ ァイルを閉 じてか らや らない と いけない。 ( 3 ) ソー トは ,qu i c ks or tを使 った. C言語 の qui c ks or t関数がないので , BASI C 用 の ものを ,Pas c alに書 き直 した。 ( 4) フ ァイルの読み書 きは ,Bl oc kRead,Bl oc kWr i t eを用いた。お もしろい ことに,長 さのパ ラメータは整数 としてほ負数で も,Wo r d として解釈 し て くれ るのである。今回は ,この ことは利用 しなか ったO フ ァイルの 1レ コー ドは , 1バイ トとして設定 しオープンした。 ( 5) LZH の中で使われている ,Lo ngi ntに対処す るため r e al 型 の変数 を用い た。 フ ァイル の長 さに も ,r ea l型 を使 った 。 pr oc edur es or tの 中 で , Longi ntを 1バイ トづつ ,r e alに変換 している。 ( 6 ) 次 の フ ァイル情 報 を見 つ け るた め に ,48バ イ ト先 読 み を 行 った 。 Bl o ckRead を行 う前に ,LongSe ek で,適切 な切 れ 目に戻 す 必要 が生 じ た。 ( 7 ) フ ァイル名の末尾 の最大 3桁 ( 半角) を数 とみなす ことに したO末尾か らスキ ャンして ,数字でない ものが現れた ら打ち切 るO打 ち切 られた前 の 部 分 が共通 で あれ ば ,数 と して の 大 き さが 順 番 を 決 め る o pr oc edur e CompSt r i ng の部分である。 ( 8) 付録のプ ログラムには ,デバ ッグ中に使 った メ ッセージ印刷を コメン ト として残 してある。 LZH ファイルにおけ る関連 した部分の構造について ,述べてお こ う。圧縮 された 1個 1個 のフ ァイルは ,LZH フ ァイルの中で独立 したバ ラバ ラの状 態である。 目次 の ような ものはな い 0 3バ イ ト目に , "-1 h" ( 2 Dh,6 Ch, 6 8h)がある。 8バイ ト目か ら 4バイ トが , フ ァイル ・デ ィ レク ト1 )か ら とった フ ァイルの長 さであ る ( pr oc edur es or tの真 ん中 あた りの処 理 を参 照)0 1 5 バイ ト目か ら 2バイ トが フ ァイル更新 の時刻 ,1 7バ イ ト目か ら 2バ イ トが年月 日を示す 。2 2バイ ト目にフ ァイル名 の長 さが 1バイ トで表わ され - 256 - LZ Hの中での末尾数字を意識 したファイル ・ソー ト 6 2 3 ている。圧縮 された フ ァイル全体 の長 さは ,フ ァイルの長 さ+ファイル名の 長 さ+2 7,とな る。付録 プ ログラムにおけ る ,p r o c e d u r es o r tの リe n g t hの 計算を見 られたい。Lo n g i n tがないので ,この変数 は r e a l型 に しているO現 在 の開始点に ,この リe n g t hを加 えれば次 のフ ァイルの開始点になる。 プ ログラム自体 のテキス ト ・ファイルは ,1 0, 3 8 0 バイ ト,コンパイル後 の COM フ ァイルが ,1 5, 1 7 5バ イ T,EXE に変 換 して ,LZEXE ( Fa b r i c e 9 8 9 年) で圧縮す ると,l l , 5 9 5 バイ トにな った。 Be l l a r d氏に よるもの :1 LHA は ,v e r . 2. 1 3 であることに注意 してほ しい。長 さ 1 MB以下 のフ ァイ ルな ら 1,2秒 で ソー トは終わ るが ,時間が異様 にかか る場合 ,ソー ト後 の 長 さが異な る場合 ,全 て順調 に修了 した よ うに見 えて もソー ト後 のフ ァイル に対 して LHA が フ ァイル異常を報 告 す る場 合 ,元 の LZ H フ ァイル が , v e r . 2. 1 3よ り旧い版 で作成 された と考 えて よい。もっとも流布 した この版で 解凍 ,圧縮 を し直せば よい01 9 9 1 年 よ り旧いLZ Hフ ァイルの場合 ,この可能 性 が高い。 種 々の LZ H フ ァイルの ソー トを してみたが ,2 7 MB の もので ,1 9 0 0 個以 上のフ ァイルを含む場合 ,I n t e 1 8 0 4 8 6,6 6 MHzの PCにおいて ,ソー トに 3 分かか った。解凍 して DOS 上で ソー トし,マニ ュアルで入れ替 えるよ りも ま しであると考 える。 Wi nd o wsもフ ァイル ・リス トのオプシ ョンで,この種 の ソー トを許 す よ うにすべ きであろ う。I E4,I E5のス ク リプ トが既に利用可能か も知れない。 - 257 - 624 付録 Pas ca l( vcr .3) プ ログ ラム progra mLZHS ORT, '(*S orti ngL HZarchl vesforTt l rb oPacalvcr. 3. OIL*) ( *TF: 1 999-8-24( Tue.),8-29( S n ): u Yashl na:Cl oudy.★) B:tralli ngmmeralsupto3di gi ts.*) ( *N const .(*Ma xnumberoffil esall owedl naLZH*) Z 4 A X_F工LE≡2000, bufl en=24576, . rbl l fl en二24576. 0; b 盲f J盲na=24624, ・(It or eadali ttl emoreaddi ti onalbytesI) t . ypeRegRec=record caseI ntegerof l:( A X. BX. CX. DX, BP. SI. DI. Ds. ES. F lags:i nteger), ・ 2:( Al. A H. BL, BZ T . CL, CH, DL, DH:byt : e); end; typeFil eContent : =recor d Name:Strl ngl1 2】; Start:real; Lengt h:real, ' end; t ype str1 2=stri ngl 1 2], ・ str13=strl ngl 13】, . t ype Flle Array-arra y【1‥Z 仏Xj ILE]ofFil eContent; Var PFile Array:A File Array; FF工. OF I. EXT: St : r13; p _str12:Strl 2, . p _byte J :byte, ' p 」) yte 」1 1:ー byte; Ihandl es* ) HjFI.H_OFI:i nteger;( fl.f2 : f il e; l astbyte: r eal; : i nteger; i,j NⅦn Read.Nt wWrlt , ten:i nteger, ' buf : array【1‥buf _l e naloft yte; sbuf : i nteger, I Regs : RegRec; me:i nteger; f _date.f _ti procedur ei nitia112 ; e, ' begi n lft Para mStr( 1) く>日) th en FFI: =P ara nStr(1) el sebegi n vri te(' * * *Pleasekeyinthelnput-filename.(ext.default.LZH).=リ. ・ r eadl n( FFI); end; if( Par anSt : r( 2) <>T') tt l en OFI: =P ara mStr( 2) el seb egi n wri t : e(' * * *NovkeyintheOl l tput-fil ena me. ( ext : . defa ult. LZ2).=' ). ・ readl n( OF工); end, I ifPOS(I.I , FFI) =O t : h enFFI: =FFI +I. L2 : t l l ; l ifOFI =l th enbegi n -2 5 8- LZH の中での末尾数字を意識 したファイル ・ソー ト 6 2 5 0FI: =F FI; OFIl 01 1 . =Ct I R( POS(I.I. FFl) -i); e l d, ' i fPOS('.I , OFI) =Ot . henOFI: = OFI+I. LZ2r , I fori: =ltoLengt h( FFI)doFFIl i]: = UpCase( FFIli]), ' f ori: =ltoLength( OFI)doOFI【 i]: = UpCase( OFI【 i]), ・ lfFF工= OFIthen begi n writ . el m(r xxxThesamena L nef orエ nput良0utpl l tFil es!Tr yagai n.I ); halt(1); end; 1: =P OS(I.t . FFI); i fl>1theT IEXで: =Copy( FF工.i +1.3); if( i=0)or( EXTく>■ LZ H■ )t hen begi n vrit . el m(. xxxl nputFileisnot【 LZ H【lTryagai n.'). I halt(1); end; (*t x )m akeASCIIZstr ings★ ) i: =Length( FFI), I Q), FFl, i +1); l nsert( Chrt *I nsertmakesthestri ngl onger.*) FFIl 0]: =Chr( i), I ( i: =Length( OFI), ' I nsert( Chr( 0), OFI. i +1); OFIl 0]: =Chr( i); assi gn( f l, FFI), ' assi 9m( f2, OFI). I t Sト ) fl.1); Reset( t SI+) i fI Or es ult . <>O th enbegi n vrite] 山(' Ⅹ王Ⅹ工 nputFil edoesnotexi st!Tr yagai n.-); halt(1); end; Rewrite( f2.1), . l astbyt : e: = LongFil eSi z ; e( fl) +0. 001. Vr it el n(. ‥.Fil eLengthoft . FFI.■三㌧ last . byte: 1 0: 0.'bytes.I ), . (*S _buf:anegati veval ueOK.SeeBl ∝kread.*) S _buf: =Si 男 eOf( buf). ' end, I( *endofinitialiZ ; e* ) procedur eopen_ha ndl e( varnJ il e:str13, .varh j il e:i nteger), ' begi n WithRegsdo begi n AX: =$3 DOO; Ds: =DSeg; DX: = Ofs( n Jil e) +1; Z 4 sDos( Regs); h fil e: = AX, en a, . end, . -2 5 9- 6 2 6 p r ocedur eclo s e _ h and le ( h b e gi n vl t hReg sdo b e gi n A X:=$3E O O; B X: =h f i l e , ' Ms Dos (R e g s ) , I e nd; e nd, ' j il e: in teg er ) , ' procedur eget _ti ne( varnj ll e:Btr13, .Tarh _fil e, Ld a te,Lti me:i nteger); begi n open_ha ndl e( n_file,h j il e), ' wit hBegsdo b egi n A R: =$5700, A (*G et . theti nesta mpOfl nputfil e.*) BX: = h fil e; Hs I ) os TRegs ). ・ fdate: = DX, I fti me: =CX; end; cl ose_ha r dl e( h J il e), A I( *e ndofget . _ti ne*) end, procedur eset _ti me( varnJ il e:st : r1 3;varhj il e:i nt . eger, ' Ld ate,Lti ne:i nt . eger); begi n open_ha ndl e( nj il e,h j il e); withRegsdo begi n ISettheti mestampofl npl l tfil e.I) AX' . =$57 01; ( 8Ⅹ: =h j il e, I (*AL=$01★) CX: =fti me; DX: =Ldate, ' Hs Dos( Regs); end, . cl ose _han血e( h _fil e); end, I( *endofseLti me*) f t mcti onCompStri ng( Sl.S2:str1 2):Bool ea n, I var SI O.S20:str1 2, ・ pl,p2:i nteger; nl.n2:i nteger; nll,n1 2,n13,n21,n22,n23:i n teger, ・ ' i e:i nt . eger, begi n ( * wri tel n(r Sl 三一. Sl. , 'S2=■. S2), .I) SI O: =Sl;S20: =S2; pl: =Pos(I .■ .Sl) -1; -i; p2: =Pos( ,S2) i fpl>OthenSl 【 0): =Chr( pl), ・ i fp2>Other LS2[ 01: =Chr( p2); ' . . nll: =0;n1 2: =0;n13: =0; if( Sl【 pll >=■ 0' )and( Sl【 pl】 くニー 9' )t hen -2 6 0- LZH の中での末尾数字を意識 した フ ァイル ・ソー ト 6 2 7 b egi n l.l e) ; Val( S l【 pl 1 .ml Sll 0] : = C h r( pl -1) ; i f( Sl t pl -1】 > =■ 0)a nd( Sl【 pト1 1 く =■ 9)t I l e n b e gi n Va l( Sl 【 pト1 1.n1 2.1 e) ; l f S ( l s l 1 0 [ ] 責_ C 2 hf 翫 亨); a nd( Slt。ト 21 く 三. ,・ )t h e n b e gi n Val( Sl【 pl 2】 .n1 3′l e) ; Sl【 01; = C h r( pト3) ; e n d; e n d; e nd; nl: = n1 3 *1 0 0 + n1 2 *1 0+ ni l; n21: = 0;n 2 2: = 0;n2 3: = 0; i f( S 2l p 2] > =1 01 )a nd( S 2l p 2] < =' 9' )t h e n b egi n Va l( S Z【 p 2】 .n21.1 e) ; S 2 [ 01: = C hr( p2 -I) ; i f( S2l p2 -1 1 > 三一 0)a nd( S 2l p 2 -1 】 く 三一 9. )t h e n b e gi n Val( S 2l p2 -1] .n2 2,i e) . ' S 2[ 01 . ' = C hr( p2 -2) , ' i f( S2l p2 2] > =1 0. )a n d( S 2l p2 2] < =1 9. )t h e n b egi n Val( S2l p2 2] ,n23,i e) , I S 2[ 0]: = C h r( p2 13) . e nd, ∼ e n d; e nd. n2: = n23 ★1 0 0 十 m2 2 ★1 0 + n21; ( I . ‥ ( t vr lteln -. S1.㌔ m I.S 2.;l : =一n l ′-;n =' .nZ );♯) . i fSl く S 2t h e na) mp St ri n g: = T R t T E; 1 fSl = S 2t h e nl fnl < n2t h e nC o m t St ri ng: = T R U E el S e i fnl = n2t h e n b e gi n i fSI O く S 2 0t h e nC o m pS t r i n g. I = T R U E el s eC o np S t ri ng: = F AL S E; e nd el s eC o n pS t r i ng: =F A L S E, ' i fSl > S 2t h e nC o n p St r i n g: = F AL S E; e nd; n. I f t mc ti o nC o np S t ri n g E( Sl,S2:s t r1 2):B o ol ea b e gi n i fC o mp S t r i n g( Sl.S 2)t h e nC o mP S tr i n g E: = T R U E el s e i fSl = S 2t h e nC o mp S tr i ng E: = T R U E el s eC く mp S tr i n g E: = F AL S E; e nd; pr o c e d ur eS va p Ar r a y( A, a: i nt e g er) , I γa r T e np:F i l e C o nt e nt : , I b egi n T e np: = P Fi l e Ar r a y-l A] . I P File Ar r a y-【 A]: = P Fl l e Ar r a yAl Bl; ー 261- 2 6 2 8 P Fi l e Ar r a y-l Bl : = T e J n P, ' e n d; pr o c e d ur eO ui c k S or t . ( L o w,Hi g h:i nt e g er) ; V ar R a n dl n d e x:i n t e g er; P a r ti ti o nI .S t r1 2; i, j:i nt e g er, . b e gi n i fL o w<Hi g ht . h e n b e gi n ( *t h ec a s eo f2el e m e n t s★) 工 FHi g h-L e w = 1t h e nb e gi n l FC o mp S t ri n gt P Fi l e A r r a yー( t t i g h] . Na me.P File Ar r a yAtL o 打 1. Na me)t he n S wa E Ar r a y( L o w, Hi g h) ; e n d el s e b e gi n ( *c e n tr eel e ne ntr a nd o ml yc h o s e npl a c e da tt . h ee nd.I) R a n dl nd e x: =R A ND O M( r L i g h L o w+1) + L o w, ' S w a p Ar r a y( t t i g h, R a n dl n d e x) ; P ar ti t i o n: IP Fi l e Ar r a yー【 Hi g h]. N a me, ' r e p e a t ( Ic o m p a r et h eb ot he n dst o wa r dt h ec e ntr e.★) 1; =L o w; ]: =Hi g h, I w hi l e( iくj)a nd( C o n p S tr i ng E( P F i l e Ar r a yAl i1. Na me,P ar t i ti o n) )d o l: =1+1 ; w hi l e( j>i)a n d( C o mp St r i n g E( P a r ti ti o n.P Fl l e Ar r a yAl jl. Na me) )d o j: =3-1 , ' ( *1 fn otr ea c h e dt h ec e ntr e,t h et woel e me nt s*) ) ( * a r ee xc h a ng e d. * i flくjt h e n b e gi n S w a p Ar r a y( i, i) ; e nd; t mti li> =3, ' ( *t h ec e nt . r eel e m e n ta tt h er i g h tpl a c e・*) S w a p Ar r a y( i, t l i g h) , ' ( *Q ui c k S or t . i sc a l l e dr e c ur si v el y.*) ( *t o削. p pr eS St h eus eofs t . a c k ★) ( *t h el e s s erel e me nt sd o n ef i r s t. ★) i f( i-L o w)<( Hi gl-i)t h e n b e gi n Q ui c k S o r t( L o w.i-1) . l Q ui c k S or t( i+1.Hi g h) , . e T d el s e b e gi r L O ui c k S or t( i+1,t l i g h) ; O ui c k S or t . ( L o w,i-1) , ' e r d. I e n d;(i fHi g hL o w=1・ . . el s eb e gi n) e n d, 'ti fL o w< Hi g hI e n d; -2 6 2- LZ Hの中での末尾数字 を意識 した フ ァイル ・ソー ト procedur esort, I γar Lstart,r _l ength:real, ' tnpJ engt h:real. ' bl l fco unt:i nt . eger, ・ r emai nder,k:i nteger, I ist , art:i nteger, ' b egi n r _start: =0. 0; i: =1; j: =0; repeat ( *mockRead:i ntegertreatedaswor d.*) r e peat Bl ock Read( fl.buf.S-buf.Nu皿Read); コ: =j +1, ' fl,LbufJ en*j);(*Donotforgettoadjust!*) LongS eek( u ntll( L Startく=Lbl ユ Ll entj); if( Nl l mRead< >O)t hen n be gi ( * wri tel n(t Nu 皿r ead=I , Nu瓜ead);*) でepeat ′ i, ;j=', j, I ;Lstart=.,rlStart), ・*) ( * writel n(' i=■ Lstart: =Round( r ーStart-Lbuf J en*( j-1)+0. 001), I ( ****l ongi ntnota vaila bl ei nTPv. 3****) t np J ength: =0. 0. ・ p _byte_i: =ADDR( buf【 i _start+8】). t npJ engt ・ h: =t np J eng th+p _byte_1-, ' p _byte_1: =ADDR( buf【 Lstart+9日 , . t np J engt h: =t mp J eng th+256. 0* p_byte _I-, ' p _byte -1: ≡ADDR( bl ユ f【 Lstart+1 0日 ; 」 A, I t 皿p_1 engt : h: =t mp _l eng th+256. 0*256. 0*p_byte p _byt ・ e J : =A DDR( but【 Lstart+11日, ' t np J engt h: =t np J eng th+256. 0*256. 0*256. 0*p_byte_lA : p _str1 2: IADDR( buf【 L3tart : +22]); p _byte Jl l: =ADDR( bl l f【 Lstart+22]). ' PFile Arra yー【 i]. Na me : ≡p _Strl T, ' PFile Arra yー【 i】. Start : ≡Lstart; r _l ength: =27. 0+tz q L1 ength+p_byt . e_nlA. '( *L2 : Hstr u ct ure*) yAl iI. Lengt h: =r _l ength, ∼ PFileArra LStart: ≡LStart+r _l ength, I i: =i+1; , ・1 er gt . h=., I _l ength: 1 0: 0);★) ( * writel n( p _str1 2-,' n til( u Lstart :>( r _buL 1 en*j))or( r _start>(l astbyte-5. 0)). ・ fl.r」) uLl en*j), ・ Lo ngSeek( e nd; u ntil( NumRead=0)or( I _st , art>(1 astbyte-5. 0)), . I QuickSort : ( 1,i-1), forj: とlto( i-1)dobegi n j】. Start), I Lo ngSeeJ E ( fl′PFileArrayー【 mes*) ( *ho vma nyti bufcou n t: =Trunc(( PFil eArray-l j]. Length+0. 01) /r _but _l en); ( * wr -i tch(buLcou n t=1 , but _co n t);★) u if( buLcount=0)then b egi n 81 ockRead( fl.but,Round( PFil eArray-l jI. Length+0. 01L Nt nRead), ・ 81 ock Write( f2,buf.Nun Read,NunWritten), ・ - 2 6 3 - 629 6 3 0 end el se n be gl fo r汰 : =1tobl l fcountdo b egi n Bl ock Read( fl,buf.buLlen.NumRead), ' Bl oc棚ri te( f2,but.NumRea d,Nl 1 如I ri tten); en d; r e mai nder: =Round( PFll e Arra yAl j). Length- LbuL l en*buLcount+0. 01). ・ ( * writeh(r r e J n ai nders = ' 一 remal nder), '*) Bl ockRead( fl.buf.rc Aai nd e r,Nt nRea d); Bl ockWrl te( f2,buf,mnRead,NunWrltten), ・ e nd; end, ' buf【 1】: =0, I( *thel astb yt : eofLZH*) 81 ock Write( f2,buf.1.Nu nWritt , en). ' end;(Iendofsort*) pr ocedur eepil ogue, I begi n cl ose( fl) ; cl os e( f2) , . wri tel n(一触 ★Sorti ngco mpl etedi***TF***-) ,・ end, . (州 ★皿ai nr ol l tl ne柑★) begi n Ne w( PFil e Arra y), I i ni ti ali 五e, ' F 工.Hj FI.Ldate,f _time). ' get : _ti me( F sort; ( ★ forj: ≡lto( ト 1)do vri tel n( PFile Arra yAHl. Na me);*) epil o9 ue; set : _ti me( 肝Ⅰ′H _OFI′Ldate,f _ti me); 11 e Arra y); Dispose( 押■ end. -2 6 41