2017-11-08 14 views
-5

私はBookクラスの配列を作っていますが、Bookクラスの内容は信じられませんが、この正確な例で実際に利用する必要はありませんが、Comparableを実装しました。私はStringであるものを返す必要があります。過去の例では、常に無効にしていますが、System.out.printlnを使用しています。私は全体として回帰について低い把握力を持っているので、もし誰かが私がそれを大いに感謝するのを助けることができれば。再帰を使用してオブジェクトの配列をプリントする方法は?

public String getName(){ 
    return this.name; 
} 

あなたがオブジェクトの文字列表現を返したい場合は大会が.toString()メソッドを使用することです:あなただけのメソッドヘッダにそう言う方法から文字列を返すには、あなたに

+0

これは、基本的な再帰を学習するためにはかなり複雑なようです。最初に、再帰を使っていくつかの数列(例えば、 '1 2 3 ... 10')を出力することに慣れてください。このタスクについて考えてみましょう – Fureeish

+0

@Fureeish私はそれを行う方法を知っていますが、すべての例ではString型では出力されませんが、常にvoidを使用するので、出力の書き込み方法はわかりません –

+0

この場合、 **最初の 'n '個の数字を集計する再帰的なメソッドです。ヒント:メソッドのシグネチャが 'int sum(int n)'の場合、そのメソッド内部のコードの一部は 'return n + sum(n - 1);'となります。注意してください - 終了条件についてもう一度お読みください。基本的な再帰を学ぶことは、無限のループやメソッド呼び出し – Fureeish

答えて

-1

をありがとうございます。 String.format()はこれに非常に役立ちます。

public String toString(){ 
    return String.format("Name: %s Number of pages: %d", this.name, this.numPages); 
} 

編集:

再帰を使用して、これらのオブジェクトの配列を印刷するには:

public static String arrayAsString(Book[] books, int startIndex){ 
    if(startIndex > books.length - 1) return null; 

    String toAppend = arrayAsString(books, startIndex + 1); 

    if(toAppend == null) return books[startIndex].toString(); 
    else return books[startIndex].toString() + " " + toAppend; 
} 
+1

につながり、どのように "*再帰*を使う*"部分に触れるのでしょうか? – Fureeish

+0

何かが見つからないか、または元の質問から何かを残していない限り、OPが尋ねる質問である文字列を返すために再帰は必要ありません。 –

+0

彼は文字通り** **再帰*の部分を**タイトル**に入れました...彼はまた、ユーザ定義のオブジェクトの配列についても言及しました – Fureeish

0

再帰は、この問題の正しい戦略ではありません。宿題の助けを求めるように聞こえるので、あなたのTAやその他のリソースをあなたの学校であなたの質問の文脈をよりよく理解することをお勧めします。あなたがそれを述べたので:配列を印刷するためにComparableを実装する必要はありません。配列にソートする場合は、Comparableが必要です。言っ

は、ここでそれはあなたが必要なように聞こえるコンポーネントです:

  1. あなたBookクラスは、文字列表現を必要とします。 Javaでは、標準的にあなたがtoString方法でこれをエンコード:

    class Book 
    { 
        private String title; 
    
        // ...other Book methods defined here... 
    
        public String toString() 
        { 
         return this.title; // Or whatever the correct string representation of your Book is. 
        } 
    } 
    
  2. 私はあなたが初期化さBookの配列を持っていると仮定し、あなたのmain機能で言います。通常、リストを繰り返し印刷します。それははるかに簡単です。この回答を参照してください:How to print out individual Strings from Iterable<String>

    ただし、ご質問は再帰に固有です。再帰関数は、常に2つの要素を必要とする:共通のベースケースは空のリストであるため

    1. ベースケース
    2. 再帰的リストを反復再帰的ステップ

    は、関数型プログラミングにおいて一般的です。 Java配列はこのパターンには適していませんが、などの一部の実装はListです。つまり、再帰的なステップではなく、カウンタをインクリメントすることで配列を使用できます。文字通りforループでリストを反復することよりも利点があり、スタックのオーバーフローが起こりやすいという大きな欠点があります。しかし、あなたは再帰を求め...

    public String stringifyBooks(Book[] books, int currentIndex) 
    { 
        // From https://stackoverflow.com/questions/47169798/how-to-print-an-array-of-objects-using-recursion 
        if (currentIndex >= books.length || currentIndex < 0) 
        { 
         // Base case 
         return ""; 
        } 
        else 
        { 
         // Recursive step 
         return books[currentIndex].toString() + ", " + 
          stringifyBooks(books, currentIndex + 1); 
        } 
    } 
    

    今、あなたはBookの配列および初期インデックスとstringifyBooksを呼び出すことができますし、そのインデックスから始まり、書籍のすべての文字列を取得します。書籍の配列の長さよりも長い初期インデックスを渡すか、書籍が空の配列の場合はどうなりますか?

    自分で試してみると、このソリューションでは末尾に", "が生成されることがあります。これを回避するには、(a)ベースケースを調整するか(または2番目の「ベースケース」を追加する)、(b)再帰的ステップを調整して、ベースケースが再帰関数呼び出し:基本ケースから返された値をチェックし、再帰的なステップでそれを考慮する)。

    再帰の使用には、Javaのスタックサイズの制限があります。非常に長い本の本を試してみてください(そのうちの10,000人)、おそらく限界にぶつかるでしょう。さらに、すべての文字列連結のコストはかなり大きくなります。ちなみに、繰り返しアルゴリズム(つまり、forループを使用するもの)内にストリングを蓄積した場合、そのコストを支払うことになります。このため、JavaにはStringBuilderが組み込まれています。 +演算子を使用して各再帰的ステップで文字列を連結する代わりに、上記のコードを変更して、再帰的ステップ内でStringBuilderappendという文字列を取り込むかどうかを確認してください。 (この変更はstringifyBooksがStringの代わりにvoidを返す意味することに注意してください - あなたのStringBuilderパラメータは、あなたの戻り値である、本質的に終わる。)

    最後に、あなたが代わりにBook[]List<Book>を使用することを意図している場合、あなたは再帰的に構築することができfunctionここで、(1)ベースケースがListisEmpty関数をチェックし、""を返します。 (2)再帰的な場合は、リスト内の最初の要素の文字列を作成し、最初の要素を削除し、リスト上の再帰関数を呼び出し、最初の要素の文字列+再帰関数呼び出しの結果を返します。 (または、同じ種類のことをStringBuilderで実行します)。これを行うと、currentIndex変数が削除されます。これはあなたの本のリストを破壊するので、関数を使用した後に必要なら再帰関数を呼び出す前にクローンを作成する必要があることに注意してください。

関連する問題