日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > java >内容正文

java

阿克曼函数实现(Java代码)

發(fā)布時(shí)間:2023/12/14 java 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 阿克曼函数实现(Java代码) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

此文記錄阿克曼函數(shù)的遞歸和非遞歸的實(shí)現(xiàn),以及我對阿卡曼函數(shù)的認(rèn)識。

阿克曼函數(shù)定義

Ackermann(m,n)函數(shù)定義如下:
Ackermann(0,n) = n+1;
Ackermann(m,0) = Ackermann(m-1,1);
Ackermann(m,n) = Ackermann(m-1,Ackermann(m,n-1)),m>0,n>0。

遞歸實(shí)現(xiàn)

思路:遞歸實(shí)現(xiàn)就很簡單了,因?yàn)榻o出了表達(dá)式,確定邊界m==0后,直接往上套。
代碼:

public static long solve_rec(long m,long n){if(m == 0){return n+1;}else if(m > 0 && n == 0){return solve_rec(m-1,1);}else{return solve_rec(m-1,solve_rec(m,n-1));}}

非遞歸實(shí)現(xiàn)

思路:用棧來模擬遞歸實(shí)現(xiàn)阿克曼函數(shù)求解。先往棧中放入需要求解的ack(m,n),判斷m,n的狀態(tài)來進(jìn)行pop和push。說的很模糊,詳情見代碼。(思路來自該博客:https://blog.csdn.net/xiaofei_it/article/details/51524754)
舉例:以計(jì)算Ackermann(2,1)為例,結(jié)合代碼食用更加,ack為一個(gè)類,見后面詳細(xì)代碼。(關(guān)于圖中的res可以沒有描述清楚,以棧頂?shù)膔es為每次操作的結(jié)果)

代碼:

//思路:使用棧來模擬遞歸函數(shù)public static long solve(long m,long n){Stack<Ack> stack = new Stack<>();stack.push(new Ack(m,n)); //放入要求解的ack//res用來記錄ack(0,n)的值//如果res大于0,則說明當(dāng)前的函數(shù)層層調(diào)用(push)已經(jīng)到底了,開始pop了。long res = -1;while(!stack.empty()){Ack ack = stack.peek(); //對棧頂?shù)腶ck進(jìn)行分析if(ack.m == 0){ //m為0,則求解出ack(0,n)的結(jié)果賦給res,并移出stackres = ack.n+1;stack.pop();}else if(ack.n == 0 && ack.m > 0){if(res < 0) {stack.push(new Ack(ack.m-1,1)); //res小于0,Ackermann(m,0) = Ackermann(m-1,1);}else {stack.pop(); //res大于0,則說明已經(jīng)計(jì)算過了,可以pop}}else{if(ack.data < 0){ //還沒有賦值,只有維if(res < 0){stack.push(new Ack(ack.m,ack.n-1)); //計(jì)算Ackermann(m,n)所需要的Ackermann(m,n-1)}else {ack.data = res; //設(shè)置data是為了判斷是否被計(jì)算res = -1; //重置為1stack.push(new Ack(ack.m-1,ack.data));//Ackermann(m,n) = Ackermann(m-1,Ackermann(m,n-1)),這里的Ackermann(m,n-1)為data}}else{stack.pop(); //已經(jīng)計(jì)算出來的ack值被用到了,所以就pop出來}}}return res;}

詳細(xì)代碼

import java.util.Stack;public class Ackermann{public static void main(String[] args) {System.out.println(solve(2,1));System.out.println(solve_rec(2,1));}//思路:遞歸方法public static long solve_rec(long m,long n){if(m == 0){return n+1;}else if(m > 0 && n == 0){return solve_rec(m-1,1);}else{return solve_rec(m-1,solve_rec(m,n-1));}}//思路:使用棧來模擬遞歸函數(shù)。有點(diǎn)難理解public static long solve(long m,long n){Stack<Ack> stack = new Stack<>();stack.push(new Ack(m,n)); //放入要求解的ack//res用來記錄ack(0,n)的值//如果res大于0,則說明當(dāng)前的函數(shù)層層調(diào)用(push)已經(jīng)到底了,開始pop了。long res = -1;while(!stack.empty()){Ack ack = stack.peek(); //對棧頂?shù)腶ck進(jìn)行分析if(ack.m == 0){ //m為0,則求解出ack(0,n)的結(jié)果賦給res,并移出stackres = ack.n+1;stack.pop();}else if(ack.n == 0 && ack.m > 0){if(res < 0) {stack.push(new Ack(ack.m-1,1)); //res小于0,Ackermann(m,0) = Ackermann(m-1,1);}else {stack.pop(); //res大于0,則說明已經(jīng)計(jì)算過了,可以pop}}else{if(ack.data < 0){ //還沒有賦值,只有維if(res < 0){stack.push(new Ack(ack.m,ack.n-1)); //計(jì)算Ackermann(m,n)所需要的Ackermann(m,n-1)}else {ack.data = res; //設(shè)置data是為了判斷是否被計(jì)算res = -1; //重置為1stack.push(new Ack(ack.m-1,ack.data));//Ackermann(m,n) = Ackermann(m-1,Ackermann(m,n-1)),這里的Ackermann(m,n-1)為data}}else{stack.pop(); //已經(jīng)計(jì)算出來的ack值被用到了,所以就pop出來}}}return res;}}class Ack{public long m;public long n;public long data;public Ack(long m, long n) {this.m = m;this.n = n;this.data = -1;} }

扯淡

做這道算法題時(shí),題目很簡陋(就一個(gè)ack函數(shù),且沒有給出范圍!!!),并不知道這是阿克曼函數(shù),以前也沒有聽聞過(比較孤陋寡聞。。。)。有趣的就是,當(dāng)我寫好這個(gè)遞歸代碼時(shí),我隨便用了(5,3)作為例子來跑一下。等了一下說是棧溢出,我就感覺可能是代碼哪個(gè)地方寫錯(cuò)了。我就測試了一下(2,1)和(2,5)兩個(gè)例子發(fā)現(xiàn)沒有問題。然后我就隨便在一個(gè)地方加上了一個(gè)print,發(fā)現(xiàn)一直在循環(huán),這就讓我懷疑是不是代碼寫錯(cuò)了(因?yàn)槲也皇莗rint中間的結(jié)果),我又檢查了一遍邏輯發(fā)現(xiàn)沒有錯(cuò)誤啊。
然后我就百度了一下,才發(fā)現(xiàn)這是阿克曼函數(shù),百度百科給出的一句話“阿克曼函數(shù)它的輸出值增長速度非常快,僅是對于(4,3)的輸出已大得不能準(zhǔn)確計(jì)算。”當(dāng)時(shí)我就震驚了(內(nèi)心os:啥叫大的不能計(jì)算。我也沒看出它有這么大),然后看到關(guān)于阿卡曼函數(shù)的科普,給我的感覺就是,真tm大。大概有這么大:
Ackermann( 0 , n ) = n + 1
Ackermann ( 1 , n ) = n + 2
Ackermann ( 2 , n ) = 2n + 3
Ackermann ( 3 , n ) = 2^(3+n) - 3
Ackermann ( 4 , 0 ) = 2^4 - 3
Ackermann ( 4 , 1 ) = 2 ^ (2 ^ 4) - 3 = 2^16 -3
Ackermann ( 4 , 2 ) = 2^ (2^ (2^ 4)) - 3 = 2^65536 - 3

要知道java中的long類型最大值也就2^64-1。
我不禁回想起斐波拉契數(shù)列的第5000項(xiàng)也不過1000多位數(shù)(計(jì)算Fibonacci的第5000項(xiàng)),而Ackermann(4,2)就有19729位數(shù)。兩者完全不是一個(gè)數(shù)量級的。我還企圖計(jì)算Ackermann(5,3),算它幾個(gè)世紀(jì)未必算出來。還是要多讀書多看報(bào)才能避免自己的無知。?_?

總結(jié)

以上是生活随笔為你收集整理的阿克曼函数实现(Java代码)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 自拍偷拍五月天 | 深夜在线免费视频 | 精品欧美一区二区久久久久 | 日本免费一区二区在线 | 中文字幕日韩在线观看 | 国产午夜精品无码一区二区 | 精品人妻在线视频 | 欧美专区在线视频 | 色老头在线一区二区三区 | 天堂网va| 日本久久激情 | 国产成人91 | 欧美激情三区 | 大学生一级一片全黄 | 国产亚洲精品女人久久久久久 | 国产av一区二区三区精品 | 高清久久久 | 九九九精品视频 | 日韩欧美一区二区三区久久婷婷 | 99自拍视频在线观看 | 日韩精品中文字幕一区二区 | 五月天婷婷基地 | 大奶毛片 | 少妇人妻丰满做爰xxx | 国产玖玖在线 | 婚后打屁股高h1v1调教 | 男人天堂中文字幕 | 国产成人精品一区二三区 | 69av在线视频| 国产一区二区观看 | 在线观看不卡av | 欧美一区二区三区四区在线观看 | 日本在线观看一区二区三区 | 淫僧荡尼巨乳(h)小说 | 久久久久久久久久久97 | 激情福利网 | 国产片高清在线观看 | 欧美aaaaa| 日韩国产精品一区二区 | 正在播放adn156松下纱荣子 | 成人a视频在线观看 | 打白嫩屁屁网站视频短裙 | 波多野结衣高清视频 | 中文资源在线播放 | www.夜夜爱| 91在线超碰| 日日爱886 | 91羞羞网站 | 精品久| 久久精品国产免费看久久精品 | 99热影院 | 在线一区二区三区四区 | 亚洲看片网 | 免费看女生裸体视频 | 免费看黄色一级片 | 成人h网站| 日本一区二区三区精品 | 欧美日韩第一区 | 久久精品99国产精品日本 | 日本网站在线 | 欧美日韩精品久久 | 波多野结衣亚洲天堂 | 337p粉嫩日本欧洲亚洲大胆 | 性欧美日本 | 蜜臀在线观看 | 午夜视频精品 | 中文字幕一区av | 亚洲黄色小说视频 | 老司机深夜影院 | 中文字幕乱码人妻无码久久 | 久久亚洲综合色 | 特级毛片网站 | 天天色天天色 | 伊人欧美 | 午夜成人免费电影 | 亚洲视频三区 | 国产欧美日韩在线视频 | 天天天天操 | 成人午夜激情网 | 九热这里只有精品 | 天天舔天天射 | 男人激烈吮乳吃奶爽文 | 欧美日韩国产三级 | 成人黄色在线 | 麻豆蜜桃wwww精品无码 | 毛片在线播放视频 | 免费在线观看网址 | 成人av无码一区二区三区 | 精品视频一区二区三区在线观看 | 美女隐私免费观看 | 午夜视频导航 | 久久h视频| 男人操女人的免费视频 | 免费成人高清 | 97在线公开视频 | 欧美激情第1页 | 男插女在线观看 | 三浦理惠子av在线播放 | 亚洲GV成人无码久久精品 |