**回文数 (Palindromic Number) **
数字の桁を逆から並べた数がもとの数に等しいものを回文数という。10進数以外にも回文数はあります。質問は10進数に限定します。
0,1,2,3,4,5,6,7,8,9,11,22,33, … , 111, 121, … , 999, …
回文数の判定のために以下を作成しました。 Long.MAX_VALUEまでは確認しています。
Java
1 /** 2 * 整数 num から、各桁の数字を反転させた整数を返す。 3 * @param num 整数 4 * @return 各桁の数字を反転させた整数 5 */ 6 static long reverse(long num) { 7 int sign = (num < 0) ? -1 : 1; 8 BigInteger rem = BigInteger.valueOf(num).abs(); 9 int numDigits = getDigitCount(rem); // 桁数 10 11 BigInteger result = BigInteger.ZERO; 12 for (int i = 1; i <= numDigits; ++i) { 13 result = result.add(BigInteger.TEN.pow(numDigits - i).multiply(rem.mod(BigInteger.TEN))); 14 rem = rem.divide(BigInteger.TEN); 15 } 16 return result.longValue() * sign; 17 } 18 19 /** 20 * スタックオーバーフローの以下の回答を引用します。(底の変換を利用) 21 * https://stackoverflow.com/questions/18828377/biginteger-count-the-number-of-decimal-digits-in-a-scalable-method/18828536#18828536 22 * 桁数を数える 23 * @param number 数 24 * @return 桁数 25 */ 26 public static int getDigitCount(BigInteger number) { 27 double factor = Math.log(2) / Math.log(10); 28 int digitCount = (int) (factor * number.bitLength() + 1); 29 if (BigInteger.TEN.pow(digitCount - 1).compareTo(number) > 0) { 30 return digitCount - 1; 31 } 32 return digitCount; 33 }
回文数の個数
0 <= n < Long.MAX_VALUE までの n に含まれる回文数の個数を求めたい。以下のコードは遅くて使えません。
Java
1 long cnt = 0; 2 for (long i=0; i < Long.MAX_VALUE; ++i) { 3 if (i==reverse(i)) ++cnt; 4 }
質問
- 回文数の個数を求める良いアルゴリズムがありませんか。
桁数が固定されているなら、組み合わせ数を計算することで効率よく求められます。
しかしLong.MAX_VALUE までとなると工夫が必要です。 - 回文数判定の良いコードがあれば教えてください。
質問のどれかに答えていただいても、解法の一部でも、ヒントでも構いません。
桁数から回文数の個数を求める(追記)
ここまではわかっています。18桁までの回文数は以下の式で求められます。
Java
1 /** 2 * 桁数nを与えて、1桁からn桁までの回文数の個数を返す。 3 * @param n 桁数 (1以上) 4 * @return 回文数の個数 5 */ 6 static long countPalindromics_(int n) { 7 if (n <= 0) { 8 throw new IllegalArgumentException("nは1以上です。"); 9 } 10 long acc = IntStream.rangeClosed(1, n).mapToLong(i -> (long) Math.pow(10, (i-1)/2) * 9l).sum(); 11 return acc + 1; 12 }
この知識を前提にすれば、n のうち、1000000000000000000 <= m < Long.MAX_VALUE までの m に含まれる回文数の個数を求めたい。
回答6件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/04/19 13:36