欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java的函數(shù)方法詳解(含漢諾塔問題)

 更新時(shí)間:2023年11月11日 14:49:32   作者:Ice_Sugar_7  
漢諾塔問題是一個(gè)經(jīng)典的遞歸問題,下面這篇文章主要給大家介紹了關(guān)于Java函數(shù)方法(含漢諾塔問題)的相關(guān)資料,文中通過圖文以及代碼示例介紹的非常詳細(xì),需要的朋友可以參考下

方法的概念

Java的方法和C語言的函數(shù)差不多,這里只講一些有區(qū)別的地方。我們以一個(gè)簡單的求和函數(shù)為例:

public class Method{
// 方法的定義
	public static int add(int x, int y) {
		return x + y;
	}
}

①首先public static是修飾符,現(xiàn)階段直接使用 public static 固定搭配。
②然后是參數(shù)列表,如果方法沒有參數(shù),那么()里面什么都不用寫。
③方法必須寫在類當(dāng)中,也就是說你不能在類外面憑空定義一個(gè)方法。
④方法不能嵌套定義,一個(gè)方法里面不能再定義另外一個(gè)方法。

有一點(diǎn)要單獨(dú)拿出來說:⑤在java當(dāng)中,沒有方法聲明這一說。方法是不用聲明的。

C語言編譯代碼時(shí)是自上向下編譯的,如果你在上面寫了A函數(shù),下面寫了B函數(shù),那A是不認(rèn)識(shí)B的,你要在A函數(shù)中調(diào)用B函數(shù),就得進(jìn)行聲明;
而Java編譯是看全局的,還是上面那個(gè)例子,在Java當(dāng)中A是認(rèn)識(shí)B的,所以這回你不用聲明,直接調(diào)用B。

方法的重載

有這樣的一個(gè)情境:

你寫了一個(gè)求兩個(gè)整數(shù)之和的方法,但如果你想求三個(gè)數(shù)的和、四個(gè)數(shù)的和…乃至n個(gè)數(shù)之和,甚至你要求n個(gè)浮點(diǎn)數(shù)之和,那豈不是每一次都要重新寫一個(gè)方法?!麻煩死了!
所以方法重載應(yīng)運(yùn)而生。

所謂的重載,簡單理解就是“一詞多義”:比如“好人”一詞,可以指一個(gè)人品行端正良好,而當(dāng)下互聯(lián)網(wǎng)中衍生出的“好人卡”一詞中的好人則是另外一個(gè)意思。(懂的都懂,希望你們不會(huì)被發(fā)好人卡)

所以當(dāng)我們把“一詞多義”代入到Java的語境之中,就是指方法名相同,但是參數(shù)列表不同。

參數(shù)列表指的是參數(shù)的個(gè)數(shù)、參數(shù)的類型、類型的次序,在方法名相同的情況下,這三個(gè)只要有一個(gè)不同,那么這個(gè)方法就會(huì)被重載了。

不知道你有沒有發(fā)現(xiàn),參數(shù)列表是不包括返回值類型的,這是一個(gè)要注意的點(diǎn):兩個(gè)方法如果僅僅只是因?yàn)榉祷刂殿愋筒煌遣荒軜?gòu)成重載的。(你這樣寫的話編譯器會(huì)報(bào)錯(cuò)的。)

方法簽名

看到這里你肯定會(huì)有疑問:在同一個(gè)作用域中不能定義兩個(gè)相同名稱的標(biāo)識(shí)符。比如:方法中不能定義兩個(gè)名字一樣的變量,那為什么類中就可以定義方法名相同的方法呢?

這就與方法簽名有關(guān)了,方法簽名即:經(jīng)過編譯器編譯修改過之后方法最終的名字。它的具體方式為:方法全路徑名+參數(shù)列表+返回值類型,構(gòu)成方法完整的名字。方法名并不是我們表面所看到的“add”。
有這樣的一段代碼:

public class TestMethod {
	public static int add(int x, int y){
		return x + y;
	}
	public static double add(double x, double y){
		return x + y;
	}
	public static void main(String[] args) {
		add(1,2);
		add(1.5, 2.5);
	}
}

上述代碼經(jīng)過編譯之后,然后使用JDK自帶的javap反匯編工具查看,具體操作如下:

  • 先對(duì)工程進(jìn)行編譯生成.class字節(jié)碼文件
  • 在控制臺(tái)中進(jìn)入到要查看的.class所在的目錄
  • 輸入:javap -v 字節(jié)碼文件名字即可

注:D指的就是double,I就是int。

遞歸

假如當(dāng)下有一個(gè)問題,我們可以把它拆成一個(gè)小的問題,而這個(gè)小的問題又可以拆成更小的問題,并且這些問題的解決辦法相同,那我們就可以使用遞歸,它類似數(shù)學(xué)中的數(shù)學(xué)歸納法,你想一下,數(shù)學(xué)歸納法需要你找到某個(gè)規(guī)律,然后證明第一項(xiàng)符合這個(gè)規(guī)律和每項(xiàng)之間的遞推關(guān)系,這個(gè)遞推關(guān)系指的是假如第k項(xiàng)成立,你就可以推出第(k+1)項(xiàng)也成立,上述這兩個(gè)條件成立的話,那你就可以推出第一項(xiàng)到第n項(xiàng)都符合這個(gè)規(guī)律。而遞歸要你找到從第n項(xiàng)往前推的方法。

所以,遞歸的出口其實(shí)是數(shù)學(xué)歸納法的起始(第一項(xiàng))。

在遞歸之中,方法的調(diào)用是需要開辟內(nèi)存的,而當(dāng)它調(diào)用結(jié)束后,這塊內(nèi)存就銷毀了。而如果一直調(diào)用但是不“歸”,會(huì)導(dǎo)致棧溢出,因此遞歸需要有一個(gè)出口,

例題:漢諾塔問題

首先我們來分析一下四個(gè)盤子的情況

首先把最上面盤子放到B柱,第二個(gè)盤子放在C柱;

然后把第一個(gè)盤子放到第二個(gè)盤子上面,再把第三個(gè)盤子放到B柱;

再把第一個(gè)盤子先放A柱(第四個(gè)盤子上面),然后第二個(gè)放第三個(gè)上面,再將第一個(gè)放第二個(gè)上面,得到上圖。

接著將第四個(gè)放C柱

最開始n個(gè)盤子在A柱,那我就得先把上面的(n-1)個(gè)盤子移到B,這個(gè)移動(dòng)過程我們得借助C才能移到B。移好之后就得考慮把(n-1)個(gè)盤子移到C,那我們繼續(xù)拆分問題,就是把上面的(n-2)個(gè)盤子先借助C移動(dòng)到A,這樣B柱就只剩下一個(gè)盤子,把它移動(dòng)到C就ok了。

現(xiàn)在剩下(n-2)個(gè)盤子在A柱,仿照上面的思路,先把(n-3)個(gè)盤子借助C移到B,再把A柱剩下的一個(gè)盤子拿到C,剩下(n-3)個(gè)盤子重復(fù)上面的做法。

至此,你應(yīng)該找到遞歸的感覺吧?那接下來開始寫代碼。

首先來寫一個(gè)方法,它用來記錄每次移動(dòng)一個(gè)盤子的軌跡(把這個(gè)盤子從哪移到哪,就是下面的pos1和pos2)

   public static void move(char pos1,char pos2) {
       System.out.print(pos1 + "->" + pos2 + ' ');  //打印移動(dòng)途徑
   }

接著我們來寫移動(dòng)盤子的方法,它應(yīng)該有四個(gè)參數(shù):盤子數(shù),移動(dòng)前所處的柱子,移動(dòng)時(shí)要借助的柱子(稱為中轉(zhuǎn)柱),要移動(dòng)到的柱子。

   public static void hanio(int n,char pos1,char pos2,char pos3) {
       if(n == 1) {
           move(pos1,pos3);   //只有一個(gè)盤子時(shí)就直接移到C柱
           return;
       }
       else {
           hanio(n-1,pos1,pos3,pos2);
           move(pos1,pos2);
           hanio(n-1,pos2,pos1,pos3);
       }
   }

我們將A、B、C分別記為pos1,pos2,pos3(注意與上面函數(shù)的pos1,pos2,pos3作區(qū)分),然后來寫下main函數(shù):

    public static void main(String[] args) {
        char pos1 = 'A',pos2 = 'B',pos3 = 'C';
        hanio(5,pos1,pos2,pos3);
    }

這里我們來試下四個(gè)盤子時(shí)的移動(dòng)情況

那么在解決了這個(gè)問題之后,我們來思考一下從中學(xué)到了什么,或者說對(duì)遞歸有無更深的理解。

遞歸采用的就是“大事化小”的思路,比如上面我們要移動(dòng)n個(gè)盤子,那么就把這個(gè)問題轉(zhuǎn)化為移動(dòng)(n-1)+1 個(gè)盤子,而移動(dòng)(n-1)個(gè)盤子又可以轉(zhuǎn)化為移動(dòng)(n-2)+1個(gè)盤子。
這道題的難點(diǎn)在于,它表面要你把最底下的盤子移過去,但實(shí)際上你要關(guān)注的是它上面的(n-1)個(gè)盤子,然后你要知道這(n-1)個(gè)盤子每一次移動(dòng)的方法都是“借助C柱,在A和B之間來回移動(dòng)”,假如某次移動(dòng)后(n-1)個(gè)盤子在A,那原先最底下那個(gè)盤子就在B,此時(shí)直接把它拿到C就ok了

總結(jié) 

到此這篇關(guān)于Java的函數(shù)方法詳解的文章就介紹到這了,更多相關(guān)Java函數(shù)方法內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • JAVA開發(fā)中的一些規(guī)范講解(阿里巴巴Java開發(fā)規(guī)范手冊(cè))

    JAVA開發(fā)中的一些規(guī)范講解(阿里巴巴Java開發(fā)規(guī)范手冊(cè))

    這篇文章主要介紹了JAVA開發(fā)中的一些規(guī)范講解(阿里巴巴Java開發(fā)規(guī)范手冊(cè)),需要的朋友可以參考下
    2018-04-04
  • Spring Validation方法實(shí)現(xiàn)原理分析

    Spring Validation方法實(shí)現(xiàn)原理分析

    這篇文章主要介紹了Spring Validation實(shí)現(xiàn)原理分析,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-07-07
  • 詳解Java虛擬機(jī)管理的內(nèi)存運(yùn)行時(shí)數(shù)據(jù)區(qū)域

    詳解Java虛擬機(jī)管理的內(nèi)存運(yùn)行時(shí)數(shù)據(jù)區(qū)域

    這篇文章主要介紹了詳解Java虛擬機(jī)管理的內(nèi)存運(yùn)行時(shí)數(shù)據(jù)區(qū)域的相關(guān)資料,需要的朋友可以參考下
    2017-03-03
  • springcloud集成nacos?使用lb?無效問題解決方案

    springcloud集成nacos?使用lb?無效問題解決方案

    這篇文章主要介紹了解決springcloud集成nacos?使用lb?無效,通過查看spring-cloud-starter-gateway?jar中的自動(dòng)配置類的源碼,得知,該jar包中是不支持負(fù)載均衡的,需要引入spring-cloud-starter-loadbalancer?來支持,需要的朋友可以參考下
    2023-04-04
  • SSH框架網(wǎng)上商城項(xiàng)目第23戰(zhàn)之在線支付功能實(shí)現(xiàn)

    SSH框架網(wǎng)上商城項(xiàng)目第23戰(zhàn)之在線支付功能實(shí)現(xiàn)

    這篇文章主要為大家詳細(xì)介紹了SSH框架網(wǎng)上商城項(xiàng)目第23戰(zhàn)之在線支付功能實(shí)現(xiàn),感興趣的小伙伴們可以參考一下
    2016-06-06
  • Java中的異常處理用法及其架構(gòu)和使用建議

    Java中的異常處理用法及其架構(gòu)和使用建議

    Java同樣也提供了拋出異常、捕捉異常和finally語句的使用來處理程序異常,下面就來具體看一下Java中的異常處理用法及其架構(gòu)和使用建議:
    2016-06-06
  • Spring中基于xml的AOP實(shí)現(xiàn)詳解

    Spring中基于xml的AOP實(shí)現(xiàn)詳解

    這篇文章主要介紹了Spring中基于xml的AOP實(shí)現(xiàn)詳解,基于xml與基于注解的AOP本質(zhì)上是非常相似的,都是需要封裝橫切關(guān)注點(diǎn),封裝到切面中,然后把橫切關(guān)注點(diǎn)封裝為一個(gè)方法,再把該方法設(shè)置為當(dāng)前的一個(gè)通知,再通過切入點(diǎn)表達(dá)式定位到橫切點(diǎn)就可以了,需要的朋友可以參考下
    2023-09-09
  • Java中PreparedStatement的用法解析

    Java中PreparedStatement的用法解析

    這篇文章主要介紹了Java中PreparedStatement的用法解析,在JDBC應(yīng)用中,PreparedStatement是一種比Statement更好的選擇,PreparedStatement可以通過使用參數(shù)化查詢來避免SQL注入攻擊,并且可以提高查詢性能,需要的朋友可以參考下
    2023-09-09
  • Java Scanner 類的使用小結(jié)

    Java Scanner 類的使用小結(jié)

    在筆試編程過程中,關(guān)于數(shù)據(jù)的讀取如果迷迷糊糊,那后來的編程即使想法很對(duì),實(shí)現(xiàn)很好,也是徒勞,于是在這里認(rèn)真總結(jié)了Java Scanner 類的使用,需要的朋友可以參考下
    2018-10-10
  • Java socket 如何獲取gps定位

    Java socket 如何獲取gps定位

    在Java中使用Socket來直接獲取GPS定位信息并不直接可行,因?yàn)镚PS數(shù)據(jù)通常不是通過Socket通信來獲取的,本文給大家介紹Java socket 獲取gps定位的相關(guān)知識(shí),感興趣的朋友跟隨小編一起看看吧
    2024-07-07

最新評(píng)論