日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > python >内容正文

python

python二十四点_Python秒算24点,行还是不行?

發(fā)布時(shí)間:2024/7/23 python 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python二十四点_Python秒算24点,行还是不行? 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

周末閑來無事,看到隔壁家的老王在和隔壁家的媳婦玩24點(diǎn),就進(jìn)屋看了看。發(fā)現(xiàn)老王是真不行啊,那不行,這也不行。

就連個(gè)24點(diǎn)都玩不過他媳婦,給他媳婦氣的,啥都不能滿足,這不能,那也不能。

我坐下來和他媳婦玩了兩把,那都是無出其右,把把贏!

我要走的時(shí)候,他媳婦還挽留我多玩幾把,有意思。

為了能讓老王在他媳婦面前抬起頭來,我決定幫他一把……就用python寫了個(gè)算24點(diǎn)的玩意,老王對(duì)我感激涕零。

什么是24點(diǎn)

我們先來約定下老王和他媳婦玩的24點(diǎn)規(guī)則:給定4個(gè)任意數(shù)字(0-9),然后通過`+,-,*,/`,將這4個(gè)數(shù)字計(jì)算出24。

小時(shí)候玩的都是這個(gè)規(guī)則,長大了才有根號(hào),才有各種莫名其妙的高級(jí)算法,不好玩了,因?yàn)槲也粫?huì)。

可能有人會(huì)覺得很簡單,但是真的簡單嗎?

比如:

* 8,3,3,3

* 7,3,3,3

你能一眼看出來答案嗎?好像真的可以……

大致思路

這樣想,將四個(gè)數(shù)字進(jìn)行全排列,在他們之間添加運(yùn)算符號(hào)。

運(yùn)算符我們需要進(jìn)行排列組合,因?yàn)橹挥兴膫€(gè)數(shù)字,所以只需要三個(gè)運(yùn)算符,而且算法符可能會(huì)重復(fù),比如三個(gè)都是`+`。

再遍歷四個(gè)數(shù)字的全排列,對(duì)每一組數(shù)字而言,遍歷所有組合的操作符。最后將數(shù)字和操作符進(jìn)行拼接運(yùn)算,就可以得到最終結(jié)果了。

演示環(huán)境

操作系統(tǒng):windows10

python版本:python 3.7

代碼編輯器:pycharm 2018.2

使用模塊:math,itertools, collections.abc

具體代碼

1、首先我們對(duì)所有數(shù)字進(jìn)行去全排列,這里我們使用 itertools.permutations 來幫助我們完成。

iertools.permutations 用法演示

from itertools import permutations

data_list = permutations([1,2,3,4],2)

for data in data_list:

print(data)

結(jié)果顯示

(1, 2)

(1, 3)

(1, 4)

(2, 1)

(2, 3)

(2, 4)

(3, 1)

(3, 2)

(3, 4)

(4, 1)

(4, 2)

(4, 3)

permutations 第一個(gè)參數(shù)是接收一個(gè)課迭代的對(duì)象,第二個(gè)參數(shù)指定每次排列時(shí)從課迭代對(duì)象中選著幾個(gè)字符進(jìn)行排列。也可以不傳入第二個(gè)參數(shù),那么默認(rèn)就是可迭代對(duì)象的長度。并且返回一個(gè)生成器。

所以我們需要對(duì)所有數(shù)字進(jìn)行全排列,就可以像下面這樣寫:

def get_all_data_sequence(data_iter):

return permutations(data_iter)

2、然后我們需要拿到所有的操作運(yùn)算符的所有組合方式。這里我們就會(huì)使用 `itertools.product` 函數(shù)了。

itertools.product 用法演示

from itertools import product

sequence1 = product('ABCD','xy')

sequence2 = product([0,1],repeat=3)

for sequence in sequence1:

print(sequence)

print('-'*30)

for sequence in sequence2:

print(sequence)

結(jié)果顯示

('A','x')

('A','y')

('B','x')

('B','y')

('C','x')

('C','y')

('D','x')

('D','y')

------------------------------

(0, 0, 0)

(0, 0, 1)

(0, 1, 0)

(0, 1, 1)

(1, 0, 0)

(1, 0, 1)

(1, 1, 0)

(1, 1, 1)

`itertools.product`,返回傳入所有序列中笛卡爾積的元祖,repeat參數(shù)表示傳入序列的重復(fù)次數(shù)。返回的是一個(gè)生成器。

那么獲取所有的操作運(yùn)算符就可以通過這個(gè)函數(shù)來獲取了

def get_all_operations_sequence():

operations = ['+','-','*','/']

return product(operations,repeat=3)

3、現(xiàn)在我們已經(jīng)拿到了所有可能組合的操作符和數(shù)字了,接下來就需要對(duì)他們進(jìn)行拼接了。然后執(zhí)行運(yùn)算。

這一步操作我們會(huì)用到 `itertools.zip_longest()` 和 `itertools.chain.form_iterable()` 函數(shù)。

itertools.zip_longest() 用法演示

data = zip_longest([1,2,3,4],['*','-','+'],fillvalue='')

for value in data:

print(value)

結(jié)果顯示

(1, '*')

(2, '-')

(3, '+')

(4, '')

zip_longest() 其實(shí)和 python 內(nèi)置的 zip() 函數(shù)用法差不多,只是 zip_longest 是以最長的一個(gè)序列為基準(zhǔn),缺失值就使用 `fillvalue` 參數(shù)的值進(jìn)行填充

itertools.chain.form_iterable() 用法演示

data = zip_longest([1,2,3,4],['*','-','+'],fillvalue='')

data_chain = chain.from_iterable(data)

for value in data_chain:

print(value)

結(jié)果顯示

1

*

2

-

3

+

4

這里的data是什么樣的大家知道了吧,然后我們將data傳入 chain.form_iterable() 中,它就能將里面的值依次拿出來。

了解了這兩個(gè)函數(shù)之后,那么我們就可以開始拼接數(shù)字和操作運(yùn)算符了。

def calculate(self):

'''

計(jì)算值,返回對(duì)應(yīng)的表達(dá)式和值

:return:

'''

for data_sequence in get_all_data_sequence():

operation_sequences = get_all_operation_sequence()

for operation_sequence in operation_sequences:

value = zip_longest(data_sequence, operation_sequence,

fillvalue='')

value_chain = chain.from_iterable(value)

calculate_str = ''

# 對(duì)得到的字符進(jìn)行拼接成為表達(dá)式 calculate_str

for _ in value_chain:

calculate_str += _

try:

result = eval(calculate_str

# 處理被除數(shù)可能為零的情況,然后就直接跳過這次循環(huán)

except ZeroDivisionError:

continue

if math.isclose(result, 24):

return calculate_str,result

return None,None

代碼分析

1、eval() 函數(shù),接受一個(gè)字符串,能讓這個(gè)字符串當(dāng)成 python 代碼運(yùn)行,返回運(yùn)行的結(jié)果。

2、math.isclose():為什么這里需要使用 math.isclose() ,而不是直接使用`==`運(yùn)算符呢?這是因?yàn)樽詈笏愠鰜淼谋磉_(dá)式可能有精度問題,例如23.9...或者24.0...等數(shù)字,所以我們就需要使用math.isclose()函數(shù)來幫助我們判斷兩個(gè)數(shù)字是否相等了,這個(gè)函數(shù)就有一個(gè)精度范圍。這樣出現(xiàn)上面情況的時(shí)候,我們也能匹配得到條件了。

我們運(yùn)行代碼,然后測(cè)試代碼是否能達(dá)到我們的需求。

首先我們測(cè)試1,2,3,4四個(gè)數(shù)字,

程序出來了結(jié)果 `1*2*3*4` 24

看來好像我們寫的代碼是正確的

我們?cè)賮頊y(cè)試一組數(shù)據(jù)8,8,3,3.

嗯?我們并沒有得到結(jié)果?這四個(gè)數(shù)字不能運(yùn)算出24嗎?

`8 / ( 3 - 8 / 3 )` 這樣組合可以吧,為什么沒有算出來這種結(jié)果呢?

這是因?yàn)槲覀儧]有考慮括號(hào)的原因。括號(hào)是可以改變運(yùn)算優(yōu)先級(jí)的。所以我們得把括號(hào)考慮進(jìn)去。

那么想一下括號(hào)最多可以有幾個(gè)呢?怎樣給我們的表達(dá)式添加括號(hào)呢?

在4個(gè)數(shù)字的運(yùn)算中,括號(hào)最多只能有三個(gè)。

并且,在這里,我們使用一種簡單的方法添加括號(hào),我們把所有可能出現(xiàn)括號(hào)的情況全部羅列出來,然后在將得到的運(yùn)算表達(dá)式拼接進(jìn)去。

可能大家會(huì)覺得羅列出所有括號(hào)出現(xiàn)的情況不現(xiàn)實(shí),因?yàn)橛泻芏嗲闆r

其實(shí)不然,當(dāng)我們?nèi)チ_列的時(shí)候,你就會(huì)發(fā)現(xiàn),只有11種情況。

FORM_STRS = [

# 數(shù)字 運(yùn)算符 數(shù)字 運(yùn)算符 數(shù)字 運(yùn)算符 數(shù)字

# 一個(gè)括號(hào) 的情況

'(%s%s%s)%s%s%s%s',

'(%s%s%s%s%s)%s%s',

'(%s%s%s%s%s%s%s)',

'%s%s(%s%s%s)%s%s',

'%s%s(%s%s%s%s%s)',

'%s%s%s%s(%s%s%s)',

# 兩個(gè)括號(hào) 的情況

'(%s%s%s)%s(%s%s%s)',

'( (%s%s%s)%s%s)%s%s',

'(%s%s(%s%s%s))%s%s',

'%s%s((%s%s%s)%s%s)',

'%s%s(%s%s(%s%s%s))',

# 三個(gè)括號(hào)是重復(fù)的,就不用羅列出來了

]

然后我們對(duì)得到的表達(dá)式在進(jìn)行遍歷拼接,然后我們?cè)龠\(yùn)算表達(dá)式。

這樣我們就能得出正確的結(jié)果了

代碼寫完了,終于可以開始和媳婦,哦不,老王家的媳婦玩起來了

關(guān)注公眾號(hào)「Python專欄」,更多好玩有趣的Python等著你

總結(jié)

以上是生活随笔為你收集整理的python二十四点_Python秒算24点,行还是不行?的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。