• ベストアンサー

再帰

お世話になります。再帰でどう組んだらいいのかわからない問題があるので質問させてください 問題は、再帰を使ってlong型の整数に、3つずつの間隔でコンマを入れString型で返す演習問題です。 例) 999 → 999 1234 → 1,234 1007 → 1,007 1023004567 → 1,023,004,567 public static String intWithCommas(long n) { String strnum = String.valueOf(n); String str = ""; int length = strnum.length(); if (strnum.length() <= 3) { return strnum; } else { str = "," + strnum.substring(length-4, length-1); } return str + intWithCommas(?); } 上記のように組んだのですが、2箇所わからないところがあります。 カンマを入れるので整数を文字列に変換してsubstringで3つずつに分けてカンマを入れようと思ったのですが、 str = "," + strnum.substring(length-4, length-1); この部分をどのように直したらいいかがわかりません。 これではカンマが一番左に行ってしまうし、整数を3つずつにわけようにも、本来インデックスは左から数えますがこの場合は右から3つずつ数えなければなりません。 それと、最後の再帰を呼ぶところですが、intWithCommas(?);の中をどうしたらいいかがわかりません。 long型の整数を受け取ってるのでlong型の整数を入れるとおもうのですが、プログラムの中で整数をStringに変換してるのでどうしたらよいのでしょうか 宜しくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
  • anmochi
  • ベストアンサー率65% (1332/2045)
回答No.1

 毎回String型のインスタンスを作ってsubstring()は効率悪すぎっしょ(1回の再起につき2つのStringインスタンスが作成される)。比較(1000以上か未満か)だってlongのまま行う方が高速だ。  もうちょっとシンプルに考えてみたらどうかな。たとえば以下のようなものはどうだろう。課題という事なんでそのものズバリを書いてしまうのは抵抗があるけど、String型に変えてからごにょごにょという事にこだわらないという例を示したいので。 package anmochi; import java.text.*; public class NumericFormat {   public static String intWithCommas(DecimalFormat df, long n) {     if(n < 1000) { // 1000未満なら       return String.valueOf(n); // そこが最上位     } else { // 1000を含むそれ以上なら       return intWithCommas(df, n / 1000) + "," + df.format(n % 1000); // 1000で割った数値を再起で処理させて、自分は1000未満の部分だけを"000"でフォーマットする。※1     }   }   public static void main(String[] args) {     DecimalFormat df = new DecimalFormat("000");     System.out.println(intWithCommas(df, 1));     System.out.println(intWithCommas(df, 20));     System.out.println(intWithCommas(df, 999));     System.out.println(intWithCommas(df, 1000));     System.out.println(intWithCommas(df, 65535));     System.out.println(intWithCommas(df, 1123456789));   } }  今この回答上にざっと書いただけなので動作確認はしてません。よろしく。  また、DecimalFormatも1つのインスタンスを使いまわしたいだけなので再起メソッドの引数に含まれるのは今回の本質ではないというのも注意。といいつつ※1のところでStringインスタンスが何個も作られてるけど。

lockwell
質問者

お礼

解決しました!ありがとうございます!

lockwell
質問者

補足

どうもありがとうございます。 一つ質問があるのですが、整数が1007だった場合、1000で割ると商が1で余りが7になります。 そうすると結果が1,7になり、余りでは00が無視されてしまいます。 1000を1000で割っても商が1、余りが0なので1,0となります 余りで0を省略されないようにするにはどうしたらよいのでしょうか DecimalFormatの部分も少し解説していただけますでしょうか

その他の回答 (1)

  • Tasuke22
  • ベストアンサー率33% (1799/5383)
回答No.2

> str = "," + strnum.substring(length-4, length-1); ","+(n/1000の余りの文字列) > return str + intWithCommas(?); return intWithCommas(n/1000) + str; 下から処理するので、再帰は上へ継ぎ足す。

lockwell
質問者

お礼

解決しました!ありがとうございました!

lockwell
質問者

補足

ありがとうございます。 ","+(n/1000の余りの文字列)この部分ですが、上にもすでに書いたように、1000や1007といった1000で割ったとき余りで0が省略されてしまう場合はどのように処理したらよいでしょうか 1007の余りは007ではなく7となってしまうので、結果1,007ではなく1,7となってしまいます