3

私は楽しみのために、何かをプログラムするために狂ったlibsプログラムを書いています。プログラム自体は非常に簡単ですが、ユーザーに与えられた単語を文に配置するというゲームの性質上、いくつかの連結に頼っています。より少ない連結に頼るか、より効率的なもののためにそれらを排除するためのエレガントな回避策はありますか? 最終的に連結を使用するかどうかに違いはないことはわかっていますが、このプログラムをより洗練された方法で作成できるかどうかに興味があります。

更新:私はJavaを使用していますが、連結をエスケープするための一般的な解決策があれば、それも高く評価されます。

4

11 に答える 11

8

解決策の 1 つは、mad libs ファイル全体を書き出して、選択した単語に置き換える必要がある特別なトークンを挿入することです。

新品の ${NOUN1} を購入したばかりで、${VERB1} に送られます。

次に、たとえば次を使用できますString.replace("${NOUN1}", noun1)。すべての単語に。

于 2009-03-16T06:57:19.117 に答える
3

どの言語を使用していますか?

ほとんどの高級言語には、次のようなものがあります。

String.Format("{0} {1} {2} {3}", word1, word2, word3, word4);
于 2009-03-16T06:44:27.307 に答える
2

単語ごとに String.replace を呼び出したり、StringBuilder に常に追加したりするのではなく、順序付けられた配列に単語を入れて、jdk 1.5 以降の場合は String.format、jdk 1.4 の場合は MessageFormat.format を使用できます。残念ながら、2 つのパターン形式は異なります。

String myPattern = "私の %s があなたの %s を食べる";
// ここでユーザーから値を取得します
文字列の結果 = String.format( myPattern, (Object[])myArray );

また

String myPattern = "私の {0} があなたの {1} を食べる";
// ここでユーザーから値を取得します
文字列の結果 = MessageFormat.format( myPattern, (Object[])myArray );

以下は、コマンド ラインからの値で文字列を埋める完全なプログラムです。

public クラス フォーマット
{
    public static void main( String[] args )
    {
        文字列パターン = "私の %s があなたの %s を食べる";
        System.out.println( String.format( pattern, (Object[])args ));
    }
}
于 2009-03-16T21:34:30.587 に答える
2

ゲーム内で連結を完全に回避していることがわかる 2 つの方法があります。

  1. ストーリー テンプレートをトークンのコレクションとして保存します: 不変部分と単語プレースホルダー。次に、単語プレースホルダーの代わりに不変部分とユーザー単語を出力するコレクションをループします。

  2. charAt を使用してテンプレート文字列をループし、単語プレースホルダーの代わりに単語を出力するカスタム印刷クラスを記述します。

于 2009-03-16T16:18:38.440 に答える
1

連結を回避する一般的な方法に関しては、何も思い浮かびません。あなたができることは、連結の仕事を単純化するある種のヘルパークラスを自分で書くことです。ただし、文字列を次のように直接連結しないことをお勧めします。

String x = "Hi";
String y = x + " there!";

Java での文字列連結の実装は非常に遅いため、代わりに StringBuffer を使用することをお勧めします。特に、多数の連結を行う場合は次のようになります。

StringBuffer myStringBuffer = new StringBuffer();
myStringBuffer.append("Hi");
myStringBuffer.append(" there!");

このようなもの。今はコンパイラでこれをチェックしていませんが、自分で理解できると確信しています。

于 2009-03-16T07:02:14.847 に答える
1

Javaについてはわかりませんが、PHPやJavascriptなどの他の言語では、配列を作成してそのすべての要素を結合する方が高速になる場合があります.

Javascript の例:

var str = str1 + str2 + str3 + "str4" + str5 + "str6" + str7;
var str = [str1, str2, str3, "str4", str5, "str6", str7].join("");

PHP の例:

$str = $str1 . $str2 . $str3 . "str4" . $str5 . "str6" . $str7;
$str = implode("", array($str1, $str2, $str3, "str4", $str5, "str6", $str7));

この方法は、各文字列の間に区切り文字を入れたい場合に最適です。この場合、高速であるだけでなく、よりコンパクトで読みやすくなります。

于 2009-03-16T07:05:17.850 に答える
1

あなたの質問には2つの側面があります。

まず、コード内で連結を直接使用したくない場合があります。次に、ランタイムから何らかの文字列フォーマット ルーチンを使用できます。これは連結をスキップしませんが、それらをコードからランタイムに移動します。

2 番目に、連結をより効率的に行いたい場合があります。それはまた別の話です。ここで最も重要なことは、連結された文字列に十分な大きさのバッファを事前に割り当てることです。これは、メモリの再割り当てにはかなりのコストがかかるためです。部分文字列を結果文字列にコピーすることは、通常はコストがかからず、必要悪です。

于 2009-03-16T06:50:32.567 に答える
0

必要に応じて、連結せずにこれを行うことは確かに可能です。それはおそらくあまり価値がありませんが。

結果をどこに表示するかによって部分的に異なります。Web またはコンソール上にある場合は、結果を出力ストリームに直接書き込むことができます。

たとえば、テンプレートが「%001 が %002 から飛び出した」のようなものである場合、次のことができます。

1) 文字列をスキャンして、変数の場所を見つけます。2) 文字列を "the","jumped out of the" コンポーネントのリストに分割します。この場合、3) リストの要素と結果をループし、次のような出力にダンプします。

PrintStream  = //get output from somewhere
for(int i = 0; i < pieces.size()-1 ; i++){
   ps.print(peices.get(i));
   ps.print(answers.get(i));
}
ps.print(pieces.get(pieces.size()-1));//last one

今。それを「エレガント」と呼ぶかどうかはわかりません。それはおそらく一種の高速でしょう。私が言ったように、これがWebサービスであり、それが超人気になった場合などに適しているかもしれません.

これが GUI アプリの場合、文字列を個別に描画するコードを記述できますが、おそらく連結よりも時間がかかります。

しかし、できることの 1 つは、ByteArrayOutputStream を使用して十分なスペースを事前に割り当てて、追加の割り当てを行わずに入力済みの madlib を格納できるようにすることです。それもかなり速いでしょう。

于 2010-02-16T11:10:22.670 に答える
0

きれいにするために連結を避けたいのですが、きれいに並べてみると、驚くほど見栄えがよくなる可能性があります。パフォーマンスが心配な場合でも、ストリングビルダーを使用する必要はないかもしれません。単純な連結 (つまり、"fdsfsd" + var1 +var2 +"dsfsdf" +"tyhty") は、文字列ビルダーと同じものにコンパイルされます (事実上同じで、よりきれいに見えます)。大量のものを連結している場合、文字列ビルダーは理にかなっていますループまたは複雑なフローで。

于 2010-02-16T11:19:44.323 に答える
0

「連結を回避する」とは、新しい文字列にスペースを割り当てて割り当てることを意味していると思いますか? .NET を使用している場合は、StringBuilderが役立つはずです。

于 2009-03-16T06:51:07.043 に答える