當我們想要寫一個循環體,期望執行10次的時候,我們會使用以下方式:
for (int i=0; i<10; i++){
}
可以看到,爲了保證循環10次,我們定義了一個整數變量從0開始,然後循環10次,結束條件是i < 10。
其實這個本質就是使用了0 ≤ i < 10
這種表達形式。
之所以很多人都這麼寫,有一個最主要的原因就是剛開始學編程的時候,老師都是這麼教的…
關於這個問題,其實還有一位偉大的數學家曾經討論過他的合理性。
這個人就是Dijkstra,他也是離散數學中應用廣泛的最短路徑算法的提出者,並且還提出了銀行家算法。
他在1982年發表了一篇說明《Why numbering should start at zero》,這裏面有部分內容闡述了這個觀點。
他首先提出一個問題,讓我們通過一個條件表達式表示 2,3,4,5,6,7,8,9,10,11,12 這11個數字,其實一般有以下四種寫法:
a) 2 ≤ i < 13
b) 1 < i ≤ 12
c) 2 ≤ i ≤ 12
d) 1 < i < 13
這幾種也是我們在寫for循環的時候可能會用到的一些表示式,那着四種寫法有沒有好壞之分呢?
答案是有的。
我們其實可以觀察到,a) 和 b)有個優點,上下邊界的相減得到的差,正好等於子序列的長度,即13-2 = 12-1 = 11
; 這樣的寫法可以讓我們快速知道這個表示表達式中一共包含多少個自然數。
當然,這並不是正菜,只是開胃而已…
接下來,Dijkstra分別從表達式的上下界討論了到底使用≤
還是<
更合理。
首先,他論證了一下表達式的下界使用哪種形式合理。
他認爲,當我們想要表達自然數2-12的時候,如果使用1 < i
作爲這個序列的下界的話,這個下界的起始值進入了非自然數的區域。而使用2 ≤ i
,那麼就可以嚴格的保證這個下界就是一個自然數2 。所以,他認爲下界使用≤
更加合理。
符合這種形式的就是a) 和 c)兩種。
那麼a) 和 c)還有一個區別,就是上界一個用了≤
一個用了<
,那該使用哪種方式更加合適呢?
Dijkstra提出,如果想要表達一個空序列,使用a) 形式可以很容易的表達,如 0<= i <0
就可以表示一個空序列。
但是如果上界和下界都用<=
就無法表示了,除非用1 <= i <= 0
,但是這種形式就很不合邏輯。
所以,綜上,他認爲a) 2 ≤ i < 13
這種表達方式更加合理一些。
也就是說,使用左閉右開的形式定義表達式合理也更加優雅!
參考資料:
http://www.cs.utexas.edu/users/EWD/transcriptions/EWD08xx/EWD831.html
關於作者:漫話編程,是一個通過漫畫+音頻的形式講解枯燥的編程知識的公衆號。致力於讓編程變得更有樂趣。
有道無術,術可成;有術無道,止於術
歡迎大家關注Java之道公衆號
好文章,我在看❤️