Home >Java >javaTutorial >3 ways to implement Fibonacci sequence in java

3 ways to implement Fibonacci sequence in java

高洛峰
高洛峰Original
2017-01-14 16:43:531215browse

Let me first talk about why I wrote this. This was entirely caused by a horrific murder caused by an interview at Alibaba. When I went for the interview, I arrived at Alibaba’s designated interview city at 11 o’clock the night before the interview. It was almost 1 o’clock before I found a hotel to stay. In addition, I didn’t sleep well at night, which directly led to the poor interview results the next day (for Those big shrimps who are looking for a job should not tell the little shrimps about the tragedy, it is still important to prepare in advance), the interview lasted for more than an hour (when I went back after the interview, I almost fell asleep while walking, so sad!!) At the end of the interview, the interviewer asked me a question about the Fibonacci sequence. At that time, my mind was completely confused. I only knew that I should set three variables or initialize them with a List. When I wrote the for loop, my mind was completely confused. It couldn't be more vague and I didn't write it out. In the end, I could only write the first method below under the guidance of the interviewer step by step. It shouldn't be done. From now on, Ali just used the entire application in a careless way. The framework has been set up. It is really a golden period for change and gold mining (the capable prawns should go quickly). After all, 99% of the data in Alibaba’s hands is important data, while 99% of the data is provided to search giants such as Baidu. Compared with garbage, for data analysis, Alibaba is better able to analyze the various detailed user data it has in hand, and can more accurately locate users' tastes and needs, and provide better solutions for precise push and precise advertising push. Serve. If Tencent's future dream is to provide water and electricity in users' lives, then Alibaba's future dream that may be realized is to provide users with basic necessities, food, housing, transportation, and collection of water and electricity, etc. O(∩_∩)O~ let's get to the point.
For excellent algorithm designers, there are only two things they care about based on the main implementation of the program function. One is the time complexity of the design algorithm, and the other is the space complexity (to put it bluntly, it is the time and space complexity used to execute a program). memory space occupied); based on different application scenarios, generally intelligent algorithm designers will find a balance point between the two relatively contradictory resources of time and space. For example, systems with high real-time requirements will generally use Space resources are exchanged for time or commonly used objects are generally resident in memory to improve response time (this is true for caching technology and most in-memory databases in NoSQL that are now popular). For embedded systems where memory resources are relatively precious, this is generally the case. Trade delay in exchange for time.
Let’s talk about the three implementations of the Fibonacci sequence, and how we can truly design an excellent algorithm that truly meets the actual application scenario.
First, let’s talk about the Fibonacci sequence:
Literally speaking, The Fibonacci sequence starts with 0 and 1, and the subsequent Fibonacci coefficients are the sum of the previous two numbers. The sequence format is as follows:
0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765, 10946,………………
In mathematics, it is defined recursively:
F_0=0
F_1=1
F_n = F_{n-1}+ F_{n-2}

Implementation requirements: input the serial number n and return the corresponding Fibonacci number
Program Implementation 1—Function Self-Iteration

/**
  * 函数自迭代
  * @Title: fnType1
  * @Description: TODO
  * @param @param n
  * @param @return    
  * @return int 
  * @throws Exception
  */
 public int fnType1(int n)throws Exception{
  if(n==0){
   return 0;
  }else if(n==1||n==2){
   return 1;
  }else if(n>2){
   int temp=fnType1(n-1)+fnType1(n-2);
   if(temp<0){
    throw new Exception("Invalid value for int type, too larage");
   }else{
    return temp;
   }
  }else{
   throw new Exception("IllegalArgument value for n,please enter n>=0 ");
  }
 }

Disadvantages of this method: A large number of iterations continuously consume stack space (those engaged in web development, debugging and maintenance should know the value of server stack resources. If a large number of concurrent iteration calls cause the server to The stack resources are not recycled for a long time, causing the web server to crash), the efficiency is low, and the function self-closure is relatively weak (an excellent interface should capture possible error messages in input and output and provide clear processing results), It is easy to make errors and difficult to debug. This method is generally not recommended in practical applications, and the number of iterations cannot exceed 3 times;
Program implementation 2 - time for space

/**
  * 时间换空间
  * @Title: fnType2
  * @Description: TODO
  * @param @param n
  * @param @return    
  * @return int (n<0 return -1,beyond max int size return -2)
  * @throws
  */
 public int fnType2(int n){
  int result=-1;
  int temp1=0;
  int temp2=1;
  for(int index=0;index<=n;index++){
   if(index==0){
    result=temp1;
   }else if(index==1){
    result=temp2;
   }else{
    result=temp1+temp2;
    if(result<0){
     result=-2;
     break;
    }
    temp1=temp2;
    temp2=result;
   }
  }
  return result;
 }

This method is mainly Used in: Usage scenario one: Scenarios where objects or variables are used rarely and will not be used again after being used once; usage scenario two: many embedded system designs where memory resources are scarce and real-time requirements are not too high. This method will be used;
Program Implementation 3 - Space for Time

 private static List<Integer> fnData=new ArrayList<Integer>();
 private static final int maxSize=50000;
 /**
  * 初始化器
  * @Title: setFnData
  * @Description: TODO
  * @param     
  * @return void
  * @throws
  */
 private static  void setFnData(){
  int result=-1;
  int temp1=0;
  int temp2=1;
  for(int index=0;index<=maxSize;index++){
   if(index==0){
    result=temp1;
   }else if(index==1){
    result=temp2;
   }else{
    result=temp1+temp2;
    if(result<0){
     result=-2;
     break;
    }
    temp1=temp2;
    temp2=result;
   }
   fnData.add(result);
  }
 }
 /**
  * 对外接口
  * @Title: getFnData
  * @Description: TODO
  * @param @param n
  * @param @return    
  * @return int <span style="font-family: sans-serif;">(n beyond fnData.size() and n<0 return -1)</span>
  * @throws
  */
 public int getFnData(int n){
  if(fnData.size()==0){
   setFnData();
  }
  if(fnData.size()>n&&n>=0){
   return fnData.get(n);
  }else{
   return -1;
  }
 }

This method is generally used in scenarios where objects or variables exist throughout the life cycle of the program or are frequently called, such as calling External WebService interface, abstract persistence layer, common configuration file parameter loading, etc.
Test case:

package com.dbc.yangg.swing.test;
import java.util.ArrayList;
import java.util.List;
/**
 * 输入序号n返回得到对应费波那西数
 * @ClassName: Init
 * @Description: TODO
 * @author guoyang2011@gmail.com
 * @date 2014年1月10日 下午7:52:13
 *
 */
public class Init {
 /**
  * 函数自迭代
  * @Title: fnType1
  * @Description: TODO
  * @param @param n
  * @param @return    
  * @return int 
  * @throws Exception
  */
 public int fnType1(int n)throws Exception{
  if(n==0){
   return 0;
  }else if(n==1||n==2){
   return 1;
  }else if(n>2){
   int temp=fnType1(n-1)+fnType1(n-2);
   if(temp<0){
    throw new Exception("Invalid value for int type, too larage");
   }else{
    return temp;
   }
  }else{
   throw new Exception("IllegalArgument value for n,please enter n>=0 ");
  }
 } 
 /**
  * 时间换空间
  * @Title: fnType2
  * @Description: TODO
  * @param @param n
  * @param @return    
  * @return int (n<0 return -1,beyond max int size return -2)
  * @throws
  */
 public int fnType2(int n){
  int result=-1;
  int temp1=0;
  int temp2=1;
  for(int index=0;index<=n;index++){
   if(index==0){
    result=temp1;
   }else if(index==1){
    result=temp2;
   }else{
    result=temp1+temp2;
    if(result<0){
     result=-2;
     break;
    }
    temp1=temp2;
    temp2=result;
   }
  }
  return result;
 }
 private static List fnData=new ArrayList();
 private static final int maxSize=50000;
 /**
  * 空间换时间
  * @Title: setFnData
  * @Description: TODO
  * @param     
  * @return void
  * @throws
  */
 private static  void setFnData(){
  int result=-1;
  int temp1=0;
  int temp2=1;
  for(int index=0;index<=maxSize;index++){
   if(index==0){
    result=temp1;
   }else if(index==1){
    result=temp2;
   }else{
    result=temp1+temp2;
    if(result<0){
     result=-2;
     break;
    }
    temp1=temp2;
    temp2=result;
   }
   fnData.add(result);
  }
 }
 /**
  * 
  * @Title: getFnData
  * @Description: TODO
  * @param @param n
  * @param @return    
  * @return int (n beyond fnData.size() and n<0 return -1)
  * @throws
  */
 public int getFnData(int n){
  if(fnData.size()==0){
   setFnData();
  }
  if(fnData.size()>n&&n>=0){
   return fnData.get(n);
  }else{
   return -1;
  }
 }
 /**
  * 
  * @Title: main
  * @Description: TODO
  * @param @param argv    
  * @return void
  * @throws
  */
 public static void main(String[] argv){
  Init init=new Init();
  int n=46;
  try {
   System.out.println("Type1="+init.fnType1(n));
  } catch (Exception e) {
   // TODO Auto-generated catch block
   System.out.println(e.getMessage());
  }
  System.out.println("Type2="+init.fnType2(n));
  System.out.println("Type3="+init.getFnData(n));
 }
}

Output result:

Type1=1836311903  
Type2=1836311903  
Type3=1836311903

对于算法设计,不要盲目遵循概念,概念是死的,人是活的(在这个需要crazy man的时代,有想法比循规蹈矩更有优势),只用结合具体的应用场景才能设计出优秀的算法和结构。
吐槽一下:个人认为优秀的数据结构设计可以简化算法设计的复杂度提高代码的可读性、程序的扩展性及执行效率;
再吐槽一下:做需求分析的时候应该遵循三点原则:1.从用户角度及其思维方式分析;2.用户说的不一定是他们真正想要的;3.用户说的不一定是对的。做程序开发遵循原则:积极提升自身品味,站在用户使用角度和使用场景分析功能;例如你做后台接口开发,你的用户就是接口调用者,你应该考虑接口功能是什么,使用者在什么情况下会调用,传入参数可能导致哪些异常,你的接口实现中可能出现哪些异常并对可能出现的异常进行捕获,清楚明了的输出,良好的函数自闭性;如果你是搞前台,那你应该在保证业务实现的基础上从用户使用习惯等方面把自己当做使用者来设计UI。很有意思对不,需求、开发多了自然就明白了O(∩_∩)O~。

更多java实现斐波那契数列的3种方法相关文章请关注PHP中文网!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn