[英]Cutting of the first 9 digits
好吧,我正在嘗試解決我的一個朋友給我做的一個難題,好吧,我已經設法從BigInteger
刪掉了最后9位數字,我有辦法刪掉前9個數字,但是太慢了,花了太長時間。
我需要前9個和后9個的原因是因為我正在尋找第一個和最后一個為pandigital的BigInteger
。
如果你不明白我的意思說,我們有n = new BigInteger("123456789987654321")
好,我需要獲得“123456789”和“987654321” seperately,我不想給的BigInteger轉換為字符串,因為這是一個非常緩慢的過程。
我在這里追求速度,我只是對這個解決方案感到困惑。 我聽說過有關黃金分割率的信息嗎? 如果您有興趣,這是我的代碼。
import java.math.BigInteger;
public class Main {
public static void main(String...strings)
{
long timeStart = System.currentTimeMillis();
fib(350_000);
long timeEnd = System.currentTimeMillis();
System.out.println("Finished processing, time: " + (timeEnd - timeStart) + " milliseconds.");
}
public static BigInteger fib(int n)
{
BigInteger prev1 = BigInteger.valueOf(0), prev2 = BigInteger.valueOf(1);
for (int i = 0; i < n; i++)
{
// TODO: Check if the head is pandigital as well.
BigInteger tailing9Digits = tailing9Digits(prev1);
boolean tailPandigital = isPanDigital(tailing9Digits);
if (tailPandigital)
{
System.out.println("Solved at index: " + i);
break;
}
BigInteger savePrev1 = prev1;
prev1 = prev2;
prev2 = savePrev1.add(prev2);
}
return prev1;
}
public static BigInteger leading9Digits(BigInteger x)
{
// STUCK HERE.
return null;
}
public static BigInteger tailing9Digits(BigInteger x)
{
return x.remainder(BigInteger.TEN.pow(9));
}
static BigInteger[] pows = new BigInteger[16];
static
{
for (int i = 0; i < 16; i++)
{
pows[i] = BigInteger.TEN.pow(i);
}
}
static boolean isPanDigital(BigInteger n)
{
if (!n.remainder(BigInteger.valueOf(9)).equals(BigInteger.ZERO))
{
return false;
}
boolean[] foundDigits = new boolean[9];
boolean isPanDigital = true;
for (int i = 1; i <= 9; i++)
{
BigInteger digit = n.remainder(pows[i]).divide(pows[i - 1]);
for (int j = 0; j < foundDigits.length; j++) {
if (digit.equals(BigInteger.valueOf(j + 1)) && !foundDigits[j])
{
foundDigits[j] = true;
}
}
}
for (int i = 0; i < 9; i++)
{
isPanDigital = isPanDigital && foundDigits[i];
}
return isPanDigital;
}
}
如果您完全關心速度,我不建議您使用BigInteger
。 它的大多數方法執行不佳,通常會導致代碼非常慢。
對於除法和基數轉換,有一個分而治之的技巧,您可能會發現有幫助。
首先, BigInteger
的multiply()
是二次的。 您將需要解決此問題,否則這些分而治之的技巧將不會導致任何提速。 通過快速傅立葉變換的乘法相當快且良好。
如果要將BigInteger
轉換為10,則將其對半分割(按位)並將其寫為a * 256^k + b.
您可以做的一件事是將a
和b
遞歸轉換為10的基數,然后通過重復平方將256^k
轉換為十進制,然后以10為基數,將a
乘以256^k
然后將b
加到結果中。 此外,由於您只對前幾位有興趣,你可能甚至不需要轉換b
如果前幾位a * 256^k
不可能通過增加小東西的影響b
。
類似的技巧適用於除法。
您可以使用toByteArray()
方法進行位移和提取。
也許這不太快,但至少很簡單
BigInteger n = new BigInteger("123456789987654321");
BigInteger n2 = n.divide(BigInteger.TEN.pow(new BigDecimal(n).precision() - 9));
BigInteger n1 = n.remainder(new BigInteger("1000000000"));
System.out.println(n1);
System.out.println(n2);
產量
987654321
123456789
好吧,我相信這是您需要的:
import java.math.BigInteger;
public class PandigitalCheck {
public static void main(String[] args) {
BigInteger num = new BigInteger("12345678907438297438924239987654321");
long timeStart = System.currentTimeMillis();
System.out.println("Is Pandigital: " + isPandigital(num));
long timeEnd = System.currentTimeMillis();
System.out.println("Time Taken: " + (timeEnd - timeStart) + " ms");
}
private static boolean isPandigital(BigInteger num) {
if (getTrailing9Digits(num).compareTo(getLeading9Digits(num)) == 0) {
return true;
}
return false;
}
private static BigInteger getLeading9Digits(BigInteger num) {
int length = getBigIntLength(num);
BigInteger leading9 = BigInteger.ZERO;
for (int i = 0; i < 9; i++) {
BigInteger remainder = num.divide(BigInteger.TEN.pow(length - 1 - i));
leading9 = leading9.add(remainder.multiply(BigInteger.TEN.pow(i)));
num = num.remainder(BigInteger.TEN.pow(length - 1 - i));
}
return leading9;
}
private static int getBigIntLength(BigInteger num) {
for (int i = 1; ; i++) {
if (num.divide(BigInteger.TEN.pow(i)) == BigInteger.ZERO) {
return i;
}
}
}
private static BigInteger getTrailing9Digits(BigInteger num) {
return num.remainder(BigInteger.TEN.pow(9));
}
}
輸出為:
Is Pandigital: true
Time Taken: 0 ms
它符合要求嗎?
我是Java的新手,我只是將BigInteger轉換為String,但它的代碼速度卻很快
import java.math.BigInteger;
public class Main {
public static void main(String args[])
{
long timeStart = System.currentTimeMillis();
String biStr = new BigInteger("123456789987654321").toString();
int length=(biStr.length())/2;
String[] ints = new String[length];
String[] ints2 = new String[length];
for(int i=0; i<length; i++) {
int j=i+length;
ints[i] = String.valueOf(biStr.charAt(i));
ints2[i] = String.valueOf(biStr.charAt(j));
System.out.println(ints[i] +" | "+ints2[i]);
}
long timeEnd = System.currentTimeMillis();
System.out.println("Finished processing, time: " + (timeEnd - timeStart) + " milliseconds.");
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.