【大數算法】( 十進制整數四則運算) 十進制運算與二進制比較與思考

  這兩天心血來潮, 想熟悉下Eclipse。 偶是寫Python的, 一般都在Ubuntu上用VIM做編輯器, PDB做調試工具, 自帶的python2.7解釋器, git做版本控制。 用着挺爽, 也就沒有搞啥IDE, 但是最近發現要做大項目或工程的話, IDE啥的還是很有必要的。

  幾乎把所有支持Py的IDE都嘗試過了, eric用着特別扭(還是比較習慣VIM的便捷操作),  要Python的自動補全居然還要用戶自己配置api文件。。 居然還敢自稱專業Python IDE..太讓人失望了。 wing IDE試用了下,挺不錯的。。 但是要收費。。 想着在Linux環境下還要用破解軟件就覺得特憋屈。 vim -> configure -> make -> make install已成習慣,自然不堪其辱,果斷放棄了。。 IDLE頂多算個編輯器。 還沒VIM功能強大, 完全感覺不到可以拿來做大項目。。 

  最後還是選擇了Eclipse + Pydev + Vrapper Eclipse強大的工程管理和自動補全,doc功能 + VIM的全鍵盤式操作 = 犀利。。

  一直堅持寫些簡單算法練手, 邏輯, coding 雙豐收, 咧呵呵。

正式開始

加法:

   先寫了測試代碼:

      

#!/usr/bin/env python
from hugeoperation import HugeOperation
import unittest

class TestHugeOperation(unittest.TestCase):

	def setUp(self):
		self.testobj = HugeOperation()
		self.testdata = {}
		self.testdata['add'] = [
				   ['2000', '1000', '1000'],
				   ['0','0','0'],
				   ['1', '0', '1'],
				   ['0', '1', '-1'],
			       ['337618', '3495', '334123'],
				   ['-219', '-98', '-121'],
				   ['3', '-32', '35'],
                   ['-2085924839766513752338888384931203236916703635113918720651407820138886450957659038931612598272',\
				   '-1042962419883256876169444192465601618458351817556959360325703910069443225478829519465806299136',\
				   '-1042962419883256876169444192465601618458351817556959360325703910069443225478829519465806299136'],
				   ['1042962419883256876169444192465601618458351817556959360325703910069443225478829519465806299136',\
				   '1042962419883256876169444192465601618458351817556959360325703910069443225478828393565899456512',\
				   '1125899906842624' ]
								]
		
		
	def test_add(self):
		for i in self.testdata['add']:
			self.assertEqual(i[0], self.testobj.huge_add(i[1], i[2]))
			print i,
			print '		Passed!\n'


if __name__=='__main__':
	unittest.main()

    就經驗來說,四則裏面最基本的應該是加法,所以就先設計好加法的測試用列, 給了9組測試數據, 肯定沒考慮全面, 比如邊界值測試,異常輸入什麼的都沒設計。。 畢竟只是練手的東西,要求不要太嚴格了,呵呵


然後開始設計算法:

   計算機指令的運算是基於位的二進制運算, 大學老師教過整型有表示範圍, 就算用長整型也是有限的,具體限制與不同語言和不同系統平臺有關。不借助庫的話是無法實現超級大數運算的。 如計算2^258 + 2^512 用一般的整型運算肯定是無法實現的。

   我使用字符串來存儲兩個數,然後用一個字符串來存儲結果。

   加法比較簡單, 從低位起逐位相加,除10取餘與進位寄存器相加便是該位的值, 進位只有0和1兩種狀態。

   實現代碼如下:


#add fun
def _add_operate(self, anum, bnum):
		carry = 0
		rdigit = 0
		rnum = []
		while anum or bnum:
			adigit = 0
			bdigit = 0
			if anum:
				adigit=anum.pop()
			if bnum:
				bdigit=bnum.pop()	
			rdigit = adigit + bdigit + carry
			carry = rdigit / 10
			rdigit = rdigit % 10	
			rnum.append(str(rdigit))
		if carry:
			rnum.append('1')
		rnum.reverse()
		result = rnum
		return result


  該函數輸入是兩個整形列表,分別順序存儲了兩個加數。 輸出是一個順序存儲了計算結果的字符型列表 (如果出於對輸入兼容性的角度考慮, 可以在函數最開始對列表元素做強制轉型處理, 這裏爲了簡潔我沒做。)

有兩個地方需要注意: 1. 當算到最後一位仍有進位時, 需要把進位添加到結果的最高位, 當然,也只可能是1. 

                                  2. 進位寄存器使用後要歸零, 這個比較容易出bug。

    但是一般來說讀入的數據會是兩個字符串, 如我們測試用列設計的那樣, 所以需要一個對輸入初始化的函數, 將字符串轉換爲列表:

def _huge_init(self, a):
		'''_huge_init(string)
			return list[list[sign],list[num]]
		'''
		num = []
		sign = 0
		if a[0] == '-':
			sign = 1
			for i in a[1:]:
				num.append(int(i))
		else:
			for i in a:
				num.append(int(i))
		return list([sign,num])

該函數是將輸入的字符串列表化, 並且要考慮首位是否有負號。 該函數輸入是一個字符串, 輸出是一個二維列表, 其中第一維存儲了符號, 第二維存儲了無符號的整型列表

有了這兩個函數依舊不夠。。 這兩個都是功能函數, 我們還差一個接口函數,這個接口函數會調用這兩個功能函數完成運算並負責輸出。 首先確定該函數的輸入爲兩個字符串, 輸出爲結果字符串。 然後再對其中代碼進行設計如下:

def huge_add(self, a, b):
		'''huge_add(string,string)
			return string
		'''
		asign = self._huge_init(a)[0]
		anum = self._huge_init(a)[1]
		bsign = self._huge_init(b)[0]
		bnum = self._huge_init(b)[1]
		#switcher: 0 => +&+ 1=> -&+ 2=>+&- 3=>-&-
		switcher = asign | bsign << 1
		if switcher == 0: 
			result = ''.join(self._add_operate(anum, bnum))
		if switcher == 1:
			result = ''.join(self._sub_operate(bnum, anum))
		if switcher == 2:
			result = ''.join(self._sub_operate(anum, bnum))
		if switcher == 3:
			result = '-' + ''.join(self._add_operate(anum, bnum))
		return result

     該函數先是調用init函數對輸入列表化,然後根據符號位控制輸出。 其中調用到暫時還沒提到的_sub_operate, 因爲相異符號的加法就是一個減法運算, 同樣,減法運算也可以轉化爲相異符號的加法運算。 所以後面大家會發現, 減法的接口函數其實是依賴於加法接口函數的囧。。 


     但是必須強調, 減法和加法的算法是不同的。 而計算機的二進制算法是用補碼來表示被減數, 然後再做加法。 看似只用了一個算法就實現了加和減,但是求補也是一個算法嘛。。只是求補的算法遠比我的減法算法簡單效率高,呵呵

     原本我也是想等到寫減法接口的時候再實現減法函數的,但是寫了才知道這個先後順序。。 要實現帶符號的加法運算就必須先把減法函數寫了T_T

   下面是我的減法運算函數(不是減法接口函數):


#subtraction fun
	def _sub_operate(self, anum, bnum):
		carry = 0
		rdigit = 0
		rsign = 0
		rnum = []
		if len(bnum) > len(anum) or len(anum) == len(bnum) and \
		 anum < bnum:
			tmp = anum
			anum = bnum
			bnum = tmp
			rsign = 1
		while anum:
			adigit = 0
			bdigit = 0
			if anum:
				adigit = anum.pop()
			if bnum:
				bdigit = bnum.pop()
			rdigit = adigit - bdigit - carry
			if rdigit < 0:
				rdigit = rdigit + 10
				carry = 1	
			else:
				carry = 0
			rnum.append(str(rdigit))
		if rnum[-1] == '0' and len(rnum)-1:
			rnum = rnum[0:-1]
		if rsign:
			rnum.append('-')
		rnum.reverse()
		result = rnum
		return result



減法先對減數和被減數做了下大小比較, 把大數換到被減數位置去,這樣既可以減少逐位相減次數(減的次數是由減數位數決定的,所以減數越短減的次數越少)又可以將可能帶符號的減法換爲無符號減法運算(大數減小數必然爲正)。 而根據減法法則, 交換減數被減數只需要在結果填一個負號便可。 所以當發生交換時符號標誌(rsign)置1.

然後便是小學學的逐位相減,不足借位。 借位寄存器用完記得清零就好了。。

結果要除去高位的0,因爲高位0 是沒有意義的, 但需要特別處理結果爲0的狀況。 根據符號標誌設置一下符號便搞定咯。

    接着比較了下二進制加法與我寫的十進制加法,發現兩個的計算方法是 一樣的,都是逐位累加,然後用進位寄存器來存儲進位。 看來加法確實是最簡單的啊

    減法上二進制就厲害多了。因爲是用加補碼,溢出捨棄的方式做減法, 最高位做符號位時依然適用, 少了很多符號換來換去的麻煩。

    補碼算法明顯比這個減法算法簡單, 按位取反再加一。 最後在做一次加法。 三個運算符就搞定咯。。

測試也順利通過了:

['2000', '1000', '1000'] 		Passed!

['0', '0', '0'] 		Passed!

['1', '0', '1'] 		Passed!

['0', '1', '-1'] 		Passed!

['337618', '3495', '334123'] 		Passed!

['-219', '-98', '-121'] 		Passed!

['3', '-32', '35'] 		Passed!

['-2085924839766513752338888384931203236916703635113918720651407820138886450957659038931612598272', '-1042962419883256876169444192465601618458351817556959360325703910069443225478829519465806299136', '-1042962419883256876169444192465601618458351817556959360325703910069443225478829519465806299136'] 		Passed!

['10429624198832568761694441924656016184583518.17556959360325703910069443225478829519465806299136', '1042962419883256876169444192465601618458351817556959360325703910069443225478828393565899456512', '1125899906842624'] 		Passed!


----------------------------------------------------------------------
Ran 1 test in 0.033s

OK


減法:

先寫測試用列:

#!/usr/bin/env python
from hugeoperation import HugeOperation
import unittest

class TestHugeOperation(unittest.TestCase):

	def setUp(self):
		self.testobj = HugeOperation()
		self.testdata = {}
		self.testdata['add'] = [
				   ['2000', '1000', '1000'],
				   ['0','0','0'],
				   ['1', '0', '1'],
				   ['0', '1', '-1'],
			       ['337618', '3495', '334123'],
				   ['-219', '-98', '-121'],
				   ['3', '-32', '35'],
                   ['-2085924839766513752338888384931203236916703635113918720651407820138886450957659038931612598272',\
				   '-1042962419883256876169444192465601618458351817556959360325703910069443225478829519465806299136',\
				   '-1042962419883256876169444192465601618458351817556959360325703910069443225478829519465806299136'],
				   ['1042962419883256876169444192465601618458351817556959360325703910069443225478829519465806299136',\
				   '1042962419883256876169444192465601618458351817556959360325703910069443225478828393565899456512',\
				   '1125899906842624' ]
								]
		
		self.testdata['sub'] = [['0', '1', '1'],
					['1','1','0'],
					['-1','0','1'],
					['23','45','22'],
					['13','5','-8'],
					['26','-3','-29'],
					['-2582249878086908587416174429825207663772263512260779234709013859305998087116852093665853482099976886055025678701140377600',\
					'2239744742177804210557442280568444278121645497234649534899989100963791871180160945380877493271607115776',\
					'2582249878086908589655919172003011874329705792829223512830659356540647622016841194629645353280137831435903171972747493376']
								]
		

		
	def test_add(self):
		for i in self.testdata['add']:
			self.assertEqual(i[0], self.testobj.huge_add(i[1], i[2]))
			print i,
			print '		Passed!\n'

	def test_sub(self):
		for i in self.testdata['sub']:
			self.assertEqual(i[0], self.testobj.huge_sub(i[1], i[2]))
			print i,
			print '		Passed!\n'
	

if __name__=='__main__':
	unittest.main()


   加法函數,減法函數,初始化函數都有了,減法接口實現還難麼? 不多說了,大家請看:

#subtraction interface
	def huge_sub(self, a, b):
		if b[0] == '-':
			b = b[1:]
		else:
			b = '-' + b
		result = self.huge_add(a,b)
		return result

對。。就是這麼Easy。。

  測試通過:

['2000', '1000', '1000'] 		Passed!

['0', '0', '0'] 		Passed!

['1', '0', '1'] 		Passed!

['0', '1', '-1'] 		Passed!

['337618', '3495', '334123'] 		Passed!

['-219', '-98', '-121'] 		Passed!

['3', '-32', '35'] 		Passed!

['-2085924839766513752338888384931203236916703635113918720651407820138886450957659038931612598272', '-1042962419883256876169444192465601618458351817556959360325703910069443225478829519465806299136', '-1042962419883256876169444192465601618458351817556959360325703910069443225478829519465806299136'] 		Passed!

['1042962419883256876169444192465601618458351817556959360325703910069443225478829519465806299136', '1042962419883256876169444192465601618458351817556959360325703910069443225478828393565899456512', '1125899906842624'] 		Passed!

['.0', '1', '1'] 		Passed!

['1', '1', '0'] 		Passed!

['-1', '0', '1'] 		Passed!

['23', '45', '22'] 		Passed!

['13', '5', '-8'] 		Passed!

['26', '-3', '-29'] 		Passed!

['-258224987808690858741617442982520766377226351226077923470901385930.5998087116852093665853482099976886055025678701140377600', '2239744742177804210557442280568444278121645497234649534899989100963791871180160945380877493271607115776', '2582249878086908589655919172003011874329705792829223512830659356540647622016841194629645353280137831435903171972747493376'] 		Passed!


----------------------------------------------------------------------
Ran 2 tests in 0.042s

OK

乘法:
  
寫算法之前先添加測試用列:
#!/usr/bin/env python
from hugeoperation import HugeOperation
import unittest

class TestHugeOperation(unittest.TestCase):

	def setUp(self):
		self.testobj = HugeOperation()
		self.testdata = {}
		self.testdata['add'] = [
				   ['2000', '1000', '1000'],
				   ['0','0','0'],
				   ['1', '0', '1'],
				   ['0', '1', '-1'],
			       ['337618', '3495', '334123'],
				   ['-219', '-98', '-121'],
				   ['3', '-32', '35'],
                   ['-2085924839766513752338888384931203236916703635113918720651407820138886450957659038931612598272',\
				   '-1042962419883256876169444192465601618458351817556959360325703910069443225478829519465806299136',\
				   '-1042962419883256876169444192465601618458351817556959360325703910069443225478829519465806299136'],
				   ['1042962419883256876169444192465601618458351817556959360325703910069443225478829519465806299136',\
				   '1042962419883256876169444192465601618458351817556959360325703910069443225478828393565899456512',\
				   '1125899906842624' ]
								]
		
		self.testdata['sub'] = [['0', '1', '1'],
					['1','1','0'],
					['-1','0','1'],
					['23','45','22'],
					['13','5','-8'],
					['26','-3','-29'],
					['-2582249878086908587416174429825207663772263512260779234709013859305998087116852093665853482099976886055025678701140377600',\
					'2239744742177804210557442280568444278121645497234649534899989100963791871180160945380877493271607115776',\
					'2582249878086908589655919172003011874329705792829223512830659356540647622016841194629645353280137831435903171972747493376']
								]
		
		self.testdata['mul'] = [
					['12','3','4'],
					['0','32','0'],
					['-0','-32','0'],
					['-54612','123','-444'],
					['54612','-123','-444'],
					['603822', '641', '942'],
					['1831650372496', '2341234', '782344'],
					['1007515750397959314', '1231231923', '818298918'],
					['324518553658426726783156020576256','18014398509481984',\
					'18014398509481984'],
					]
		
	def test_add(self):
		for i in self.testdata['add']:
			self.assertEqual(i[0], self.testobj.huge_add(i[1], i[2]))
			print i,
			print '		Passed!\n'

	def test_sub(self):
		for i in self.testdata['sub']:
			self.assertEqual(i[0], self.testobj.huge_sub(i[1], i[2]))
			print i,
			print '		Passed!\n'
	
	def test_multiple(self):
		for i in self.testdata['mul']:
			self.assertEqual(i[0], self.testobj.huge_multip(i[1], i[2]))
			print i,
			print '		Passed!\n'

if __name__=='__main__':
	unittest.main()


 然後開始設計算法:
   小學學過做乘法是逐位相乘,然後累加。 最後的累加是個陣列式。 累加我們可以調用之前設計的無符號加法函數來完成。 所以在計算機上乘法器是基於加法器一說便是這麼由來的。 先來看代碼:

#multiplication fun
	def _multi_poperate(self, anum, bnum):
		carry = 0
		rnum = []
		strrnum = []
		accnum = []
		acclist = []
		#Switch the short num to multiplicator
		if len(anum) < len(bnum):
			tmpnum = anum
			anum = bnum
			bnum = tmpnum
		#逐位相乘,乘積的陣列式放在二維列表acclist中, 
		#acclist的下標整好可以標識該行數據的進位。
		while bnum:
			adigit = 0
			bdigit = 0
			bdigit=bnum.pop()	
			for adigit in anum[::-1]:
				product = (bdigit * adigit + carry) % 10
				carry = (bdigit * adigit + carry)/10
				accnum.append(product)
			if carry:
				accnum.append(carry)
				carry = 0
			acclist.append(accnum[::-1])	
			accnum = []
		t = 1;
		rnum = acclist[0];
		#累加運算, 注意由於輸出是字符型列表,要實現累加需要對每次輸出進行整型轉型
		while t < len(acclist):
			for i in range(0,t):
				acclist[t].append(0)
				b = acclist[t]
			accnum = self._add_operate(rnum,b)
			for i in accnum:
				rnum.append(int(i))
			t +=1
		#去除高位多餘的0
		zerosign = 0	
		for i in rnum:
			if i:
				zerosign = 1
			if zerosign:
				strrnum.append(str(i))
		if not strrnum:
			strrnum = ['0']
		result = strrnum
		return result


    PS:中文註釋是寫文章的時候才加的。。之前覺得邏輯很簡單,沒有必要
    首先做的依然是根據位數交換乘數被乘數位置,減少陣列式累加次數。 之後是逐位相乘後放入陣列式中. 注意算乘法時最後有進位的話記得把進位進上去,並把進位寄存器清零。 每次乘出的積會倒序,所以需要對列表正序列化。
然後對陣列做累加,每次取陣列式裏面的數時要根據下標補零 (十進制的移位??)
最後去除高位多餘的0, 完成。

與二進制相比較算法大抵相當,都是做陣列式累加。 只是二進制乘法的逐位相乘就是一個左移位操作,非常便捷(因爲乘數要麼爲0,要麼爲1.。 爲0時該行直接添零,爲一時根據該位位置直接移位就好了) 。 串行乘法器所做的也就是‘移位-累加’操作罷了。 後來出現的並行乘法器算法也是一樣的, 不過藉由全加器實現了接受3個輸入(之前該位的累加結果+陣列值+進位值 ) 和提供兩個輸出(進位值+累加結果) 。 這樣便可以將執行效率提高N倍(理論值, N 爲被乘數位寬)。 但是歸根而言依舊是逐位相乘,再陣列累加的方法,只是將累加操作併發了而已

最後是乘法的接口函數:
  符號判斷很簡單,符號位求異或。。 計算機做乘法時也是這麼幹的。。
def huge_multip(self, a, b):
		asign = self._huge_init(a)[0]
		anum = self._huge_init(a)[1]
		bsign = self._huge_init(b)[0]
		bnum = self._huge_init(b)[1]
		#rsign: 0 -> + ; 1 -> -
		rsign = asign ^ bsign
		result = ''.join(self._multi_poperate(anum, bnum))
		if rsign:
			result = '-' + result
		return result

測試結果不發了。。 等除法做完一起貼上來。。

除法:

   除法這個纔是最有意思的。 二進制做除法相當爽啊, 直接做‘差-》移位’就搞定了。 因爲商只可能是0和1。 按照除法的法則,我們也可以從高位開始做差,然後移位。 但是我在這裏使用了另一種方法實現了類似操作:

def _div_operate(self, anum, bnum):
		trynum = [1]
		result = []
		n = 0
		# if divider is bigger than dividend, return '0'
		if len(anum) < len(bnum) or len(anum) == len(bnum) and \
		anum[0] < bnum[0]:
			return ['0']
		else:
			#Use the diff of tow number's length to ensure the try number's bit
			bitdiff = len(anum) - len(bnum)
			#If the first number of divider is bigger than dividend, try number's bit -1
			if anum[0] < bnum[0]:
				n = 1
			#Initial try number as a '10000' like number
			for i in range(n, bitdiff):
				trynum.append(0)
			#Use try number to multiply the dividend and compare with divider
			for i in range(0,len(trynum)):
				k = 1
				#If result number is bigger than divider, 
				#break out and set the littler bit to 1
				#If result is at the last bit, do not set the littler bit and break out.
				while 1:
					if k == 10:
						if i < len(trynum)-1:
							trynum[i] = 9
							break
						else:
							break
					strtryresult = self.huge_multip(bnum, trynum)
					tryresult = []
					for n in strtryresult:
						tryresult.append(int(n))
					if len(tryresult) > len(anum) or len(tryresult) == len(anum) and \
					tryresult > anum:
						if i < len(trynum) - 1:
							trynum[i] -= 1
							trynum[i+1] = 1
							break
						else:
							trynum[i] -= 1
							break
					else:
						trynum[i] += 1
						k +=1
			for n in trynum:
				result.append(str(n))
			return result

利用try number 逐位嘗試,直到找到小於,但最接近商的整數爲止(如果能整除則剛好相等了)。 先通過列表長度確定try number的位數,然後從高位開始遞增並與被除數相乘, 當大於除數時回退1, 並將挨着的低位置爲1, 直到最低位即得出結果了。


除法接口函數:

def huge_div(self, a, b):
		asign = self._huge_init(a)[0]
		anum = self._huge_init(a)[1]
		bsign = self._huge_init(b)[0]
		bnum = self._huge_init(b)[1]
		#rsign: 0 -> + ; 1 -> -
		if bnum[0] == 0 and len(bnum) == 1:
			return None
		else:
			rsign = asign ^ bsign
			result =''.join(self._div_operate(anum, bnum))
			if rsign:
				result = '-' + result
			return result

和乘法一樣, 用符號位異或來確定符號。

測試結果:

['2000', '1000', '1000'] 		Passed!

['0', '0', '0'] 		Passed!

['1', '0', '1'] 		Passed!

['0', '1', '-1'] 		Passed!

['337618', '3495', '334123'] 		Passed!

['-219', '-98', '-121'] 		Passed!

['3', '-32', '35'] 		Passed!

['-2085924839766513752338888384931203236916703635113918720651407820138886450957659038931612598272', '-1042962419883256876169444192465601618458351817556959360325703910069443225478829519465806299136', '-1042962419883256876169444192465601618458351817556959360325703910069443225478829519465806299136'] 		Passed!

['1042962419883256876169444192465601618458351817556959360325703910069443225478829519465806299136', '1042962419883256876169444192465601618458351817556959360325703910069443225478828393565899456512', '1125899906842624'] 		Passed!

.['3', '6', '2'] 		Passed!

[None, '2', '0'] 		Passed!

['0', '0', '3'] 		Passed!

['1', '3', '2'] 		Passed!

['25', '300', '12'] 		Passed!

['-3', '-6', '2'] 		Passed!

['-3', '6', '-2'] 		Passed!

['3', '-6', '-2'] 		Passed!

['2', '115792089237316195423570985008687907853269984665640564039457584007913129639936', '57896044618658097711785492504343953926634992332820282019728792003956564819968'] 		Passed!

['57896044618658097711785492504343953926634992332820282019728792003956564819968', '115792089237316195423570985008687907853269984665640564039457584007913129639936', '2'] 		Passed!

.['12', '3', '4'] 		Passed!

['0', '32', '0'] 		Passed!

['-0', '-32', '0'] 		Passed!

['-54612', '123', '-444'] 		Passed!

['54612', '-123', '-444'] 		Passed!

['603822', '641', '942'] 		Passed!

['1831650372496', '2341234', '782344'] 		Passed!

['1007515750397959314', '1231231923', '818298918'] 		Passed!

['324518553658426726783156020576256', '18014398509481984', '18014398509481984'] 		Passed!

.['0', '1', '1'] 		Passed!

['1', '1', '0'] 		Passed!

['-1', '0', '1'] 		Passed!

['23', '45', '22'] 		Passed!

['13', '5', '-8'] 		Passed!

['26', '-3', '-29'] 		Passed!

['-2582249878086908587416174429825207663772263512260779234709013859305998087116852093665853482099976886055025678701140377600', '2239744742177804210557442280568444278121645497234649534899989100963791871180160945380877493271607115776', '2582249878086908589655919172003011874329705792829223512830659356540647622016841194629645353280137831435903171972747493376'] 		Passed!

.
----------------------------------------------------------------------
Ran 4 tests in 0.698s

OK

若不考慮call 等的損耗的話,算法上比二進制時間複雜度多一倍左右(因爲要退位)。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章