為何STL中的容器和演算法都是用的左閉右開區間?

時間 2021-05-30 15:19:15

1樓:

除了迭代器用起來方便外,另乙個原因是這樣的情況下將區間的兩個端點相減就可以得到區間內元素的數目,或者說用區間的左端點加上區間長度就可以直接得到區間的右端點,十分方便。

2樓:

因為對迭代器的begin,end,++和==操作,並不是一種高度抽象的做法。抽象程度不夠,自然不能完美相容所有的用例,而硬要往抽象程度不高的公式上套,只能修改用例本身,進而出現半開半閉區間這種奇怪的東西。

舉例來說,unordered_map的end在哪?根據演算法不同,它並沒有乙個確切的end,而end在這裡也沒有確切的意義。再來乙個例子,如果非要按照begin end框架理解,從999(含)以內所有正奇數,++不是加一而是加二,這個是抽象,沒問題。

但是begin不是0,end不是999也不是1000,就奇怪了。

真正高層次的迭代器抽象,應該是for item in set,具體實現可以是hasnext和getnext。這樣含義上會更加統一,介面更少,題主的問題也就不存在了。

3樓:AlanShawn

如果說是開區間的話那就不太直觀,半開半閉區間就是現在所使用的。而閉區間乙個很不好的性質是,當只有乙個元素的時候就不能用區間表達了,只能用乙個點來表示。因此還是半開半閉區間比較合理。

4樓:原子筆

這樣迭代器只需要支援++和!=(或者《或者==)操作就可以方便的進行區間遍歷了。

其它區間設定的話,要麼得支援<=操作,要麼得在迴圈體內,++操作之前進行!=判定。

換而言之,左閉右開區間的遍歷,只需要迭代器支援最少的操作符。

5樓:馮東

「左閉右開」的優勢的表現形式是「很多演算法寫起來更舒服」。其內在原因是,在乙個離散軸上表示乙個 range 的時候,最好把 range 的開始和結束 marker 解釋為指向這個 range 在軸上的 border,而不是 begin/end item。

當你把 begin(), end() 在表示 range 的時候想象為表示 border 而不是 item 本身,很多演算法就有了 universal 的表示方法。特別是那些涉及 subrange 的場景。

但是同時乙個 iterator 又要去引用 item 本身,這個時候就出現把 iterator 對 border 的指向「移半格」的解釋,造成了「左閉右開」的表象。其實在兩種解釋語境(引用 item 和表示 range)分開考慮的時候,後者並不存在「左閉右開」的實質。

6樓:

因為左閉右開是更加自然的表示方式。考慮乙個陣列如下圖3,4,2,1,6,1每個位置的索引可以看作是左下邊的數,也就是將索引看作陣列中間的空隙的索引。如果要表達乙個區間包含2,1。

自然是使用下標2和下標4作為範圍來的更加自然,因為可以看作是從這兩個位置進行切割,中間的部分即為所要。

7樓:

補充高票答案,比如寫二分的時候,可以理解為滿足xx性質的答案在乙個左閉右開的區間。這樣的話,就有左端點滿足xx性質,右端點不滿足xx性質恆成立,那麼每當遇到滿足xx性質的中點就讓它變成新的左端點,不滿足xx性質的中點讓它變成新的右端點,這樣二分就很難寫錯。

8樓:暮無井見鈴

Why numbering should start at zero (EWD 831)

你可以參考下 Dijkstra 的見解。

C 中的size t型別和容器中的size type型別有什麼區別?

容器的size type不一定是size t,但標準保證二者都是unsigned integer型別,可以用std numeric limits max檢查範圍,如果範圍相等那可以直接用size t,否則可以取最大值更小的那個型別確保安全。這樣寫保證不會因為編譯器和標準庫實現的不同而出現問題。 王美...

STL庫里的演算法時間複雜度和空間複雜度都是最佳的嗎?

Alinshans 肯定不都是最佳的。但肯定比99 的人寫的都要好。競賽中不一定要求時間複雜度最小,但是基本上 嚴格一點的 要求達到乙個級別。比如複雜度能O nlogn 的你不要搞O n STL中的演算法肯定能確保你能達到,如果你的寫法沒有問題,但死活超時了 卡常數 我覺得題目出得有問題。另,你知道...

KNN演算法中的K用什麼方法確定?

凱家的梧桐 K值選取過小,容易使得模型變複雜,從而過擬合 K值選取過大,使得分類結果收到較遠點的影響,從而會讓分類誤差增大 綜上所述,K值不宜過大也不宜過小,選取最優的K值可以通過K折交叉驗證等方法實現,設定分類準確率的閾值,達到閾值的K值往往分類效果還不錯。 牛博 k本身沒有特定的取值,但K值對結...