WEB相談室

Webページ作成に関しての何でも掲示板です。

タイトル:2.頻繁に出てくる文字を検出したい

はるか [WriteDate : Sun May 13 15:04:35 2001]

もう一つの質問なんですが、Perlで、指定されたページ中に
頻繁に出てくる文字列を検出するプログラムを作りたいんですが、
どうしたらいいんでしょうか?

例えば、「明日があるさ、明日がある」だと、
「明日がある」という文字列を返してくれるような・・・。

教えて下さい。よろしくお願いします。
もう一つの「1.」の方の質問もよろしくお願いします。
色々とすいません(__;)


andi [WriteDate : Sun May 13 15:42:41 2001]

何をもって「文字列の切れ目」と判断されるのでしょうか。
不可能ではないかも知れませんがプログラムだけでなく国語の知識も必要ですね。

# 歌詞は著作権の対象になります。
# 無闇に他人のサイトに書き込むのはやめましょう。
# (どこからが歌詞と言えるのかは分かりませんけど)

> もう一つの「1.」の方の質問もよろしくお願いします。

あなたのサイトではないのですから「1」とか「2」とか
自分の都合だけで番号を付けるのはどうでしょうか??


バギンズ [WriteDate : Mon May 14 00:06:35 2001]

>頻繁に出てくる文字列を検出する
データ圧縮のアルゴリズムに近い物がありますね。
そっち方面を調べてみてはいかがでしょう?


R.M [WriteDate : Mon May 14 01:05:18 2001]

力業で遊んでみたり(死)
英単語で区切っているというわけでもなく、2バイト文字に対応しているというわけでもなく、使えない仕様になっています。
EUCだったら簡単に実装できると思いますが――

$string に処理対象の文字列を入れて実行します。

while ($string) {
 next if (substr($string, -1, 1) eq "\n");
 next if (substr($string, -1, 1) eq " ");
 next if (substr($string, -1, 1) eq "\t");
 $k = length($string);
 for ($i=1; $i<=$k; $i++) {
   last if (substr($string, -$i, 1) eq "\n");
   next if (substr($string, -$i, 1) eq " ");
   next if (substr($string, -$i, 1) eq "\t");
   $hash{substr($string, -$i, $i)} ++;
 }
} continue {
 chop($string);
}
@keys = keys(%hash);
@keys = sort grep {length($_) > 2 && $hash{$_} > 1} @keys;
&junkdel;
@keys = sort {reverse($a) cmp reverse($b)} @newkeys;
&junkdel;
foreach (@newkeys) {
    print "$hash{$_}: $_\n";
}
exit;

sub junkdel {
 undef($n);
 undef($m);
 undef(@newkeys);
 for ($i=$#keys; $i>=0; $i--) {
   if (index($m, $keys[$i]) == -1 || $hash{$keys[$i]} != $n) {
     push(@newkeys, $keys[$i]);
   }
   $m = $keys[$i];
   $n = $hash{$keys[$i]};
 }
}


R.M [WriteDate : Mon May 14 01:05:19 2001]

力業で遊んでみたり(死)
英単語で区切っているというわけでもなく、2バイト文字に対応しているというわけでもなく、使えない仕様になっています。
EUCだったら簡単に実装できると思いますが――

$string に処理対象の文字列を入れて実行します。

while ($string) {
 next if (substr($string, -1, 1) eq "\n");
 next if (substr($string, -1, 1) eq " ");
 next if (substr($string, -1, 1) eq "\t");
 $k = length($string);
 for ($i=1; $i<=$k; $i++) {
   last if (substr($string, -$i, 1) eq "\n");
   next if (substr($string, -$i, 1) eq " ");
   next if (substr($string, -$i, 1) eq "\t");
   $hash{substr($string, -$i, $i)} ++;
 }
} continue {
 chop($string);
}
@keys = keys(%hash);
@keys = sort grep {length($_) > 2 && $hash{$_} > 1} @keys;
&junkdel;
@keys = sort {reverse($a) cmp reverse($b)} @newkeys;
&junkdel;
foreach (@newkeys) {
    print "$hash{$_}: $_\n";
}
exit;

sub junkdel {
 undef($n);
 undef($m);
 undef(@newkeys);
 for ($i=$#keys; $i>=0; $i--) {
   if (index($m, $keys[$i]) == -1 || $hash{$keys[$i]} != $n) {
     push(@newkeys, $keys[$i]);
   }
   $m = $keys[$i];
   $n = $hash{$keys[$i]};
 }
}


ふじ [URL] [WriteDate : Mon May 14 02:46:02 2001]

kakasi を使って、単語を分解するという手もありますね。(他力本願)
http://kakasi.namazu.org/index.html
http://www.daionet.gr.jp/~knok/kakasi/

Perl と Text::Kakasi で簡単に書くと、

use Text::Kakasi;
Text::Kakasi::getopt_argv('kakasi', '-ieuc', '-w');
$split_str = Text::Kakasi::do_kakasi($str);
@words = split(/\s+/, $split_str);

で、$str が @words に単語ごとに分割されて入ります。
例:
入力 : 私の名前は「ふじ」です。
出力 : 私 の 名前 は 「 ふじ 」 です 。

ただこれだと(Kakasiの知っている)単語ごとにしか分解できないですし、
句読点や記号類が大量に(単語として)マッチするので、これは適宜
フィルタリングする必要もあります。

文字の切り分けには、Text::BroakIterator.pm も使えるかもしれません。
http://perl.infoware.ne.jp/source.html


D.D. [WriteDate : Mon May 14 09:38:13 2001]

精度を追求するならば ChaSen の方がいいかな、と思ってみたり。


はるか [WriteDate : Mon May 14 15:12:10 2001]

みなさん、ありがとうございます。
色々な方法があるみたいですね。
自分でも調べてみます。
色々とありがとうございました!!感謝します!!


はるか [WriteDate : Mon May 14 15:12:51 2001]

というわけで完了です。

回答(必須): 状態:

お名前(必須):

e-mail:

URL:




[戻る]
ChaichanPAPA's World