Java 确定一个数是否为斐波那契数
我需要编写一个Java代码来检查用户输入的数字是否在斐波那契序列中 我没有问题将斐波那契数列写入输出,但是(可能是因为它在深夜),我正在努力思考“是否”是斐波那契数的序列。我一次又一次地开始。这真让我头疼 我现在拥有的是第n个Java 确定一个数是否为斐波那契数,java,fibonacci,Java,Fibonacci,我需要编写一个Java代码来检查用户输入的数字是否在斐波那契序列中 我没有问题将斐波那契数列写入输出,但是(可能是因为它在深夜),我正在努力思考“是否”是斐波那契数的序列。我一次又一次地开始。这真让我头疼 我现在拥有的是第n个 public static void main(String[] args) { ConsoleReader console = new ConsoleReader(); System.out.println("Enter the value for y
public static void main(String[] args)
{
ConsoleReader console = new ConsoleReader();
System.out.println("Enter the value for your n: ");
int num = (console.readInt());
System.out.println("\nThe largest nth fibonacci: "+fib(num));
System.out.println();
}
static int fib(int n){
int f = 0;
int g = 1;
int largeNum = -1;
for(int i = 0; i < n; i++)
{
if(i == (n-1))
largeNum = f;
System.out.print(f + " ");
f = f + g;
g = f - g;
}
return largeNum;
}
publicstaticvoidmain(字符串[]args)
{
ConsoleReader控制台=新的ConsoleReader();
System.out.println(“输入n:”)的值;
int num=(console.readInt());
System.out.println(“\n最大的第n个斐波那契:“+fib(num));
System.out.println();
}
静态整数fib(整数n){
int f=0;
int g=1;
int-largeNum=-1;
对于(int i=0;i
不要传递索引,n
,而是编写一个接受限制的函数,让它生成达到并包括该限制的斐波那契数。让它返回一个布尔值,这取决于它是否超出了限制,您可以使用它来检查该值是否在序列中
因为这是一个家庭作业,像这样的轻推可能是我们应该给你的全部…如果我理解正确,你需要做的(而不是写出前n个斐波那契数)是确定n是否是斐波那契数 因此,您应该修改您的方法以继续生成斐波那契序列,直到得到一个大于等于n的数字。如果等于,n是斐波那契数,否则不是 更新:由于@Moron一再声称基于公式的算法在性能上优于上面简单的算法,我实际上做了一个基准比较——具体地说是Jacopo的解决方案作为生成器算法和StevenH的上一个版本作为基于公式的算法。以下是准确的代码供参考:
public static void main(String[] args) {
measureExecutionTimeForGeneratorAlgorithm(1);
measureExecutionTimeForFormulaAlgorithm(1);
measureExecutionTimeForGeneratorAlgorithm(10);
measureExecutionTimeForFormulaAlgorithm(10);
measureExecutionTimeForGeneratorAlgorithm(100);
measureExecutionTimeForFormulaAlgorithm(100);
measureExecutionTimeForGeneratorAlgorithm(1000);
measureExecutionTimeForFormulaAlgorithm(1000);
measureExecutionTimeForGeneratorAlgorithm(10000);
measureExecutionTimeForFormulaAlgorithm(10000);
measureExecutionTimeForGeneratorAlgorithm(100000);
measureExecutionTimeForFormulaAlgorithm(100000);
measureExecutionTimeForGeneratorAlgorithm(1000000);
measureExecutionTimeForFormulaAlgorithm(1000000);
measureExecutionTimeForGeneratorAlgorithm(10000000);
measureExecutionTimeForFormulaAlgorithm(10000000);
measureExecutionTimeForGeneratorAlgorithm(100000000);
measureExecutionTimeForFormulaAlgorithm(100000000);
measureExecutionTimeForGeneratorAlgorithm(1000000000);
measureExecutionTimeForFormulaAlgorithm(1000000000);
measureExecutionTimeForGeneratorAlgorithm(2000000000);
measureExecutionTimeForFormulaAlgorithm(2000000000);
}
static void measureExecutionTimeForGeneratorAlgorithm(int x) {
final int count = 1000000;
final long start = System.nanoTime();
for (int i = 0; i < count; i++) {
isFibByGeneration(x);
}
final double elapsedTimeInSec = (System.nanoTime() - start) * 1.0e-9;
System.out.println("Running generator algorithm " + count + " times for " + x + " took " +elapsedTimeInSec + " seconds");
}
static void measureExecutionTimeForFormulaAlgorithm(int x) {
final int count = 1000000;
final long start = System.nanoTime();
for (int i = 0; i < count; i++) {
isFibByFormula(x);
}
final double elapsedTimeInSec = (System.nanoTime() - start) * 1.0e-9;
System.out.println("Running formula algorithm " + count + " times for " + x + " took " +elapsedTimeInSec + " seconds");
}
static boolean isFibByGeneration(int x) {
int a=0;
int b=1;
int f=1;
while (b < x){
f = a + b;
a = b;
b = f;
}
return x == f;
}
private static boolean isFibByFormula(int num) {
double first = 5 * Math.pow((num), 2) + 4;
double second = 5 * Math.pow((num), 2) - 4;
return isWholeNumber(Math.sqrt(first)) || isWholeNumber(Math.sqrt(second));
}
private static boolean isWholeNumber(double num) {
return num - Math.round(num) == 0;
}
简言之,生成器算法在所有正int值上都优于基于公式的解决方案-即使接近最大int值,其速度也要快两倍以上!
基于信念的性能优化到此为止;-)
对于记录,将上述代码修改为使用long
变量而不是int
,生成器算法会变慢(正如预期的那样,因为现在必须将long
值相加),公式开始变快的转换点约为10000000000L,即1012
更新2:正如IVlad和Moron所指出的,我不是浮点计算方面的专家:-)根据他们的建议,我将公式改进为:
private static boolean isFibByFormula(long num)
{
double power = (double)num * (double)num;
double first = 5 * power + 4;
double second = 5 * power - 4;
return isWholeNumber(Math.sqrt(first)) || isWholeNumber(Math.sqrt(second));
}
这将切换点降低到大约108(对于长版
版本-对于所有int值,带int
的生成器速度更快)。毫无疑问,将sqrt
调用替换为@Moron建议的调用将进一步降低转换点
我(和IVlad)的观点很简单,总是会有一个转换点,低于这个转换点,生成器算法会更快。因此,关于哪一种表现更好的说法在一般意义上没有意义,只是在某种背景下才有意义。阅读上题为“识别斐波那契数”的章节
或者,正整数z是斐波那契数当且仅当5z^2+4或5z^2中的一个− 4是一个完美的正方形
或者,您可以继续生成斐波那契数,直到一个数等于您的数:如果它等于,则您的数是斐波那契数,否则,这些数最终将大于您的数,您可以停止。然而,这是相当低效的 正整数x是斐波那契数当且仅当5x^2+4和5x^2-4中的一个是一个完美的平方我不知道是否有一个实际公式可以应用于用户输入。但是,您可以生成斐波那契序列,并对照用户输入检查它,直到它小于生成的最后一个数字
int userInput = n;
int a = 1, b = 1;
while (a < n) {
if (a == n)
return true;
int next = a + b;
b = a;
a = next;
}
return false;
intuserinput=n;
INTA=1,b=1;
while(a
如果我的Java不是太生锈
static bool isFib(int x) {
int a=0;
int b=1;
int f=1;
while (b < x){
f = a + b;
a = b;
b = f;
}
return x == f;
}
static bool isFib(int x){
int a=0;
int b=1;
int f=1;
while(b
为了充分利用您已经编写的代码,我首先提出以下建议,因为这是最简单的解决方案(但不是最有效的):
有很多方法可以用来确定给定的数字是否在斐波那契序列中,可以在上面看到一些选择 但是,考虑到您已经完成的工作,我可能会使用更为暴力的方法,例如:
我可能会使用递归方法,传入当前的n值(即,它计算第n个斐波那契数)和目标数。可以用两种方法来实现,递归和数学方法。 递归方法 开始生成斐波那契序列,直到您找到或通过该数字 这里很好地描述了数学方法。。。
祝你好运。好的。由于人们声称我只是空谈(“事实”与“猜测”),没有任何数据支持,我写了一个自己的基准 不是java,而是下面的C代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace SO
{
class Program
{
static void Main(string[] args)
{
AssertIsFibSqrt(100000000);
MeasureSequential(1);
MeasureSqrt(1);
MeasureSequential(10);
MeasureSqrt(10);
MeasureSequential(50);
MeasureSqrt(50);
MeasureSequential(100);
MeasureSqrt(100);
MeasureSequential(100000);
MeasureSqrt(100000);
MeasureSequential(100000000);
MeasureSqrt(100000000);
}
static void MeasureSequential(long n)
{
int count = 1000000;
DateTime start = DateTime.Now;
for (int i = 0; i < count; i++)
{
IsFibSequential(n);
}
DateTime end = DateTime.Now;
TimeSpan duration = end - start;
Console.WriteLine("Sequential for input = " + n +
" : " + duration.Ticks);
}
static void MeasureSqrt(long n)
{
int count = 1000000;
DateTime start = DateTime.Now;
for (int i = 0; i < count; i++)
{
IsFibSqrt(n);
}
DateTime end = DateTime.Now;
TimeSpan duration = end - start;
Console.WriteLine("Sqrt for input = " + n +
" : " + duration.Ticks);
}
static void AssertIsFibSqrt(long x)
{
Dictionary<long, bool> fibs = new Dictionary<long, bool>();
long a = 0;
long b = 1;
long f = 1;
while (b < x)
{
f = a + b;
a = b;
b = f;
fibs[a] = true;
fibs[b] = true;
}
for (long i = 1; i <= x; i++)
{
bool isFib = fibs.ContainsKey(i);
if (isFib && IsFibSqrt(i))
{
continue;
}
if (!isFib && !IsFibSqrt(i))
{
continue;
}
Console.WriteLine("Sqrt Fib test failed for: " + i);
}
}
static bool IsFibSequential(long x)
{
long a = 0;
long b = 1;
long f = 1;
while (b < x)
{
f = a + b;
a = b;
b = f;
}
return x == f;
}
static bool IsFibSqrt(long x)
{
long y = 5 * x * x + 4;
double doubleS = Math.Sqrt(y);
long s = (long)doubleS;
long sqr = s*s;
return (sqr == y || sqr == (y-8));
}
}
}
当n=50时,sqrt方法本身就优于naive方法,这可能是因为我的机器上存在硬件支持。即使它是10^8(就像在彼得的测试中),在这个截止点下最多有40个斐波那契数,这可以很容易地放入查找中
private static void main(string[] args)
{
//This will determnine which numbers between 1 & 100 are in the fibonacci series
//you can swop in code to read from console rather than 'i' being used from the for loop
for (int i = 0; i < 100; i++)
{
bool result = isFib(1);
if (result)
System.out.println(i + " is in the Fib series.");
System.out.println(result);
}
}
private static bool isFib(int num)
{
int counter = 0;
while (true)
{
if (fib(counter) < num)
{
counter++;
continue;
}
if (fib(counter) == num)
{
return true;
}
if (fib(counter) > num)
{
return false;
}
}
}
public static long fib(int n)
{
if (n <= 1)
return n;
else
return fib(n-1) + fib(n-2);
}
//(5z^2 + 4 or 5z^2 − 4) = a perfect square
//perfect square = an integer that is the square of an integer
private static bool isFib(int num)
{
double first = 5 * Math.pow((num), 2) + 4;
double second = 5 * Math.pow((num), 2) - 4;
return isWholeNumber(Math.sqrt(first)) || isWholeNumber(Math.sqrt(second));
}
private static bool isWholeNumber(double num)
{
return num - Math.round(num) == 0;
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace SO
{
class Program
{
static void Main(string[] args)
{
AssertIsFibSqrt(100000000);
MeasureSequential(1);
MeasureSqrt(1);
MeasureSequential(10);
MeasureSqrt(10);
MeasureSequential(50);
MeasureSqrt(50);
MeasureSequential(100);
MeasureSqrt(100);
MeasureSequential(100000);
MeasureSqrt(100000);
MeasureSequential(100000000);
MeasureSqrt(100000000);
}
static void MeasureSequential(long n)
{
int count = 1000000;
DateTime start = DateTime.Now;
for (int i = 0; i < count; i++)
{
IsFibSequential(n);
}
DateTime end = DateTime.Now;
TimeSpan duration = end - start;
Console.WriteLine("Sequential for input = " + n +
" : " + duration.Ticks);
}
static void MeasureSqrt(long n)
{
int count = 1000000;
DateTime start = DateTime.Now;
for (int i = 0; i < count; i++)
{
IsFibSqrt(n);
}
DateTime end = DateTime.Now;
TimeSpan duration = end - start;
Console.WriteLine("Sqrt for input = " + n +
" : " + duration.Ticks);
}
static void AssertIsFibSqrt(long x)
{
Dictionary<long, bool> fibs = new Dictionary<long, bool>();
long a = 0;
long b = 1;
long f = 1;
while (b < x)
{
f = a + b;
a = b;
b = f;
fibs[a] = true;
fibs[b] = true;
}
for (long i = 1; i <= x; i++)
{
bool isFib = fibs.ContainsKey(i);
if (isFib && IsFibSqrt(i))
{
continue;
}
if (!isFib && !IsFibSqrt(i))
{
continue;
}
Console.WriteLine("Sqrt Fib test failed for: " + i);
}
}
static bool IsFibSequential(long x)
{
long a = 0;
long b = 1;
long f = 1;
while (b < x)
{
f = a + b;
a = b;
b = f;
}
return x == f;
}
static bool IsFibSqrt(long x)
{
long y = 5 * x * x + 4;
double doubleS = Math.Sqrt(y);
long s = (long)doubleS;
long sqr = s*s;
return (sqr == y || sqr == (y-8));
}
}
}
Sequential for input = 1 : 110011
Sqrt for input = 1 : 670067
Sequential for input = 10 : 560056
Sqrt for input = 10 : 540054
Sequential for input = 50 : 610061
Sqrt for input = 50 : 540054
Sequential for input = 100 : 730073
Sqrt for input = 100 : 540054
Sequential for input = 100000 : 1490149
Sqrt for input = 100000 : 540054
Sequential for input = 100000000 : 2180218
Sqrt for input = 100000000 : 540054
//Program begins
public class isANumberFibonacci {
public static int fibonacci(int seriesLength) {
if (seriesLength == 1 || seriesLength == 2) {
return 1;
} else {
return fibonacci(seriesLength - 1) + fibonacci(seriesLength - 2);
}
}
public static void main(String args[]) {
int number = 4101;
int i = 1;
while (i > 0) {
int fibnumber = fibonacci(i);
if (fibnumber != number) {
if (fibnumber > number) {
System.out.println("Not fib");
break;
} else {
i++;
}
} else {
System.out.println("The number is fibonacci");
break;
}
}
}
}
//Program ends
public static boolean isNumberFromFibonacciSequence(int num){
if (num == 0 || num == 1){
return true;
}
else {
//5n^2 - 4 OR 5n^2 + 4 should be perfect squares
return isPerfectSquare( 5*num*num - 4) || isPerfectSquare(5*num*num - 4);
}
}
private static boolean isPerfectSquare(int num){
double sqrt = Math.sqrt(num);
return sqrt * sqrt == num;
}
public static int isFibonacci (int n){
int isFib = 0;
int a = 0, b = 0, c = a + b; // set up the initial values
do
{
a = b;
b = c;
c = a + b;
if (c == n)
isFib = 1;
} while (c<=n && isFin == 0)
return isFib;
}
public static void main(String [] args){
System.out.println(isFibonacci(89));
}