TypeScript中怎么實(shí)現(xiàn)一個(gè)斐波那契數(shù)列

這篇文章將為大家詳細(xì)講解有關(guān)TypeScript中怎么實(shí)現(xiàn)一個(gè)斐波那契數(shù)列,文章內(nèi)容質(zhì)量較高,因此小編分享給大家做個(gè)參考,希望大家閱讀完這篇文章后對(duì)相關(guān)知識(shí)有一定的了解。

成都一家集口碑和實(shí)力的網(wǎng)站建設(shè)服務(wù)商,擁有專業(yè)的企業(yè)建站團(tuán)隊(duì)和靠譜的建站技術(shù),十年企業(yè)及個(gè)人網(wǎng)站建設(shè)經(jīng)驗(yàn) ,為成都上1000家客戶提供網(wǎng)頁設(shè)計(jì)制作,網(wǎng)站開發(fā),企業(yè)網(wǎng)站制作建設(shè)等服務(wù),包括成都營銷型網(wǎng)站建設(shè),品牌網(wǎng)站制作,同時(shí)也為不同行業(yè)的客戶提供做網(wǎng)站、成都做網(wǎng)站的服務(wù),包括成都電商型網(wǎng)站制作建設(shè),裝修行業(yè)網(wǎng)站制作建設(shè),傳統(tǒng)機(jī)械行業(yè)網(wǎng)站建設(shè),傳統(tǒng)農(nóng)業(yè)行業(yè)網(wǎng)站制作建設(shè)。在成都做網(wǎng)站,選網(wǎng)站制作建設(shè)服務(wù)商就選成都創(chuàng)新互聯(lián)。

const fib = (n: number): number => n <= 1 ? n : fib(n - 1) + fib(n - 2);  for (let i = 0; i < 10; i++) {   console.log(i, fib(i)); }

運(yùn)行結(jié)果如下:

TypeScript中怎么實(shí)現(xiàn)一個(gè)斐波那契數(shù)列

斐波那契數(shù)列打印結(jié)果

程序完全沒問題,完結(jié)撒花!

開玩笑的,上面是只一個(gè)用了TypeScript類型定義的JavaScript寫法,我們其實(shí)真正想這樣做&darr;&darr;&darr;, 也就是使用TS  Type解決FIbonacci

import { Fib, Add } from './fib-type';  type one = Fib<1>; type zero = Fib<0>; type Two = Add<one, one>; type Five = Add<Two, Add<Two, one>>; type Fib5 = Fib<Five>; type Fib9 = Fib<9>; type r0 = Fib<Zero>; // type r0= 0 type r1 = Fib<One>; // type r1 = 1 type r2 = Fib<Two>; // type r2 = 1 type r3 = Fib<3>; // type r3 = 2 type r4 = Fib<4>; // type r4 = 3 type r5 = Fib<5>; // type r5 = 5 type r6 = Fib<6>; // type r6 = 8 type r9 = Fib<9>; // type r9 = 34 type sum = Add<r9, r6>; // type sum = 42

TypeScript中怎么實(shí)現(xiàn)一個(gè)斐波那契數(shù)列

類型提示

二、我們?cè)撛趺醋?/h3>

要想實(shí)現(xiàn)斐波那契數(shù)列,參考一開始的代碼,有基本的比較, 加法, 循環(huán)語法, 所以我們也需要使用類型系統(tǒng)依次實(shí)現(xiàn)這三種功能

2.1 加法的實(shí)現(xiàn)

為了實(shí)現(xiàn)加法, 需要先實(shí)現(xiàn)一些工具類型

// 元組長度 type Length<T extends any[]> = T['length']; type one = 1   // 使用extends實(shí)現(xiàn)數(shù)字相等的比較 type a111 = 0 extends one ? true : false // type a111 = false type a112 = 1 extends one ? true : false // type a112 = true

range的實(shí)現(xiàn)是遞歸實(shí)現(xiàn)的

// 偽代碼 function range(n, list=[]){   if(n<=0) return list.length   return range(n-1, [1, ...list]) }

TypeScript的限制, 沒有循環(huán), 只能用遞歸代替循環(huán), 后面會(huì)有幾個(gè)類似的寫法, 記住一點(diǎn):遞歸有幾個(gè)出口, 對(duì)象就有幾個(gè) key, 每個(gè) key  就是一個(gè)條件

// 創(chuàng)建指定長度的元組, 用第二個(gè)參數(shù)攜帶返回值 type Range<T extends Number = 0, P extends any[] = []> = {   0: Range<T, [any, ...P]>;   1: P; }[Length<P> extends T ? 1 : 0];  // 拼接兩個(gè)元組 type Concat<T extends any[], P extends any[]> = [...T, ...P];  type t1 = Range<3>; // type t1 = [any, any, any]  type Zero = Length<Range<0>>; //   type Zero = 0 type Ten = Length<Range<10>>; // type Ten = 10  type Five = Length<Range<5>>; // type Five = 5  type One = Length<Range<1>>;

有了上面的工具語法,那么實(shí)現(xiàn)加法就比較容易了, 只需要求兩個(gè)元組合并后的長度

type Add<T extends number, P extends number> = Length<    Concat<Range<T>, Range<P>>  >;  type Two = Add<One, One>;  //   type Two = 2  type Three = Add<One, Two>;  // type Three = 3

有了加法,該如何實(shí)現(xiàn)減法呢?一般減法和除法都比加法難, 所以我們需要更多的工具類型函數(shù)!

2.2 工具函數(shù)

2.2.1 實(shí)現(xiàn)一些基本工具類型

  • Shift:刪除第一個(gè)元素

  • Append:在元組末尾插入元素

  • IsEmpty / NotEmpty:判斷列表為空

// 去除元組第一個(gè)元素 [1,2,3] -> [2,3] type Shift<T extends any[]> = ((...t: T) => any) extends (   _: any,   ...Shift: infer P ) => any   ? P   : [];  type pp = Shift<[number, boolean,string, Object]> // type pp = [boolean, string, Object]  // 向元組中追加 type Append<T extends any[], E = any> = [...T, E]; type IsEmpty<T extends any[]> = Length<T> extends 0 ? true : false; type NotEmpty<T extends any[]> = IsEmpty<T> extends true ? false : true; type t4 = IsEmpty<Range<0>>; // type t4 = true  type t5 = IsEmpty<Range<1>>; // type t5 = false

2.2.2 邏輯類型

  • And:a && b

// 邏輯操作 type And<T extends boolean, P extends boolean> = T extends false   ? false   : P extends false   ? false   : true; type t6 = And<true, true>; // type t6 = true  type t7 = And<true, false>; // type t7 = false  type t8 = And<false, false>; // type t8 = false  type t9 = And<false, true>; // type t9 = false

2.2.3 小于等于

偽代碼: 主要思想是同時(shí)從列表中取出一個(gè)元素, 長度先到0的列表比較短

function dfs (a, b){     if(a.length && b.length){         a.pop()         b.pop()         return dfs(a,b)     }else if(a.length){         a >= b     }else if (b.length){         b > a     } }

思想:將數(shù)字的比較轉(zhuǎn)換為列表長度的比較

// 元組的小于等于   T <= P, 同時(shí)去除一個(gè)元素, 長度先到0的比較小 type LessEqList<T extends any[], P extends any[]> = {   0: LessEqList<Shift<T>, Shift<P>>;   1: true;   2: false; }[And<NotEmpty<T>, NotEmpty<P>> extends true   ? 0   : IsEmpty<T> extends true   ? 1   : 2];   // 數(shù)字的小于等于 type LessEq<T extends number, P extends number> = LessEqList<Range<T>, Range<P>>;  type t10 = LessEq<Zero, One>; // type t10 = true type t11 = LessEq<One, Zero>; // type t11 = false  type t12 = LessEq<One, One>; // type t12 = true

2.3 減法的實(shí)現(xiàn)

減法有兩個(gè)思路,列表長度相減求值和數(shù)字相減求值

2.3.1 列表減法

默認(rèn)大減小, 小減大只需要判斷下反著來, 然后加個(gè)符號(hào)就行了, 這里為了簡(jiǎn)單沒有實(shí)現(xiàn),可參考偽代碼如下:

// 偽代碼 const a = [1, 2, 3]; const b = [4, 5]; const c = []; while (b.length !== a.length) {   a.pop();   c.push(1); }// c.length === a.length - b.lengthconsole.log(c.length);  // 元組的減法 T - P, 同時(shí)去除一個(gè)元素, 長度到0時(shí), 剩下的就是結(jié)果, 這里使用第三個(gè)參數(shù)來攜帶結(jié)果, 每次做一次減法, 向第三個(gè)列表里面追加 type SubList<T extends any[], P extends any[], R extends any[] = []> = {   0: Length<R>;   1: SubList<Shift<T>, P, Apped<R>>; }[Length<T> extends Length<P> ? 0 : 1]; type t13 = SubList<Range<10>, Range<5>>; // type t13 = 5

2.3.2 數(shù)字減法

思想:將數(shù)字轉(zhuǎn)成元組后再比較

// 集合大小不能為負(fù)數(shù), 默認(rèn)大減小 // 數(shù)字的減法 type Sub<T extends number, P extends number> = {   0: Sub<P, T>;   1: SubList<Range<T>, Range<P>>; }[LessEq<T, P> extends true ? 0 : 1];  type t14 = Sub<One, Zero>; //   type t14 = 1 type t15 = Sub<Ten, Five>; // type t15 = 5

我們有了這些工具后, 就可以將一開始用JavaScript實(shí)現(xiàn)的斐波那契數(shù)列的實(shí)現(xiàn)代碼,翻譯為TypeScript類型編碼

三、Fib: JS函數(shù) --> TS類型

在JavaScript中,我們使用函數(shù)

const fib = (n: number): number => n <= 1 ? n : fib(n - 1) + fib(n - 2);

在TypeScript中,我們使用類型, 其實(shí)只是換了一種寫法, 用類型函數(shù)描述運(yùn)算, 萬變不離其宗~

由于TypeScript遞歸限制, 并不能求解非常大的項(xiàng), 不過好玩就完事了~

export type Fib<T extends number> = {   0: T;   1: Add<Fib<Sub<T, One>>, Fib<Sub<T, Two>>>; }[LessEq<T, One> extends true ? 0 : 1];  type r0 = Fib<Zero>; // type r10= 0 type r1 = Fib<One>; // type r1 = 1  type r2 = Fib<Two>; // type r2 = 1  type r3 = Fib<3>; // type r3 = 2  type r4 = Fib<4>; // type r4 = 3  type r5 = Fib<5>; //type r5 = 5  type r6 = Fib<6>; //   type r6 = 8

關(guān)于TypeScript中怎么實(shí)現(xiàn)一個(gè)斐波那契數(shù)列就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺得文章不錯(cuò),可以把它分享出去讓更多的人看到。

標(biāo)題名稱:TypeScript中怎么實(shí)現(xiàn)一個(gè)斐波那契數(shù)列
標(biāo)題鏈接:http://bm7419.com/article6/jdiiig.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供定制網(wǎng)站ChatGPT、外貿(mào)網(wǎng)站建設(shè)、企業(yè)建站網(wǎng)站排名、域名注冊(cè)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

綿陽服務(wù)器托管