電腦科學和Python程式設計導論(三) 一些簡單的數值程式
基本概念
1. 窮舉法
窮舉法
:是猜測與檢驗演算法的一個變種。我們列舉所有可能性,直至得到正確答案或者嘗試完所有值。
#尋找完全立方數的立方根
x = int(input('Enter an integer: '))
ans = 0
while ans**3 < abs(x):
ans = ans + 1
if ans**3 != abs(x):
print(x, 'is not a perfect cube')
else:
if x < 0:
ans = -ans
print('Cube root of', x,'is', ans)
那麼,對於何種x值,程式能正常結束呢?答案是“所有整數”。
注
:
1.表示式ans**3的值從0開始,並隨著每次迴圈逐漸變大;
2.當這個值達到或超過abs(x)時,迴圈結束;
3.因為abs(x)的值總為正,所以迴圈結束前進行的迭代次數必然是有限的。編寫迴圈時,應該使用一個合適的遞減函式。這個函式具有如下屬性:
- 它可以將一組程式變數對映為一個整數;
- 進入迴圈時,它的值是非負的;
- 當它的值≤0時,迴圈結束;
- 每次迴圈它的值都會減小。
2. for迴圈
for迴圈中常用到range()函式
,因此先對它進行介紹:
- range函式接受3個整數引數:start、stop和step。生成一個數列:start、start + step、start + 2*step,等等。
- 如果step是正數,最後一個元素就是小於stop的最大整數start + i * step。如果step是負數,最後一個元素就是大於stop的最小整數start + i * step。
- 數列中的數值是以“按需產生”的原則生成的,所以即使range(1000000)這樣的表示式也只佔用很少記憶體。
#尋找完全立方數的立方根
x = int(input('Enter an integer: '))
for ans in range(0, abs(x)+1):
if ans**3 >= abs(x):
break
if ans**3 != abs(x):
print(x, 'is not a perfect cube')
else:
if x < 0:
ans = -ans
print('Cube root of', x,'is', ans)
3. 近似解和二分查詢
窮舉法
是一種查詢技術,只在被查詢集合中包含答案時才有效
#使用窮舉法求近似平方根
x = 25
epsilon = 0.01
step = epsilon**2
numGuesses = 0
ans = 0.0
while abs(ans**2 - x) >= epsilon and ans <= x:
ans += step
numGuesses += 1
print('numGuesses =', numGuesses)
if abs(ans**2 - x) >= epsilon:
print('Failed on square root of', x)
else:
print(ans, 'is close to square root of', x)
二分查詢法
,可以提升查詢效率
x = 25
epsilon = 0.01
numGuesses = 0
low = 0.0
high = max(1.0, x)
ans = (high + low)/2.0
while abs(ans**2 - x) >= epsilon:
print('low =', low, 'high =', high, 'ans =', ans)
numGuesses += 1
if ans**2 < x:
low = ans
else:
high = ans
ans = (high + low)/2.0
print('numGuesses =', numGuesses)
print(ans, 'is close to square root of', x)
4. 關於浮點數
很多時候,float型別
的數值是實數的一個非常好的近似
。但“很多時候”並不代表所有情況,這個功能失效時會引起不可思議的後果。例如,試著執行以下程式碼:
x = 0.0
for i in range(10):
x = x + 0.1
if x == 1.0:
print(x, '= 1.0')
else:
print(x, 'is not 1.0')
# 結果
0.9999999999999999 is not 1.0
為什麼會出現這樣的結果呢?
- 其實這和二進位制與十進位制表示方式有關(python中二進位制表示的0.1並不是真的等於十進位制中0.1)。
- 那Python中寫作0.1的十進位制分數1/10呢?若使用4位有效數字,最好的表示方式是(0011,-101),等於3/32,也就是0.09375。如果有5位有效的二進位制數字,可以將0.1表示成(11001, -1000),等於25/256,也就是0.09765625。那麼,需要多少位有效數字才能使用浮點數準確表示0.1呢?需要無窮位!不存在兩個整數sig和exp,使sig × 2-exp = 0.1。所以無論Python(或任何一種語言)使用多少位有效數字表示浮點數,都只能表示0.1的一個近似值。
- 所以將0.1相加10次真的不等於10乘以0.1的值
5. 牛頓-拉弗森法
牛頓-拉弗森法
可以用於求單變數多項式的值,那麼什麼是單變數多項式?
單變數多項式或者是0,或者是一個有限數目的非零單項式的和。每一項都由一個常數(項的係數)乘以變數的非負整數次方(這裡為2次方)組成。
牛頓-拉弗森法的原理
:
逐次逼近;牛頓證明了一個定理:如果存在一個值guess是多項式p的根的近似值,那麼guess -p(guess)/p’(guess)就是一個更好的近似值,其中p’是p的一次導數。
#利用牛頓.拉弗森法尋找平方根
#尋找x,滿足x**2-24在epsilon和0之間
epsilon = 0.01
k = 24.0
guess = k/2.0
while abs(guess*guess - k) >= epsilon:
guess = guess - (((guess**2) - k)/(2*guess))
print('Square root of', k, 'is about', guess)
程式設計練習
1.編寫一個程式,要求使用者輸入一個整數,然後輸出兩個整數root和pwr,滿足0 <pwr < 6
,並且root**pwr
等於使用者輸入的整數。如果不存在這樣一對整數,則輸出一條訊息進行說明。
# 解法1
r = int(input('input an integer'))
root = 0
i = 0
for pwr in range(1, 7):
result = -1
while result < abs(r):
root += 1
result = root**pwr
if result == abs(r):
if r < 0:
root = -root
print('root:{},pwr:{}'.format(root, pwr))
i += 1
root = 0
print('總共有{}種輸出結果'.format(i))
# 解法2
x=int(input('Enter an integer: '))
root=1
pwr=1
w=root**pwr
i=0
while w<abs(x) or root<=abs(x):
if pwr<6:
w=root**pwr
if w==abs(x) and x<0:
i+=1
print('root','=',-root,'pwr','=',pwr)
elif w==abs(x):
i+=1
print('root','=',root,'pwr','=',pwr)
pwr+=1
else:
pwr=1
root+=1
w=root**pwr
print('符合條件的整數對共有{}種'.format(i))
2.假設s是包含多個小數的字串,由逗號隔開,如s = '1.23, 2.4, 3.123'
。編寫一個程式,輸出s中所有數值的和。
# 解法1
s = '1.23, 2.4, 3.123'
sum = 0.0
for i in map(lambda i: float(i), s.split(',')):
sum += i
print(sum)
# 解法2
s = '1.23, 2.4, 3.123'
a=s.split(',')
t=0
for i in a:
t=t+float(i)
print(t)
3.如果語句x = 25被替換為x = -25,程式碼會如何執行?
程式會進入無限迴圈
# 該程式while迴圈中,x值始終未變。則導致該迴圈條件(abs(ans**2 - x) >= epsilon)始終成立,程式進入無限迴圈中。
x = -25
epsilon = 0.01
numGuesses = 0
low = 0.0
high = max(1.0, x)
ans = (high + low)/2.0
while abs(ans**2 - x) >= epsilon: # 這一步永遠不會停止
print('low =', low, 'high =', high, 'ans =', ans)
numGuesses += 1
if ans**2 < x:
low = ans
else:
high = ans
ans = (high + low)/2.0
print('numGuesses =', numGuesses)
print(ans, 'is close to square root of', x)
4.如何修改圖3-4中的程式碼,才能求出一個數的立方根?這個數既可以是正數,也可以是負數。(提示:修改low保證答案位於待查詢區域。)
x = -30
epsilon = 0.01
numGuesses = 0
x_abs = abs(x) # 關鍵程式碼
low = 0.0
high = max(1.0, x_abs)
ans = (high + low) / 2.0
while abs(ans**3 - x_abs) >= epsilon:
numGuesses += 1
if ans**3 < x_abs:
low = ans
else:
high = ans
ans = (high + low) / 2.0
print('numGuesses =', numGuesses)
if x < 0:
print(-ans, 'is close to square root of', x)
else:
print(ans, 'is close to square root of', x)
5.二進位制數10011等於十進位制中的哪個數?
19
# 解法1 進位制轉換
# 解法2 函式求解
int('10011',base=2)
6.在牛頓.拉弗森法的實現中新增一些程式碼,跟蹤求平方根所用的迭代次數。在這段程式碼的基礎上編寫一個程式,比較牛頓.拉弗森法和二分查詢法的效率。
#利用牛頓.拉弗森法尋找平方根
#尋找x,滿足x**2-24在epsilon和0之間
epsilon = 0.01
k = 24.0
guess = k/2.0
a=0
while abs(guess*guess - k) >= epsilon:
guess = guess - (((guess**2) - k)/(2*guess))
a+=1
print('Square root of', k, 'is about', guess)
print('牛頓法迭代次數={}'.format(a))
#利用二分查詢法尋找平方根
#尋找x,滿足x**2-24在epsilon和0之間
x = 24.0
epsilon = 0.01
numGuesses = 0
low = 0.0
high = max(1.0, x)
ans = (high + low)/2.0
b=0
while abs(ans**2 - x) >= epsilon:
numGuesses += 1
if ans**2 < x:
low = ans
else:
high = ans
ans = (high + low)/2.0
print(ans, 'is close to square root of', x)
print('二分法迭代次數 ={}'.format(numGuesses))
Square root of 24.0 is about 4.8989887432139305
牛頓法迭代次數=4
4.8984375 is close to square root of 24.0
二分法迭代次數 =9
相關文章
- 電腦科學和Python程式設計導論(二 ) Python簡介Python程式設計
- 電腦科學和Python程式設計導論week1Python程式設計
- 電腦科學和Python程式設計導論(一) 計算機相關理論Python程式設計計算機
- 電腦科學和Python程式設計導論(六) 測試與除錯Python程式設計除錯
- 開啟電腦就能學習,風變程式設計讓學習程式設計更簡單程式設計
- 簡單理解非同步程式設計(python)和非同步程式設計(nodejs)非同步程式設計PythonNodeJS
- python學習之物件導向程式設計的一些思考Python物件程式設計
- 科學軟體十條簡單程式設計原則程式設計
- Python - 物件導向程式設計 - __new()__ 和單例模式Python物件程式設計單例模式
- Python程式設計方法論學習Python程式設計
- 風變程式設計,讓程式設計學習更簡單!程式設計
- 併發程式設計導論程式設計
- Python(簡單圖形和檔案處理)程式設計Python程式設計
- 學習Python程式設計哪種線路科學?Python程式設計
- 簡單學懂鏈式程式設計程式設計
- 2024 計算導論與程式設計程式設計
- Python學習之物件導向程式設計Python物件程式設計
- 最簡單的C程式設計--順序程式設計C程式程式設計
- 給Python初學者的一些程式設計技巧Python程式設計
- 程式導向程式設計哲學程式設計
- 簡單學:併發程式設計之 ThreadLocal程式設計thread
- 程式設計師程式設計時的簡單方法與技巧程式設計師
- Python物件導向程式設計Python物件程式設計
- Python 物件導向程式設計Python物件程式設計
- PYTHON程式設計導論群【提問與解惑】資料統計Python程式設計
- Python學習之路——類-物件導向程式設計Python物件程式設計
- 數學與程式設計:“機率論”總結程式設計
- [譯] 值型別導向程式設計型別程式設計
- 簡單是 Python 程式設計的第一要則Python程式設計
- Javascript 物件導向程式設計(三)JavaScript物件程式設計
- 《Python程式設計練習與解答》之程式設計概論Python程式設計
- Python中物件導向程式設計的一些高階方法拾遺Python物件程式設計
- Python網路程式設計(子程式的建立與處理、簡單群聊工具)Python程式設計
- Python - 物件導向程式設計 - 三大特性之繼承Python物件程式設計繼承
- 電腦程式設計是什麼?程式設計
- 物件導向程式設計和`GP`泛型程式設計物件程式設計泛型
- 程式設計師的數學程式設計師
- 【論文】核心電腦科學會議排名