HSPポータル
サイトマップ お問い合わせ


HSPTV!掲示板


未解決 解決 停止 削除要請

2011
1105
おけらテキストデータのインデックス位置から行番号を調べる方法7解決


おけら

リンク

2011/11/5(Sat) 13:42:39|NO.42818

 改行で区切られたテキストファイルから特定の文字列を検索するデータベースソフトを作成中なのですが、検索にinstr命令を使うと検索キー位置はテキスト先頭からのインデックスとして返されます。そのインデックスから検索キーが含まれる行の行番号を導き出す方法はありますでしょうか?

※メモリノートパッド命令で全行をnotegetして個々の行を検索すると行番号は自動的に分かるのですが、元のテキストファイルがそこそこ大きな容量なので、軽量化のため上記方法を取りたいと思っています。



この記事に返信する


mamo

リンク

2011/11/5(Sat) 14:57:22|NO.42819

一行毎にチェックする感じにしたら
改行コードまでの文字数と改行コードの数を使うだけでもいけるんじゃない?



TTRUKO

リンク

2011/11/5(Sat) 17:08:33|NO.42820

↓instrで改行の数を調べるのが一番単純で速度もそこそこです

#define CRLF_SIZE 2 tx = "あいうえお\n" tx += "かきくけこ\n" tx += "さしすせそ\n" target = "け" targetIndex = instr( tx, 0, target ) if ( targetIndex != -1 ) { // 行数チェック nowIndex = 0 repeat index = instr( tx, nowIndex, "\n" ) if ( index != -1 ) { nowIndex += index + CRLF_SIZE if ( targetIndex <= nowIndex ) { count = cnt break } } else { count = cnt break } await loop mes "「" + target + "」は" + str( count ) + "行目" }

↓あまり変更が発生しないテキストなら、予めインデックスを調べておいたほうが速いです

#define CRLF_SIZE 2 tx = "あいうえお\n" tx += "かきくけこ\n" tx += "さしすせそ\n" // 事前準備 notesel tx max = notemax noteunsel dim txSixe, max nowIndex = 0 repeat max index = instr( tx, nowIndex, "\n" ) if ( index != -1 ) { nowIndex += index + CRLF_SIZE txSixe.cnt = nowIndex } else { txSixe.cnt = strlen( tx ) break } await loop target = "け" targetIndex = instr( tx, 0, target ) if ( targetIndex != -1 ) { // 行数チェック repeat max if ( targetIndex < txSixe.cnt ) { count = cnt break } loop mes "「" + target + "」は" + str( count ) + "行目" }

↓これもあまり変更しないテキスト用。ほぼ最速ですが、事前準備は一番面倒です^^;

#define TAB_SIZE 1 max = 0 tx = "あいうえお" + "\t" + str( max ) + "\n" : max++ tx += "かきくけこ" + "\t" + str( max ) + "\n" : max++ tx += "さしすせそ" + "\t" + str( max ) + "\n" : max++ target = "け" targetIndex = instr( tx, 0, target ) if ( targetIndex != -1 ) { // 行数チェック getstr cntStr, tx, targetIndex + instr( tx, targetIndex, "\t" ) + TAB_SIZE count = int( cntStr ) mes "「" + target + "」は" + str( count ) + "行目" }



ひらまる

リンク

2011/11/5(Sat) 17:39:32|NO.42821

splitのstatに分割数が入るのを利用した楽な書き方。速度は…普通?

元の文字列 = "あいうえお\n" 元の文字列 += "かきくけこ\n" 元の文字列 += "さしすせそ\n" 元の文字列 += "たちつてと\n" 元の文字列 += "なにぬねの\n" mes ">元の文字列" mes 元の文字列 + "\n" 検索文字列 = "け" 検索結果 = instr( 元の文字列, 0, 検索文字列 ) if 検索結果 != -1 { 検索結果位置までの文字列 = strmid( 元の文字列, 0, 検索結果 + strlen( 検索文字列 ) ) mes ">検索結果位置までの文字列" mes 検索結果位置までの文字列 + "\n" split 検索結果位置までの文字列, "\n" mes "「" + 検索文字列 + "」は" + ( stat - 1 ) + "行目" }



おけら

リンク

2011/11/5(Sat) 19:47:24|NO.42825

mamoさん、TTRUKOさん、ひらまるさん、回答ありがとうございます。

予め改行位置インデックスを調べる方法、split命令のstatを使う方法は目からウロコでした。工夫次第で標準命令だけでも結構いけるものですね。
元のテキストファイルは数種類の区分がありそれぞれの区分末尾に定期的にデータを追加する仕様なので、頂いたアイディアを上手く組合わせればかなり軽いものができそうです。

アイディアだけでなく、たくさんの分かり易いサンプルスクリプトまで作って頂き本当にありがとうございました。m(_ _)m



HK2

リンク

2011/11/5(Sat) 22:56:14|NO.42828

split命令を使用することはお勧めできません。
以前、この命令でcsv形式のデータを分解しようとしたのですが、
とても時間がかかって使えるものではありませんでした。
HSPで自分で実装したほうが圧倒的に早かったです。
その時のデータの個数は10万を超えていました。


#uselib "winmm.dll" #func timeGetTime "timeGetTime" number=100000 sdim string,number*5 string="test" mes "データを準備しています。" repeat number-1 string+=",test" loop mes "準備完了" wait 100 dst="" mes "分解中" timeGetTime starttime=stat split string,",",dst mes strf("分解完了。\n分解数は%d個でした。",stat) timeGetTime mes strf("処理時間は%dmsでした。",stat-starttime)

こちらの環境(2.1GHzのCPU×4)では実行に87秒かかりました。
1.2GHzのCPUの環境でもテストしていますが、なかなか終わりません。
終わると信じて、待っています。
CPUクロック周波数が性能のすべで手はありませんが、周波数だけ書かせていただきました。



HK2

リンク

2011/11/5(Sat) 23:11:55|NO.42829

信じる者は報われるようです。

1.2GHzでの結果は、1482秒でした。
20分以上もかかりました。

先ほどの投稿で、最後に誤字がありました。

誤「CPUクロック周波数が性能のすべで手はありませんが」
正「CPUクロック周波数が性能のすべてではありませんが」
「て」と「で」が逆になっていました。



ROL

リンク

2011/11/6(Sun) 03:54:35|NO.42834

>とても時間がかかって使えるものではありませんでした
split命令というか配列の自動拡張に時間がかかってるみたいです。
あらかじめ予想されるより多めに配列を確保しておけば問題ないです。

#uselib "winmm.dll" #func timeGetTime "timeGetTime" number=100000 sdim string,number*5 string="test" mes "データを準備しています。" repeat number-1 poke string,4+cnt*5,",test" loop mes "準備完了" wait 100 sdim dst,64,number mes "分解中" timeGetTime starttime=stat split string,",",dst mes strf("分解完了。\n分解数は%d個でした。",stat) timeGetTime mes strf("処理時間は%dmsでした。",stat-starttime)



ONION software Copyright 1997-2023(c) All rights reserved.