質問

私は、おもしろくて、ただ何かをプログラムするために、狂ったlibsプログラムを書いています。プログラム自体は非常に単純ですが、ユーザーが指定した単語を文に配置するゲームの性質により、いくつかの連結に頼っています。より少ない連結に頼る、またはより効率的な何かのためにそれらを排除するためのエレガントな作業がありますか?連結を使用してもしなくても、最終的には違いはありませんが、このプログラムを書くためのよりエレガントな方法があるかどうか興味があります。

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

役に立ちましたか?

解決

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

  

新しい$ {NOUN1}を購入しましたが、   $ {VERB1}になります。

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

他のヒント

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

ほとんどの高レベル言語には次のようなものがあります:

String.Format("{0} {1} {2} {3}", word1, word2, word3, word4);

ゲームでの連結を完全に回避する方法は2つあります:

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

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

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

String myPattern = "My %s eats your %s";
// get values from the user here
String result = String.format( myPattern, (Object[])myArray );

または

String myPattern = "My {0} eats your {1}";
// get values from the user here
String result = MessageFormat.format( myPattern, (Object[])myArray );

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

public class Format
{
    public static void main( String[] args )
    {
        String pattern = "My %s eats your %s";
        System.out.println( String.format( pattern, (Object[])args ));
    }
}

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

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

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

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

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

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

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

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

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));

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

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

文字列がある場合は、文字列を頻繁に変更する必要があります。char[]配列を使用し、変更が完了したら文字列を作成してください。

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

結果を表示する場所に一部依存します。 Webまたはコンソール上にある場合は、結果を出力ストリームに直接書き込むことができます。

たとえば、テンプレートが<!> quot;のような場合、%001は%002 <!> quotから飛び出しました。あなたができる:

1)文字列をスキャンして、変数の場所を見つけます。 2)文字列をコンポーネントのリストに分割します<!> quot; the <!> quot;、<!> quot; <!> quotから飛び出した;この場合 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

今。あなたがそれを「エレガント」と呼ぶかどうかはわかりません。たぶんちょっと速いでしょう。私が言ったように、これがウェブサービスであり、超人気になった場合などに適切かもしれません。

これがGUIアプリの場合、文字列を個別に描画するコードを作成できますが、連結よりも時間がかかる可能性があります。

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

クリーンのためにそれをうまく並べてみて、驚くほど良く見えるかもしれないのに、なぜ連結を避けたいのですか?パフォーマンスが心配な場合でも、文字列ビルダーを使用する必要はないかもしれませんが、一連の連結(つまり、<!> quot; fdsfsd <!> quot; + var1 + var2 + <!> quot; dsfsdf <!> quot; + <!> quot; tyhty <!> quot;にコンパイルされます。文字列ビルダーと同じこと(事実上同じで、よりきれいに見えます。文字列ビルダーは、ループまたは複雑なフローで大量のものを連結している場合に意味があります。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top