久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

一起學習PHP中的DS數(shù)據(jù)結構擴展(一)

 硬核項目經理 2021-12-02

一起學習PHP中的DS數(shù)據(jù)結構擴展(一)

在之前學習 SPL 相關的文章中,,我們已經學習過 SPL 中的一些數(shù)據(jù)結構相關的數(shù)據(jù)結構對象,非常強大也非常好用,,最主要的是 SPL 已經集成在 PHP 源碼中不需要我們再單獨地安裝別的什么擴展,。但是,,今天我們要學習的這個 DataStruct 擴展庫的內容則更加地豐富,不過相對應的,,這套擴展是需要我們自己手動再進行安裝的,。如果大家對于數(shù)據(jù)結構的需求不高的話,使用 SPL 中的相關對象就夠用了,,但是如果需要更加豐富的數(shù)據(jù)結構類型的話,,這套 DS 擴展是更好的選擇。

DS 擴展的安裝和其它普通的擴展安裝沒有什么區(qū)別,,也不需要額外的操作系統(tǒng)上的組件支持,,直接安裝即可。

首先還是從棧這個最基本的數(shù)據(jù)結構說起,。DS 中的棧結構非常地簡單好用,。

$stack = new \Ds\Stack();
var_dump($stack);
// object(Ds\Stack)#1 (0) {
// }

$stack = new \Ds\Stack([123]);
var_dump($stack);
// object(Ds\Stack)#2 (3) {
//     [0]=>
//     int(3)
//     [1]=>
//     int(2)
//     [2]=>
//     int(1)
//   }

兩種方式實例化棧對象,其實就是參數(shù)的不同,,如果我們直接給構造函數(shù)傳遞一個數(shù)組的話,,那么這個數(shù)組就會做為棧內部的元素供我們使用。

$stack->push(4);
$stack->push(5);
var_dump($stack);
// object(Ds\Stack)#2 (5) {
//     [0]=>
//     int(5)
//     [1]=>
//     int(4)
//     [2]=>
//     int(3)
//     [3]=>
//     int(2)
//     [4]=>
//     int(1)
//   }

var_dump($stack->pop()); // int(5)
var_dump($stack->pop()); // int(4)
var_dump($stack);
// object(Ds\Stack)#2 (3) {
//     [0]=>
//     int(3)
//     [1]=>
//     int(2)
//     [2]=>
//     int(1)
//   }

push() 就是將數(shù)據(jù)壓棧,,pop() 則是將棧頂?shù)脑貜棾?。關于棧的最主要的操作其實就是這兩個方法函數(shù)了,。

var_dump($stack->peek()); // int(3)
// object(Ds\Stack)#2 (3) {
//     [0]=>
//     int(3)
//     [1]=>
//     int(2)
//     [2]=>
//     int(1)
//   }

peek() 這個函數(shù)是直接獲取棧頂?shù)臄?shù)據(jù),但是需要注意的是,,它不會彈出棧頂?shù)脑?。也就是說,這個 peek() 方法只會取得數(shù)據(jù)的內容,,不會改變棧內部的數(shù)據(jù),。

var_dump($stack->count()); // int(3)
var_dump($stack->isEmpty()); // bool(false)
var_dump($stack->toArray());
// array(3) {
//     [0]=>
//     int(3)
//     [1]=>
//     int(2)
//     [2]=>
//     int(1)
//   }

$stack->clear();
var_dump($stack);
// object(Ds\Stack)#2 (0) {
// }

count() 返回棧內部元素的數(shù)量,isEmpty() 用于判斷棧是否為空,,toArray() 直接以數(shù)組的格式返回棧內部的數(shù)據(jù),clear() 方法用于清空棧,。這些方法函數(shù)都非常地簡單,,所以就不多做解釋了。最后我們來看看棧對象的賦值拷貝操作,。

$a = $stack;
$a->push(4);
var_dump($stack);
// object(Ds\Stack)#2 (1) {
//     [0]=>
//     int(4)
//   }

$b = $stack->copy();
$b->push(5);

var_dump($stack);
// object(Ds\Stack)#2 (1) {
//     [0]=>
//     int(4)
//   }

var_dump($b);
// object(Ds\Stack)#1 (2) {
//     [0]=>
//     int(5)
//     [1]=>
//     int(4)
//   }

\$stack 對象是實例化之后的對象,,在普通的賦值操作中是引用傳遞的。上文中我們清空了 $stack ,,然后在這里我們讓 $a 等于這個 $stack ,,然后操作 $a 相應地 $stack 里面的內容也發(fā)生了變化。對于引用傳遞這個問題,,我們一般會使用 __clone() 魔術方法來解決,, Stack 類直接就為我們提供了一個 copy() 方法,直接可以獲得一個棧對象的拷貝,,也可以說是一個新的棧對象,。就像上面代碼中的 $b 一樣,當使用 copy() 方法賦值給 $b 之后,,它就成為了一個新的棧對象,,任何 $b 的操作和 $stack 對象就沒有什么關系了。我們可以看到 對象id 也完全不同了,。

隊列

對于隊列來說,,整體上的功能方法和棧的內容差不多,它們實現(xiàn)的方法基本上是一模一樣的,。具體在實現(xiàn)層面上的不同就體現(xiàn)在彈棧和出隊的不同,,也就是 push() 方法在實現(xiàn)中有差別。

$queue = new \Ds\Queue();
var_dump($queue);
// object(Ds\Queue)#3 (0) {
// }

$queue = new \Ds\Queue([123]);
var_dump($queue);
// object(Ds\Queue)#4 (3) {
//     [0]=>
//     int(1)
//     [1]=>
//     int(2)
//     [2]=>
//     int(3)
//   }

$queue->push(4);
$queue->push(5);
var_dump($queue);
// object(Ds\Queue)#4 (5) {
//     [0]=>
//     int(1)
//     [1]=>
//     int(2)
//     [2]=>
//     int(3)
//     [3]=>
//     int(4)
//     [4]=>
//     int(5)
//   }

var_dump($queue->pop()); // int(1)
var_dump($queue->pop()); // int(2)
var_dump($queue);
// object(Ds\Queue)#4 (3) {
//     [0]=>
//     int(3)
//     [1]=>
//     int(4)
//     [2]=>
//     int(5)
//   }

可以看出,,在隊列中,,我們 push() 進來的數(shù)據(jù)的順序是 1,2,3,4,5 這樣正序的,也就是將數(shù)據(jù)放到內部這個數(shù)組的底部,,出隊 pop() 直接拿最頂上的數(shù)據(jù)也就實現(xiàn)了先進先出的效果,。對比上面棧的數(shù)據(jù)內容,,就可以發(fā)現(xiàn)棧的數(shù)據(jù)在 push() 的時候就是反過來的,5,、4,、3、2,、1 這樣的,,然后在 pop() 的時候其實也是從頂部拿出數(shù)據(jù),只不過棧是將數(shù)據(jù) push() 到內部數(shù)組的頂部的,,然后從頂部直接拿出數(shù)據(jù)實現(xiàn)了 后進先出 的效果,。

優(yōu)先隊列

最重要的兩個數(shù)據(jù)結構說完了,我們再來看一個隊列的擴展結構,,也就是優(yōu)先隊列的實現(xiàn),。其實這個隊列就是在 push() 數(shù)據(jù)的時候多了一個參數(shù),也就是數(shù)據(jù)的優(yōu)先級,,越大的越靠前,,其它的方法和普通隊列以及棧的方法都沒什么太大的區(qū)別。

$pQueue = new \Ds\PriorityQueue();

$pQueue->push(1100);
$pQueue->push(2101);
$pQueue->push(399);

var_dump($pQueue);
// object(Ds\PriorityQueue)#3 (3) {
//     [0]=>
//     int(2)
//     [1]=>
//     int(1)
//     [2]=>
//     int(3)
//   }

var_dump($pQueue->pop()); // int(2)
var_dump($pQueue->pop()); // int(1)
var_dump($pQueue->pop()); // int(3)

Map

最后我們來學習一個 Map 數(shù)據(jù)結構,,其實也就是 HaspMap 這種 K/V 的鍵值對形式的數(shù)據(jù)結構,。只能說 PHP 中的數(shù)組實在是太強大了,完全兼容了這種數(shù)據(jù)結構,,所以使得單獨的 Map 結構并沒有什么實際的意義,。

$map = new \Ds\Map(['a'=>125=>3]);
var_dump($map);
// object(Ds\Map)#5 (3) {
//     [0]=>
//     object(Ds\Pair)#6 (2) {
//       ["key"]=>
//       string(1) "a"
//       ["value"]=>
//       int(1)
//     }
//     [1]=>
//     object(Ds\Pair)#7 (2) {
//       ["key"]=>
//       int(0)
//       ["value"]=>
//       int(2)
//     }
//     [2]=>
//     object(Ds\Pair)#8 (2) {
//       ["key"]=>
//       int(5)
//       ["value"]=>
//       int(3)
//     }
//   }


var_dump($map->get(0)); // int(2)
var_dump($map->get(5)); // int(3)

$map->put('b''4');
$map->put('c', [123]);
$map->put('d'new class{public $t = 't';});

var_dump($map);
// object(Ds\Map)#5 (6) {
//     [0]=>
//     object(Ds\Pair)#7 (2) {
//       ["key"]=>
//       string(1) "a"
//       ["value"]=>
//       int(1)
//     }
//     [1]=>
//     object(Ds\Pair)#6 (2) {
//       ["key"]=>
//       int(0)
//       ["value"]=>
//       int(2)
//     }
//     [2]=>
//     object(Ds\Pair)#9 (2) {
//       ["key"]=>
//       int(5)
//       ["value"]=>
//       int(3)
//     }
//     [3]=>
//     object(Ds\Pair)#10 (2) {
//       ["key"]=>
//       string(1) "b"
//       ["value"]=>
//       string(1) "4"
//     }
//     [4]=>
//     object(Ds\Pair)#11 (2) {
//       ["key"]=>
//       string(1) "c"
//       ["value"]=>
//       array(3) {
//         [0]=>
//         int(1)
//         [1]=>
//         int(2)
//         [2]=>
//         int(3)
//       }
//     }
//     [5]=>
//     object(Ds\Pair)#12 (2) {
//       ["key"]=>
//       string(1) "d"
//       ["value"]=>
//       object(class@anonymous)#8 (1) {
//         ["t"]=>
//         string(1) "t"
//       }
//     }
//   }

$map->remove('d');
$map->remove('c');

var_dump($map);
// object(Ds\Map)#5 (4) {
//     [0]=>
//     object(Ds\Pair)#8 (2) {
//       ["key"]=>
//       string(1) "a"
//       ["value"]=>
//       int(1)
//     }
//     [1]=>
//     object(Ds\Pair)#12 (2) {
//       ["key"]=>
//       int(0)
//       ["value"]=>
//       int(2)
//     }
//     [2]=>
//     object(Ds\Pair)#11 (2) {
//       ["key"]=>
//       int(5)
//       ["value"]=>
//       int(3)
//     }
//     [3]=>
//     object(Ds\Pair)#10 (2) {
//       ["key"]=>
//       string(1) "b"
//       ["value"]=>
//       string(1) "4"
//     }
//   }

在 Java 之類的語言中,數(shù)組 和 HashMap 是兩種東西,,或者說是兩種集合對象,,比如 List<Obj> 就是一個數(shù)據(jù)集合,而 Map<Obj> 就是一個 HashMap 集合,。相對應的,,在 Java 的這種泛型集合中,我們需要添加和獲取數(shù)據(jù)就要像這個 DS 擴展中的 Map 一樣使用 get(),、put(),、remove() 類似的方法來實現(xiàn)。

Map 這個數(shù)據(jù)結構與上面的棧,、隊列之類的數(shù)據(jù)結構中實現(xiàn)的方法差別還是挺大的,。

var_dump($map->first());
// object(Ds\Pair)#8 (2) {
//     ["key"]=>
//     string(1) "a"
//     ["value"]=>
//     int(1)
//   }

var_dump($map->last());
// object(Ds\Pair)#8 (2) {
//     ["key"]=>
//     int(5)
//     ["value"]=>
//     int(3)
//   }

var_dump($map->sum()); // int(10)

var_dump($map->hasKey('b')); // bool(true)
var_dump($map->haskey('bb')); // bool(false)

var_dump($map->hasValue('4')); // bool(true)
var_dump($map->hasValue(4)); // bool(false)

它有 first() 和 last() 方法直接獲取第一個和最后一個數(shù)據(jù)元素。也有 sum() 方法獲得數(shù)據(jù)元素的個數(shù),,同時可以通過 hasKey() 和 hasValue() 來判斷指定的鍵或者值是存在,。是不是有點像 key_exists() 和 in_array() 這兩個方法。當然,,相對應的我們也可以直接獲取這些 Key 和 Value 的內容,。

var_dump($map->keys());
// object(Ds\Set)#10 (4) {
//     [0]=>
//     string(1) "a"
//     [1]=>
//     int(0)
//     [2]=>
//     int(5)
//     [3]=>
//     string(1) "b"
//   }

var_dump($map->values());
// object(Ds\Vector)#10 (4) {
//     [0]=>
//     int(1)
//     [1]=>
//     int(2)
//     [2]=>
//     int(3)
//     [3]=>
//     string(1) "4"
//   }

我們可以看到,,keys() 返回的內容是 Set 類型的對象,而 values() 返回的內容是 Vector 類型的對象,,這兩種也是 DS 中的數(shù)據(jù)結構類型,,我們將在下篇文章中再學習。除了 Key 和 Values 之外,,它還可以直接返回一個 Vector 類型的對象集合結構,,使用 paris() 方法。

var_dump($map->pairs());
// object(Ds\Vector)#9 (4) {
//     [0]=>
//     object(Ds\Pair)#10 (2) {
//       ["key"]=>
//       string(1) "a"
//       ["value"]=>
//       int(1)
//     }
//     [1]=>
//     object(Ds\Pair)#11 (2) {
//       ["key"]=>
//       int(0)
//       ["value"]=>
//       int(2)
//     }
//     [2]=>
//     object(Ds\Pair)#12 (2) {
//       ["key"]=>
//       int(5)
//       ["value"]=>
//       int(3)
//     }
//     [3]=>
//     object(Ds\Pair)#8 (2) {
//       ["key"]=>
//       string(1) "b"
//       ["value"]=>
//       string(1) "4"
//     }
//   }

在 Map 對象中,,還提供了一些為數(shù)據(jù)排序,、合并兩個 Map 以及截取一部分數(shù)據(jù)的方法,直接貼出代碼吧,。

$map->ksort();
var_dump($map);
// object(Ds\Map)#5 (4) {
//     [0]=>
//     object(Ds\Pair)#9 (2) {
//       ["key"]=>
//       string(1) "a"
//       ["value"]=>
//       int(1)
//     }
//     [1]=>
//     object(Ds\Pair)#8 (2) {
//       ["key"]=>
//       int(0)
//       ["value"]=>
//       int(2)
//     }
//     [2]=>
//     object(Ds\Pair)#12 (2) {
//       ["key"]=>
//       string(1) "b"
//       ["value"]=>
//       string(1) "4"
//     }
//     [3]=>
//     object(Ds\Pair)#11 (2) {
//       ["key"]=>
//       int(5)
//       ["value"]=>
//       int(3)
//     }
//   }

$map->reverse();
var_dump($map);
// object(Ds\Map)#5 (4) {
//     [0]=>
//     object(Ds\Pair)#11 (2) {
//       ["key"]=>
//       int(5)
//       ["value"]=>
//       int(3)
//     }
//     [1]=>
//     object(Ds\Pair)#12 (2) {
//       ["key"]=>
//       string(1) "b"
//       ["value"]=>
//       string(1) "4"
//     }
//     [2]=>
//     object(Ds\Pair)#8 (2) {
//       ["key"]=>
//       int(0)
//       ["value"]=>
//       int(2)
//     }
//     [3]=>
//     object(Ds\Pair)#9 (2) {
//       ["key"]=>
//       string(1) "a"
//       ["value"]=>
//       int(1)
//     }
//   }

$newMap = new \Ds\Map();
$newMap->put('a''a');
$newMap->put('b''b');
$newMap->put('e''e');

var_dump($map->diff($newMap));
// object(Ds\Map)#8 (2) {
//     [0]=>
//     object(Ds\Pair)#12 (2) {
//       ["key"]=>
//       int(5)
//       ["value"]=>
//       int(3)
//     }
//     [1]=>
//     object(Ds\Pair)#11 (2) {
//       ["key"]=>
//       int(0)
//       ["value"]=>
//       int(2)
//     }
//   }

var_dump($map->union($newMap));
// object(Ds\Map)#8 (5) {
//     [0]=>
//     object(Ds\Pair)#11 (2) {
//       ["key"]=>
//       int(5)
//       ["value"]=>
//       int(3)
//     }
//     [1]=>
//     object(Ds\Pair)#12 (2) {
//       ["key"]=>
//       string(1) "b"
//       ["value"]=>
//       string(1) "b"
//     }
//     [2]=>
//     object(Ds\Pair)#10 (2) {
//       ["key"]=>
//       int(0)
//       ["value"]=>
//       int(2)
//     }
//     [3]=>
//     object(Ds\Pair)#6 (2) {
//       ["key"]=>
//       string(1) "a"
//       ["value"]=>
//       string(1) "a"
//     }
//     [4]=>
//     object(Ds\Pair)#7 (2) {
//       ["key"]=>
//       string(1) "e"
//       ["value"]=>
//       string(1) "e"
//     }
//   }

var_dump($map->xor($newMap));
// object(Ds\Map)#8 (3) {
//     [0]=>
//     object(Ds\Pair)#7 (2) {
//       ["key"]=>
//       int(5)
//       ["value"]=>
//       int(3)
//     }
//     [1]=>
//     object(Ds\Pair)#6 (2) {
//       ["key"]=>
//       int(0)
//       ["value"]=>
//       int(2)
//     }
//     [2]=>
//     object(Ds\Pair)#10 (2) {
//       ["key"]=>
//       string(1) "e"
//       ["value"]=>
//       string(1) "e"
//     }
//   }

var_dump($map->intersect($newMap));
// object(Ds\Map)#8 (2) {
//     [0]=>
//     object(Ds\Pair)#10 (2) {
//       ["key"]=>
//       string(1) "b"
//       ["value"]=>
//       string(1) "4"
//     }
//     [1]=>
//     object(Ds\Pair)#6 (2) {
//       ["key"]=>
//       string(1) "a"
//       ["value"]=>
//       int(1)
//     }
//   }

$map->putAll($newMap);
var_dump($map);
// object(Ds\Map)#5 (5) {
//     [0]=>
//     object(Ds\Pair)#8 (2) {
//       ["key"]=>
//       int(5)
//       ["value"]=>
//       int(3)
//     }
//     [1]=>
//     object(Ds\Pair)#6 (2) {
//       ["key"]=>
//       string(1) "b"
//       ["value"]=>
//       string(1) "b"
//     }
//     [2]=>
//     object(Ds\Pair)#10 (2) {
//       ["key"]=>
//       int(0)
//       ["value"]=>
//       int(2)
//     }
//     [3]=>
//     object(Ds\Pair)#7 (2) {
//       ["key"]=>
//       string(1) "a"
//       ["value"]=>
//       string(1) "a"
//     }
//     [4]=>
//     object(Ds\Pair)#12 (2) {
//       ["key"]=>
//       string(1) "e"
//       ["value"]=>
//       string(1) "e"
//     }
//   }

var_dump($map->slice(12));
// object(Ds\Map)#12 (2) {
//     [0]=>
//     object(Ds\Pair)#7 (2) {
//       ["key"]=>
//       string(1) "b"
//       ["value"]=>
//       string(1) "b"
//     }
//     [1]=>
//     object(Ds\Pair)#10 (2) {
//       ["key"]=>
//       int(0)
//       ["value"]=>
//       int(2)
//     }
//   }

var_dump($map->skip(2));
// object(Ds\Pair)#12 (2) {
//     ["key"]=>
//     int(0)
//     ["value"]=>
//     int(2)
//   }

代碼內容很多,,展示的注釋內容也就是我們執(zhí)行的結果??梢钥闯觯琈ap 這個數(shù)據(jù)結構提供的方法功能真的是非常豐富的,。而且我們這里還沒有完全展示出來,,它還有一些類似的方法,大家有興趣的可以自己多多地去探索,。不過就像上面說過的,,PHP 中的數(shù)組實在是太方便了,所以這個 Map 的應用場景有限,,或者某些特殊的必須需要對象來表示數(shù)組結構的場景會有用,。

總結

是不是有點意思呀,就像在開頭時我們說過的,,了解學習可以,,但如果真實業(yè)務中只是需要一些簡單的棧或隊列的實現(xiàn)的話,,直接使用 SPL 擴展庫中的數(shù)據(jù)結構就可以了,。當然,DS 中的內容還沒有講完,,Vector 和 Set 相信學習過 Java 的同學一定不陌生,,下篇文章我們將繼續(xù)學習 DS 中剩余的數(shù)據(jù)結構。

測試代碼:

https://github.com/zhangyue0503/dev-blog/blob/master/php/2021/02/source/2.一起學習PHP中的DS數(shù)據(jù)結構擴展(一).php

參考文檔:

https://www./manual/zh/book.ds.php

    轉藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多