gpt4 book ai didi

c# - 我可以在 C# 中找到 BigInteger 的位数吗?

转载 作者:太空狗 更新时间:2023-10-30 00:04:42 26 4
gpt4 key购买 nike

我正在解决 this problem ,其中他们要求第一个 1000 位斐波那契数的索引,我的第一个想法类似于:

BigInteger x = 1;
BigInteger y = 1;
BigInteger tmp = 0;

int currentIndex = 2;
while (x.NoOfDigits < 1000)
{
tmp = x + y;
y = x;
x = tmp;
currentIndex++;
}
return currentIndex;

但是,据我所知,没有计算 BigInteger 位数的方法。这是真的?绕过它的一种方法是使用 BigInteger 的 .ToString().Length 方法,但有人告诉我字符串处理速度很慢。

BigInteger 也有一个 .ToByteArray(),我想将 BigInteger 转换为字节数组并检查该数组的长度 - 但我认为这不能唯一地确定 BigInteger 中的位数。

为了它的值(value),我实现了另一种解决它的方法,即手动将斐波那契数存储在数组中,并在数组已满时立即停止,我将其与基于 .ToString 的方法进行了比较,后者慢了大约2.5倍,但是第一种方法用了0.1秒,也显得很长。

编辑:我已经测试了下面答案中的两个建议(一个使用 BigInteger.Log,另一个使用 MaxLimitMethod)。我得到以下运行时间:

  • 原始方法:00:00:00.0961957
  • 字符串方法:00:00:00.1535350
  • BigIntegerLogMethod: 00:00:00.0387479
  • 最大限制方法:00:00:00.0019509

程序

using System;
using System.Collections.Generic;
using System.Numerics;
using System.Diagnostics;

class Program
{
static void Main(string[] args)
{
Stopwatch clock = new Stopwatch();
clock.Start();
int index1 = Algorithms.IndexOfNDigits(1000);
clock.Stop();
var elapsedTime1 = clock.Elapsed;
Console.WriteLine(index1);
Console.WriteLine("Original method: {0}",elapsedTime1);
Console.ReadKey();

clock.Reset();
clock.Start();
int index2 = Algorithms.StringMethod(1000);
clock.Stop();
var elapsedTime2 = clock.Elapsed;
Console.WriteLine(index2);
Console.WriteLine("StringMethod: {0}", elapsedTime2);
Console.ReadKey();

clock.Reset();
clock.Start();
int index3 = Algorithms.BigIntegerLogMethod(1000);
clock.Stop();
var elapsedTime3 = clock.Elapsed;
Console.WriteLine(index3);
Console.WriteLine("BigIntegerLogMethod: {0}", elapsedTime3);
Console.ReadKey();

clock.Reset();
clock.Start();
int index4 = Algorithms.MaxLimitMethod(1000);
clock.Stop();
var elapsedTime4 = clock.Elapsed;
Console.WriteLine(index4);
Console.WriteLine("MaxLimitMethod: {0}", elapsedTime4);
Console.ReadKey();


}
}

static class Algorithms
{
//Find the index of the first Fibonacci number of n digits
public static int IndexOfNDigits(int n)
{
if (n == 1) return 1;
int[] firstNumber = new int[n];
int[] secondNumber = new int[n];

firstNumber[0] = 1;
secondNumber[0] = 1;
int currentIndex = 2;

while (firstNumber[n-1] == 0)
{
int carry = 0, singleSum = 0;
int[] tmp = new int[n]; //Placeholder for the sum
for (int i = 0; i<n; i++)
{
singleSum = firstNumber[i] + secondNumber[i];
if (singleSum >= 10) carry = 1;
else carry = 0;

tmp[i] += singleSum % 10;
if (tmp[i] >= 10)
{
tmp[i] = 0;
carry = 1;
}
int countCarries = 0;
while (carry == 1)
{
countCarries++;
if (tmp[i + countCarries] == 9)
{
tmp[i + countCarries] = 0;
tmp[i + countCarries + 1] += 1;
carry = 1;
}
else
{
tmp[i + countCarries] += 1;
carry = 0;
}
}
}

for (int i = 0; i < n; i++ )
{
secondNumber[i] = firstNumber[i];
firstNumber[i] = tmp[i];
}
currentIndex++;
}
return currentIndex;
}

public static int StringMethod(int n)
{
BigInteger x = 1;
BigInteger y = 1;
BigInteger tmp = 0;
int currentIndex = 2;

while (x.ToString().Length < n)
{
tmp = x + y;
y = x;
x = tmp;
currentIndex++;
}
return currentIndex;
}

public static int BigIntegerLogMethod(int n)
{
BigInteger x = 1;
BigInteger y = 1;
BigInteger tmp = 0;
int currentIndex = 2;

while (Math.Floor(BigInteger.Log10(x) + 1) < n)
{
tmp = x + y;
y = x;
x = tmp;
currentIndex++;
}
return currentIndex;
}

public static int MaxLimitMethod(int n)
{
BigInteger maxLimit = BigInteger.Pow(10, n - 1);
BigInteger x = 1;
BigInteger y = 1;
BigInteger tmp = 0;
int currentIndex = 2;

while (x.CompareTo(maxLimit) < 0)
{
tmp = x + y;
y = x;
x = tmp;
currentIndex++;
}
return currentIndex;
}
}

最佳答案

前提是x > 0

int digits = (int)Math.Floor(BigInteger.Log10(x) + 1);

会得到位数。

出于好奇,我测试了

int digits = x.ToString().Length; 

方法。对于 100 000 000 次迭代,它比 Log10 解决方案慢 3 倍。

关于c# - 我可以在 C# 中找到 BigInteger 的位数吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34052376/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com