7

私が働いている会社のために、カスタムの電子メール管理アプリケーションを作成したとしましょう。同社のサポート アカウントから電子メールを読み取り、それらのクリーンアップされたプレーン テキスト バージョンをデータベースに保存し、その過程でそれを顧客アカウントや注文に関連付けるなど、他の優れた処理を行います。従業員がメッセージに返信すると、私のプログラムは電子メールを生成し、ディスカッション スレッドの書式設定されたバージョンを顧客に送信します。顧客が応答すると、アプリは件名で一意の番号を探して着信メッセージを読み取り、前のディスカッションを取り除き、スレッドの新しいアイテムとして追加します。例えば:

これは Contoso カスタマー サービスからのメッセージです。

最近、カスタマーサポートをリクエストしました。以下はあなたの要約です
リクエストと私たちの返信。

-------------------------------------------------- ------------------
Contoso (Fred) 2008 年 12 月 30 日火曜日、午前 9 時 4 分
-------------------------------------------------- ------------------
ジョン:

あなたの住所を変更しました。あなたはログインすることで私の仕事を確認することができます
当社の Web サイトの「あなたのアカウント」。ご注文は本日発送されます。

Contoso でお買い物いただきありがとうございます。

-------------------------------------------------- ------------------
2008 年 12 月 30 日火曜日の午前 8:03 のあなた
-------------------------------------------------- ------------------
おっと、住所を間違って入力してしまいました。に変更できますか

フレッド・スミス
123メインストリート
バージニア州エニータウン 12345

ありがとう!

--
フレッド・スミス
Contoso 製品愛好家

一般に、これはすべてうまく機能しますが、クリーンアップをしばらく延期している領域が 1 つあります。それは、テキストの折り返しを扱っています。上記のようなきれいな電子メール形式を生成するには、顧客が最初に送信したテキストを再ラップする必要があります。

これを行うアルゴリズムを作成しました (コードを見ても、それがどのように機能するのか完全にはわかりません。リファクタリングを使用する可能性があります)。しかし、ハードラップ改行、「段落の終わり」改行、および「意味論的」改行を区別することはできません。たとえば、ハードラップの改行は、たとえば 79 桁の長いテキスト行を折り返すために、電子メール クライアントが段落内に挿入した改行です。段落改行の終わりは、ユーザーが段落の最後の文の後に追加した改行です。セマンティックな改行はbr、フレッドが上で入力したアドレスなど、タグのようなものになります。

代わりに、私のアルゴリズムは、新しい段落を示すものとして 2 つの改行が連続して表示されるだけであるため、顧客の電子メールは次のような形式になります。

おっと、住所を間違って入力してしまいました。に変更できますか

フレッド スミス 123 Main St Anytown, VA 12345

ありがとう!

-- Fred Smith Contoso 製品愛好家

このテキストを意図したとおりに再ラップするバージョンを書こうとするときはいつでも、基本的に、テキストのセマンティクス、「ハードラップ」改行と「本当に意味した」の違いを知る必要があるという点で壁にぶつかります。br顧客の住所などの "-タイプの改行のようなものです。(私は 2 つの改行を続けて使用して、いつ新しい段落を開始するかを決定します。これは、大多数の人々が実際に電子メールを入力する方法と一致しています。)

意図したとおりにテキストを再ラップできるアルゴリズムを持っている人はいますか? それとも、特定のソリューションの複雑さを比較検討する際に、この実装は「十分」でしょうか?

ありがとう。

4

3 に答える 3

3

行の長さを最大値未満に保つために改行が挿入されているかどうかを確認することができます(ハードラップとも呼ばれます)。テキスト内の最長の行を確認するだけです。次に、任意の行について、次の行の最初の単語を追加します。結果の行が最大長を超える場合、改行はおそらくハードラップでした。

さらに単純な場合は、すべての侵入をハードラップと見なすことができます(maxlength - 15) <= length <= maxlength(15は知識に基づいた推測です)。これにより、住所などの意図的な中断が確実に除外され、この範囲で中断を見逃しても、結果にそれほど悪影響を与えることはありません。

于 2008-12-30T14:29:16.830 に答える
2

上記のOleのアドバイスに従って、しきい値を確認するために実装を作り直しました。それは、私が実際に英語を理解するコードを書く必要なしに、私がそれに投げかけるほとんどのシナリオを十分に処理するようです。

基本的に、最初に入力文字列をスキャンして、変数に最長の行の長さを記録しますinputMaxLineLength。次に、再折り返ししているときに、インデックスが〜85 inputMaxLineLength%の改行に遭遇した場合inputMaxLineLength、ハードラップ改行だと思うので、その改行をスペースに置き換えます。ただし、直後に別の改行が続く場合を除きます。その範囲内でたまたま発生するのは1行の段落だと思います。これは、たとえば、誰かが短い箇条書きを入力した場合に発生する可能性があります。

確かに完璧ではありませんが、私のシナリオでは「十分」です。テキストは通常​​、以前の電子メールクライアントによって最初から半分壊れていることを考慮してください。

これがいくつかのコードです。私の数時間前の実装は、おそらくいくつかのエッジケースでまだアンダーラップしています(C#を使用)。以前のソリューションよりもはるかに複雑ではありません。これは素晴らしいことです。

ソースコード

そして、(MSTestを使用して)そのコードを実行するいくつかの単体テストを次に示します。

テストコード

誰かがより良い実装を持っているなら(そして間違いなくより良い実装が存在するなら)、私はあなたの考えを喜んで読んでいきます!ありがとう。

于 2008-12-30T19:43:53.873 に答える
2

以下のように、2つの提案があります。

  • 句読点に注意してください: これは、「ハードラップ」改行と「段落の終わり」改行を区別するのに役立ちます (行がピリオドで終わる場合、ユーザーが意図したものである可能性が高いため)段落の終わり。

  • 行が最大行長よりもはるかに短いかどうかに注意してください。上記の例では、テキストが 79 文字で「ハードラップ」されている可能性があります。さらに、住所行の長さはわずか 30 文字です。30 は 79 よりもはるかに小さいため、アドレス行がユーザーによって改行されたのではなく、ユーザーのテキスト ラップ アルゴリズムによって改行されたことがわかります。

また、インデントにも注意してください。左から空白でインデントされている行は、このフォーラムにあるように、前の行から分割された新しい段落であると想定される場合があります。

于 2008-12-30T14:59:16.863 に答える