0

ドキュメント内の一意のフレーズの数を数える方法を知っているか、コードを持っている人はいますか? (1 語、2 語句、3 語句)。

ありがとう

探しているものの例: 私が言いたいのは、テキスト ドキュメントがあり、最も一般的な単語句が何であるかを確認する必要があるということです。例文

私は車を洗車場に持って行きました。

私: 1
かかった: 1
ザ:2
車: 2
に : 1
ウォッシュ:1
私が取った:1
かかった : 1
車 : 2
車まで:1
に : 1
洗車:1
私は取った:1
車に乗った : 1
への車:1
までの車:1
車へ : 1
洗車:1
私は車を : 1 に持っていきました
に車を持って行きました: 1
車から車へ:1
車から洗車まで:1

フレーズと、それが現れる回数が必要です。

どんな助けでも大歓迎です。これに最も近いものは、http://tools.seobook.com/general/keyword-density/source.phpの PHP スクリプトでした。

以前はこのためのコードがいくつかありましたが、見つかりません。

4

4 に答える 4

2

問題を解決する最初のコードを次に示します。

function CountWordSequences(const s:string; Counts:TStrings = nil):TStrings;
var
  words, seqs : TStrings;
  nw,i,j:integer;
  t :string;
begin
  if Counts=nil then Counts:=TStringList.Create;
  words:=TStringList.Create;        // build a list of all words
  words.DelimitedText:=s;
  seqs:=TStringList.Create;
  for nw:=1 to words.Count do       // build a list of all word sequences
   begin
    for i:=0 to words.Count-nw do
     begin
      t:='';
      for j:=0 to nw-1 do
       begin
        t:=t+words[i+j];
        if j<>nw-1 then t:=t+' ';
       end;
      seqs.Add(t);
     end;
   end;
  words.Destroy;
  for i:=0 to seqs.Count-1 do         // count repeated sequences
   begin
    j:=Counts.IndexOf(seqs.Strings[i]);
    if j=-1 then
      Counts.AddObject(seqs.Strings[i],TObject(1))
    else
      Counts.Objects[j] := TObject(Succ(Integer(Counts.Objects[j])));
   end;
  seqs.Destroy;
  result:=Counts;
end;

たとえば、より多くの単語区切り文字 (空白だけでなく) を認識したり、ある種の大文字と小文字を区別しないように実装したりして、このコードを実際の生産用に精巧にする必要があります。

テストするには、Button、EntryField、Memo を Form に配置し、次のコードを追加します。

procedure TForm1.Button1Click(Sender: TObject);
var i:integer; l:TStrings;
 begin
  l:=CountWordSequences(edit1.Text,TStringList.Create);
  for i:=1 to l.count do
    memo1.Lines.Add('"'+l.Strings[i-1]+'": '+inttostr(Integer(l.Objects[i-1])));
 end;

私は最初に試してみますI took the car to the car wash

与える

"I": 1
"took": 1
"the": 2
"car": 2
"to": 1
"wash.": 1
"I took": 1
"took the": 1
"the car": 2
"car to": 1
"to the": 1
"car wash.": 1
"I took the": 1
"took the car": 1
"the car to": 1
"car to the": 1
"to the car": 1
"the car wash.": 1
"I took the car": 1
"took the car to": 1
"the car to the": 1
"car to the car": 1
"to the car wash.": 1
"I took the car to": 1
"took the car to the": 1
"the car to the car": 1
"car to the car wash.": 1
"I took the car to the": 1
"took the car to the car": 1
"the car to the car wash.": 1
"I took the car to the car": 1
"took the car to the car wash.": 1
"I took the car to the car wash.": 1
于 2010-03-17T11:06:47.070 に答える
0

可能な組み合わせの数は本当に急速に増加します。ある言語で 30000 語が主流で使用されていると仮定すると、3 つの句の組み合わせの数は 30000^3 の大きさになります。

とにかく、レベル 0 の実装では、単語の (ハッシュ) リストを作成し、必要に応じて非常に一般的な単語 (the、of など) のリストをフィルター処理して、フレーズの数を減らします。他にやりたいことは、複数形を単数形に減らしたり、末尾の 's やケーシングなどを削除したりすることです。

Delphi には 64 ビット バージョンがないため、次に、テキストを単語ごとに調べて (トークナイザー スタイル)、一般的な単語をスキップし、遭遇したフレーズの順序付けられたリストを単純に保持し、メモリが不足しないことを願っています。 )

クヌースは組み合わせに関する本を丸ごと持っていませんでしたか?

于 2010-03-17T06:05:14.820 に答える
0

Delphi Basics の Web サイトから。

var
  position : Integer;

begin
  // Look for the word 'Cat' in a sentence
  // Note : that this search is case sensitive, so that
  //        the first 'cat' is not matched
  position := AnsiPos('Cat', 'The cat sat on the Cat mat');
  if position = 0
  then ShowMessage('''Cat'' not found in the sentence')
  else ShowMessage('''Cat'' was found at character '+IntToStr(position));
end;

多分それは助けになるでしょう

于 2010-03-17T02:58:31.500 に答える
0

これが私が問題を解決する方法です。データ ファイルを通過するたびに、次のステップのために新しいデータ ファイルが作成されると仮定します。言及された制御文字は、データに自然に現れない任意の文字にすることができます。制御文字を記述するときは、重複して記述しないでください。

  1. 文書をざっと見て、各単語を別々に数えます。
  2. ドキュメントをもう一度実行し、一度だけ使用された単語を制御文字に置き換えて、出現するペアを新しいリストに追加します (単語 ABC はアイテム AB とアイテム BC になります)。制御文字はハード区切り文字として機能します。制御文字の間に単独である単語は、ペアに変換できないため、変換する必要があります。
  3. ドキュメントをもう一度実行し、一度だけ使用されたペアを制御文字に置き換えて、出現するトリプレットを新しいリストに追加します。制御文字間のペアを制御文字に変換します。

空のリストを取得するか、サポートする最大のフレーズが得られるまで、各リストに別の単語レベルを追加することを繰り返します。

この方法は、最も一般的なフレーズに、使用頻度の低い小さなフレーズを含めることはできないという事実を意味します。

于 2010-03-17T22:22:47.513 に答える