主頁 > 後端開發 > 這個Python自動掃雷演算法寫完了,估計看懂的人十不存一了吧

這個Python自動掃雷演算法寫完了,估計看懂的人十不存一了吧

2022-01-06 17:20:50 後端開發

效果

 

 

?

 

閑來無事,打開虛擬機上的掃雷玩了玩,覺得自己計算很浪費時間,還容易遺漏,就做了個自動掃雷,
簡單模式下很容易通關,困難的就看臉了,感興趣的可以拿去運行一下,
自動化處理核心代碼段在 168~273行,

很多人學習蟒蛇,不知道從何學起,

很多人學習python,掌握了基本語法之后,不知道在哪里尋找案例上手,

很多已經可能案例的人,卻不知道如何去學習更多高深的知識,

那么針對這三類人,我給大家提供一個好的學習平臺,免費獲取視頻教程,電子書,以及課程的源代碼!

QQ群:101677771

歡迎加入,一起討論一起學習

 

 

次日,發現自動掃雷演算法并不完整,上次的代碼僅對單個數字周圍進行判斷,
但在一些情況下,單個數字無法判斷,要綜合一片小區域確定某些方塊是否一定是炸彈,或者一定安全,
暫且稱為高級演算法,(并不是演算法有多高級,本質上還是取集合(區域),進行大量的判斷,難在復雜判斷的邏輯關系以及集合、字典的操作上),
通過半天的歸納總結,找到規律后開始設計代碼,

 

**本次修改還優化了輸出格式,使得在大區域下更容易確定方塊的坐標,**

 

  • 【代碼中一些重復的地方可以提取出來作為單獨的方法,通過改變引數位置來實作相同的功能,讓代碼看上去更精簡】
  • 【但長時間的修改代碼,隨著變數、變數型別、資料結構嵌套和邏輯關系的不斷增加,有點被搞得頭暈了】
  • 【所以既然運行上沒有錯誤,多次試驗也沒有發現毛病,就不去管它了,說不定也是靠著什么bug運行起來了呢】
  • 【事實上最初寫出來的高級演算法代碼還多了一個子模塊,這個模塊在一次高級演算法結束之后進行進一步處理】
  • 【在設計演算法的時候,考慮到這樣能減少遍歷游戲視窗的次數,加快運行速度,并且可以確定更多的更復雜的坐標及操作】
  • 【雖然寫好代碼之后第一次運行全自動困難模式順利通關,但在后來的幾次測驗中總會錯把炸彈點開??】
  • 【而且計算出的坐標我實在是看不懂根據什么條件算出來的,修改多次無果,想著是不是演算法最初處理的時候就是錯誤的】
  • 【把這段代碼注釋掉之后,多次測驗,沒有任何錯誤,而且計算出來的坐標和操作都是正確的!計算不出來的時候,我看著也是無法確定哪個方塊安全】
  • 【這種情況下只能靠運氣隨機選擇,所以上文說到,說不定是靠著什么bug運行起來的呢,】

 

教學時間:

 


咱都上榜一了,咋能不出個教學呢,
(綠色底為演算法講解,藍色底為舉例說明,無色底、算是旁白或設計演算法的程序吧,)

 

首先介紹下掃雷的冷知識:

 


掃雷上面數字的意思是該方塊周圍八格方塊中的雷的個數,

 


有時候點一下會開一大片,是因為點到了數字0,0周圍沒有方塊,游戲會自動向四周擴散,直到有數字的方塊停止,(0向四周擴散是不可能遇到雷的)

 


這段“點到0向四周擴散”的代碼在141~150行,通過126-128行進入,通過非常簡單的遞回實作的,遍歷一遍0方塊周圍的方塊,是數字就顯示數字,是0就再次呼叫該方法,傳入該位置,這段代碼可以優化,但重點是自動掃雷,

 

生成一局掃雷的方法:(對應代碼43 ~ 63行)

 


先生成指定大小(m×n)的空間,我在這里用了二維陣串列示,初始化全為0,程式中變數名為game_space, 然后隨機k(k個雷)個不同坐標,用’*‘表示雷,記錄在陣列中,
然后遍歷一下每個雷的周圍八個格子,如果不是字符’*‘,則+1,生成完成,(可以驗證,數字與周圍雷的數量都是匹配的)

 


可能有同學會質疑,既然game_space串列已經記錄了雷的位置,那還有啥掃的?
實際上,掃雷游戲就是提前生成好的游戲棋盤資料,然后在每個格子上都蓋上蓋子而已,這里表示頂層蓋子的串列是show_list,

 


所有的操作都在show_list串列上,game_space串列僅用于點擊show_list串列時進行資料補充,相當于掀開了外層的蓋子,露出了里面的內容,

 

自動掃雷:

 


自動掃雷就是一個模擬玩家掃雷的程序,你開一局掃雷,第一個肯定是要隨便點的,如果運氣爆棚,是可以直接點到雷結束該局游戲的,

 


點到數字一般也不會是8,一般都是從點到0開始才能判斷哪里是雷,哪里是安全的,
這里開一局“簡單”模式的掃雷,8*8大小,10個雷,用于舉例說明,(順帶一提,我寫的輸出格式在pycharm里輸出是整齊的,沒有在IDLE里測驗過,這里粘貼過來■就比數字寬些)
隨機選擇【4, 3】點開
Game Over!
1│ ■ ■ ■ ■ ■ ■ ■ ■
2│ ■ ■ ■ ■ ■ ■ ■ ■
3│ ■ ■ ■ ■ ■ ■ ■ ■
4│ ■ ■ * ■ ■ ■ ■ ■
5│ ■ ■ ■ ■ ■ ■ ■ ■
6│ ■ ■ ■ ■ ■ ■ ■ ■
7│ ■ ■ ■ ■ ■ ■ ■ ■
8│ ■ ■ ■ ■ ■ ■ ■ ■
運氣爆棚,一發入魂, 再開一局,
再開N局,
無法確定位置,隨機選擇【2, 1】點開
無法確定位置,隨機選擇【4, 8】點開
1│ ■ ■ ■ ■ ■ ■ 1 0
2│ 1 ■ ■ ■ ■ ■ 1 0
3│ ■ ■ ■ ■ ■ 1 1 0
4│ ■ ■ ■ ■ ■ 1 0 0
5│ ■ ■ ■ ■ ■ 3 1 1
6│ ■ ■ ■ ■ ■ ■ ■ ■
7│ ■ ■ ■ ■ ■ ■ ■ ■
8│ ■ ■ ■ ■ ■ ■ ■ ■
這里我們可以通過【行3列7】(以下使用形如【3,7】表示)確定【2,6】是雷,因為【3,7】周圍只有【2,6】沒有點開,而【3,7】周圍只有一個雷,
給【2,6】插上旗子之后,又可以通過【1,7】判斷【1,6】是安全的,可以點開;可以通過【3,6】判斷【2,5】【3,5】【4,5】是安全的,
【2,5】【3,5】【4,5】點開后 又可以通過【4,6】判斷【5,5】是雷,

 

自動演算法說明:(該段代碼在174-198行)

 


掃雷棋盤使用二維陣串列示,首先通過兩層回圈遍歷,找到一個大于0的數字,使用一個變數’z‘記錄這個數字,
再遍歷一下該數字周圍的八格格子,這里我又使用了兩層回圈實作,(代碼在178-180行,要確保坐標不超界),
在遍歷程序中,若發現插了旗子‘□’的格子,則讓z - 1,表示z周圍已經確定了1個雷,所以還剩z - 1個雷,
如果發現了還沒有點開過的格子’■‘,則記錄該坐標,(代碼中用類變數coordinate_list串列記錄)
八個格子遍歷完成后,若 z 等于 0, 則說明coordinate_list串列中記錄的’■‘格子都是安全的,可以點擊,于是將coordinate_list串列中的每個坐標后記錄可以點擊(即操作1),回傳,
若z 等于 coordinate_list串列的長度,則可以確定coordinate_list串列中記錄的’■‘格子都是雷 ,給這些坐標記錄上插旗操作(即操作0),回傳,
剩下的情況就是coordinate_list串列長度 大于 z了,這種情況無法確定記錄的格子是什么東西,則清空coordinate_list串列, 繼續回圈,尋找下個數字進行這套操作,
注意到z = 0時,coordinate_list串列可能為空,所以要在回傳前判斷coordinate_list串列非空,(代碼194行)
回傳的只是串列中的一個坐標及操作,若串列中有多個坐標,要全部進行相應操作,對應代碼(168-172行)

 

還可以通過綜合一個區域判斷【6,5】【6,7】一定是雷,因為【5,6】周圍有3個雷,【5,5】是1個,剩下兩個在【6,5】【6,6】【6,7】中;

 


而通過【5,7】可知【6,6】【6,7】【6,8】中只有1個雷,所以【6,5】一定是雷,又由【5,8】可知【6,7】【6,8】中有1個雷,

 


所以【6,7】一定是雷,【6,6】【6,8】安全,若存在疑惑,可通過假設法假設【6,6】或【6,8】是雷,通過推匯出雷周圍的數字與數字周圍的雷數不符合,得到驗證,

 


這里就是上面提到的“高級演算法”,會在下文中詳細介紹演算法(就是一堆復雜的資料結構和邏輯判斷),
這里只是說明了通過現在的局面可以判斷到的格子,在自動掃雷程式中是按行先遍歷的,不一定就是按我說的這些去依次點開,可能點開【1,6】后又能判斷出【1,6】周圍的格子是安全的了,
(順帶一提,有??圖文字,但是寬度和方塊、數字不一樣,為了輸出排版,就換成了白色方塊□ 代替??,大家也可以修改代碼,將所有字符、數字換成全角,)
讓我們繼續游戲:(操作0是插旗的意思,操作1是點開的意思)

 

選定位置【2, 6】, 操作為:0
選定位置【1, 6】, 操作為:1
1│ ■ ■ ■ ■ ■ 1 1 0
2│ 1 ■ ■ ■ ■ □ 1 0
3│ ■ ■ ■ ■ ■ 1 1 0
4│ ■ ■ ■ ■ ■ 1 0 0
5│ ■ ■ ■ ■ ■ 3 1 1
6│ ■ ■ ■ ■ ■ ■ ■ ■
7│ ■ ■ ■ ■ ■ ■ ■ ■
8│ ■ ■ ■ ■ ■ ■ ■ ■
在這里插入掃雷串列,是因為點開【1,6】后可通過【1,6】【2,6】判斷【1,5】【2,5】安全,已經和我上面所述的操作路徑不同了,
下面我不在詳細展示,讓我們直接快進到需要重要介紹的位置,
選定位置【2, 5】, 操作為:1
選定位置【1, 5】, 操作為:1
……
……
1│ 0 0 1 □ 2 1 1 0
2│ 1 1 2 1 2 □ 1 0
3│ 2 □ 2 0 1 1 1 0
4│ 2 □ 2 1 1 1 0 0
5│ 2 2 1 2 □ 3 1 1
6│ □ 1 0 3 □ ■ ■ ■
7│ 2 2 1 2 □ 3 1 1
8│ 1 □ 1 1 1 1 0 0
呼叫高級計算處理,請等候...
計算完成!生成操作:
坐標【6,8】,操作:1
坐標【6,6】,操作:1
========================
選定位置【6, 6】, 操作為:1
選定位置【6, 8】, 操作為:1
選定位置【6, 7】, 操作為:0
可以看到,通過上面簡單的計算,已經快將游戲解完了,在簡單模式下,多數情況根本用不上高級計算,這局游戲是開了許多局才呼叫到了高級演算法代碼,就算沒有高級演算法,也可以通過隨機方法隨機一個坐標點開,有2/3的概率是數字,只要點開一個是數字,就可以確定最后一個雷的位置了,
可由【5,8】知道【6,7】【6,8】中有1個雷,由【5,7】知道 【6,6】【6,7】【6,8】中有1個雷,所以【6,6】一定是安全的,可以點開,
可由【5,6】得知【6,6】【6,7】中有1個雷,綜合【5,7】,可以確定【6,8】是安全的,可以點開,
這就是需要通過綜合一片區域才能確定的,用代碼實作確實比較復雜,

 

高級演算法說明:(代碼在228~273行,通過202行呼叫)

 


要將這種思想轉化為代碼,就要先總結他們共有的特征,就是找規律,規律是:求差集,
這里要用到python的 字典、集合、元組、串列,

 


首先,我將游戲輸出串列show_list做了一個處理,把所有>0的數字減去他們周圍已經插旗的個數,結果保存在了processed_list串列中,(代碼229~247行)

 


在處理之前 要先創建一個空的集合c(代碼238行),在遍歷數字周圍八個方格時,如果遇到沒有打開的方格’■‘,則在c中記錄該方格坐標,這里,我們相當于得到了一個區域,

 


遍歷完八個方格之后,如果集合c非空,那么處理的數字一定還>0,將集合c轉變為元組,作為字典的鍵,處理后的數字做為該鍵對應的值,(字典名為set_dic)
對上面的示例,該操作能得到:

 

1│ 0 0 0 □ 0 0 0 0
2│ 0 0 0 0 0 □ 0 0
3│ 0 □ 0 0 0 0 0 0
4│ 0 □ 0 0 0 0 0 0
5│ 0 0 0 0 □ 1 1 1
6│ □ 0 0 0 □ ■ ■ ■
7│ 0 0 0 0 □ 1 1 1
8│ 0 □ 0 0 0 0 0 0

 


并得到字典set_dic = {((6, 6), (6, 7)) : 1, ((6, 6), (6, 7), (6, 8)) : 1, ((6, 7), (6, 8)) : 1} 【解釋下為什么要將集合c轉化為元組,因為集合是可變資料型別,屬于非可哈希型別,無法作為字典的鍵,】
之后就是對字典的兩層回圈:取其中一個鍵,(取完鍵之后首先轉變為集合型別,通過集合型別自帶的判斷子集的方法),與其他鍵做判斷是否為子集,
如果是子集,即可求差集,并求這兩個鍵對應值的差,如果值的差為0,說名求得的差集中的坐標是安全的,可以打開;如果值的差非零,如果值得差等于差集的長度,說明差集中的坐標一定是雷,需要插旗,(代碼249~273)
對應上面的示例,集合a = {(6, 6), (6, 7)} 是 集合b = {(6, 6), (6, 7), (6, 8)}的子集, 求差集 b - a 得到差集{(6, 8)}, 差值為0,說明坐標(6,8)的方格’■‘是安全的,
之后就是將元組(6,8)轉換為串列[6, 8],加入操作碼得到[6, 8, 1],加入到操作串列 coordinate_list 中,
講解結束,這也不算難,也得益于python本身的優勢,如果用其他語言,還要定義大量結構體,或無休止的取值賦值,
這里順便說個bug,代碼中在得到差集和差值后,加入操作串列的時候沒有判斷要插入的資料是否已經存在,因為可能通過不同的集合判斷得到同一個差集,如果是點擊操作還好,點擊過后該方塊不能再進行其他操作,但如果是插旗,那么插旗之后再插旗就是取消插旗,

 


而操作完成之后,下次高級判斷可能還會得到兩次相同坐標的插旗操作,那么程式將進入無線回圈,所以可以將 coordinate_list 串列變成集合型別,集合本身不允許重復,或者在向 coordinate_list 串列加入資料前前進行一個重復判斷,
這個bug是在測驗 行100,列200,雷3000的游戲中發現的bug,小規模一般不會遇到,

 

【可以將帶有注釋的time.sleep代碼給打開,在括號內設定合適的時長,可以看到自動掃雷的程序】

 

python代碼

 

import random
import time
 
 
class SaoLei:
    m: int
    n: int
    k: int
    mode: int
    coordinate_list = []
    game_space: list[list[int or str]]
 
    def __init__(self, m: int, n: int, k: int, mode: int):
        """
        初始化游戲
        :param m: m行, m >= 8
        :param n: n列, n >= 8
        :param k: k個雷, 10 <= k <= m*n*0.3
        :param mode: 0:手動模式,1:全自動模式 2:半自動模式
        """
        if m >= 8:
            self.m = m
        else:
            print("row Error!")
            exit(0)
        if n >= 8:
            self.n = n
        else:
            print("col Error!")
            exit(0)
        if 10 <= k <= m * n * 0.3:
            self.k = k
            self.flag = self.k
        else:
            print("k Error!")
            exit(0)
        if mode in (0, 1, 2):
            self.mode = mode
        else:
            print("Mode Error!")
            exit(0)
 
        # 生成區域
        self.game_space = [[0 for _ in range(n)] for _ in range(m)]
        print("game_space create success!")
 
        # 隨機雷的位置
        i = 0
        while i < self.k:
            a = random.randint(0, m - 1)
            b = random.randint(0, n - 1)
            if self.game_space[a][b] != '*':
                i += 1
 
                # 產生資料
                self.game_space[a][b] = '*'
                c = [-1, 0, 1]
                for x in c:
                    if 0 <= a + x < m:
                        for y in c:
                            if 0 <= b + y < n:
                                if self.game_space[a + x][b + y] != '*':
                                    self.game_space[a + x][b + y] += 1
 
        # 呼叫游戲行程
        self.game_window()
 
    def game_window(self):
        show_list = [['■' for _ in range(self.n)] for _ in range(self.m)]
        text = ''
        while True:
            # 輸出畫面
            for i in range(10):
                print()
            print(text)
            print("+++" * self.n, end='+\n')
            print(' │ ', end='')
            for k in range(1, self.n + 1):
                print('%d' % (k % 10), end='  ')
            print('\n─┼─', end='')
            print('───' * (self.n - 1), end='─\n')
            k = 1
            for i in range(self.m):
                print(k, end='│ ')
                for j in range(self.n):
                    print(show_list[i][j], end='  ')
                print()
                k = (k + 1) % 10
            if text == 'Game Over!':
                exit(0)
            text = ''
 
            # 檢測是否結束
            row = self.m
            for i in show_list:
                if '■' not in i:
                    row -= 1
            if row == 0:
                print('Victory!')
                exit(1)
 
            # 輸入坐標及操作
            if self.mode == 0:
                a, b, c = self.input_set()
            else:
                a, b, c = self.automatic_input(show_list)
 
            # 進行處理
            if c == 0:
                if self.flag > 0:
                    if show_list[a][b] == '■':
                        show_list[a][b] = '□'
                        self.flag -= 1
                    elif show_list[a][b] == '□':
                        show_list[a][b] = '■'
                        self.flag += 1
                    else:
                        text = 'Error! Is number'
                else:
                    text = 'Error! No flag'
            elif c == 1:
                if show_list[a][b] == '■':
                    if self.game_space[a][b] == '*':
                        show_list[a][b] = '*'
                        text = 'Game Over!'
                    elif self.game_space[a][b] == 0:
                        show_list[a][b] = self.game_space[a][b]
                        self.look_zero(a, b, show_list)
                    else:
                        show_list[a][b] = self.game_space[a][b]
                else:
                    text = 'Error! No Click'
            elif c == 2:
                if show_list[a][b] == '■':
                    show_list[a][b] = '?'
                elif show_list[a][b] == '?':
                    show_list[a][b] = '■'
                else:
                    text = 'Error! Open'
 
    def look_zero(self, a: int, b: int, show_list):
        for i in range(a - 1, a + 2):
            for j in range(b - 1, b + 2):
                if 0 <= i < self.m and 0 <= j < self.n:
                    if show_list[i][j] == '■':
                        if self.game_space[i][j] == 0:
                            show_list[i][j] = 0
                            self.look_zero(i, j, show_list)
                        else:
                            show_list[i][j] = self.game_space[i][j]
 
    def input_set(self):
        a = int(input("輸入行:"))
        b = int(input("輸入列:"))
        c = int(input("操作(0:插旗; 1:點擊; 2:標記):"))
        if not (0 < a <= self.m and 0 < b <= self.n and c in (0, 1, 2)):
            a, b, c = self.input_set()
            a += 1
            b += 1
        return a - 1, b - 1, c
 
    def automatic_input(self, show_list: list[list]
 
 
):
        """
        自動化方法
        :param show_list:
        :return:a,b,c
        """
        if self.coordinate_list:
            a = self.coordinate_list.pop()
            print("選定位置【%d, %d】, 操作為:%d" % (a[0] + 1, a[1] + 1, a[2]))
            # time.sleep(0.5)
            return a[0], a[1], a[2]
 
        for i in range(self.m):
            for j in range(self.n):
                if type(show_list[i][j]) is not str and show_list[i][j] > 0:
                    z = show_list[i][j]
                    for x in range(i - 1, i + 2):
                        for y in range(j - 1, j + 2):
                            if 0 <= x < self.m and 0 <= y < self.n:
                                if show_list[x][y] == '□':
                                    z -= 1
                                elif show_list[x][y] == '■':
                                    self.coordinate_list.append([x, y])
                    if z == 0:
                        for p in range(len(self.coordinate_list)):
                            self.coordinate_list[p].append(1)
                    elif z == len(self.coordinate_list):
                        for p in range(len(self.coordinate_list)):
                            self.coordinate_list[p].append(0)
                    else:
                        self.coordinate_list.clear()
 
                    if self.coordinate_list:
                        a = self.coordinate_list.pop()
                        print("選定位置【%d, %d】, 操作為:%d" % (a[0] + 1, a[1] + 1, a[2]))
                        # time.sleep(0.5)
                        return a[0], a[1], a[2]
 
        # 進入高級計算
        print("呼叫高級計算處理,請等候...")
        self.advanced_automatic_input(show_list)
        if self.coordinate_list:
            print("計算完成!生成操作:")
            for mmm in self.coordinate_list:
                print("\t坐標【%d,%d】,操作:%d" % (mmm[0] + 1, mmm[1] + 1, mmm[2]))
            print("========================")
            a = self.coordinate_list.pop()
            print("選定位置【%d, %d】, 操作為:%d" % (a[0] + 1, a[1] + 1, a[2]))
            # time.sleep(0.5)
            return a[0], a[1], a[2]
 
        # 無法確定,隨機選擇位置
        elif self.mode == 1:
            a = random.randint(0, self.m - 1)
            b = random.randint(0, self.n - 1)
            while show_list[a][b] != '■':
                a = random.randint(0, self.m - 1)
                b = random.randint(0, self.n - 1)
            else:
                print("無法確定位置,隨機選擇【%d, %d】點開" % (a + 1, b + 1))
                # time.sleep(2)
                return a, b, 1
        else:
            print("無法確定位置,請手動輸入, 提示:還有【%d】個" % self.flag)
            return self.input_set()
 
    def advanced_automatic_input(self, show_list: list[list]
 
 
):
        processed_list = []
        set_dic = dict()
        for i in show_list:
            processed_list.append(i.copy())
 
        # 初步處理
        for i in range(self.m):
            for j in range(self.n):
                if type(processed_list[i][j]) is int and processed_list[i][j] > 0:
                    c = set()
                    for p in range(i - 1, i + 2):
                        for q in range(j - 1, j + 2):
                            if 0 <= p < self.m and 0 <= q < self.n:
                                if processed_list[p][q] == '□':
                                    processed_list[i][j] -= 1
                                elif processed_list[p][q] == '■':
                                    c.add((p, q))
                    if c:
                        set_dic[tuple(c)] = processed_list[i][j]
 
        # 尋找子集
        key_list = list(set_dic.keys())
        for i in range(len(key_list)):
            for j in range(i + 1, len(key_list)):
                if len(key_list[i]) < len(key_list[j]):
                    p = i
                    q = j
                elif len(key_list[i]) > len(key_list[j]):
                    p = j
                    q = i
                else:
                    continue
 
                if set(key_list[p]).issubset(set(key_list[q])):
                    d = list(set(key_list[q]) - set(key_list[p]))
                    if set_dic[key_list[q]] - set_dic[key_list[p]] == 0:
                        for k in d:
                            e = list(k)
                            e.append(1)
                            self.coordinate_list.append(e)
                    elif set_dic[key_list[q]] - set_dic[key_list[p]] == len(d):
                        for k in d:
                            e = list(k)
                            e.append(0)
                            self.coordinate_list.append(e)
 
 
# 傳參【 m行,n列, k個雷, mode:0、手動; 1、全自動; 2、半自動】,可自定義
# 簡單 8 8 10
# 一般 16 16 40
# 困難 16 32 99
game = SaoLei(16, 32, 99, 2)

 

 

?

 

?

 

?

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/404280.html

標籤:其他

上一篇:SpringBoot自動裝配

下一篇:C語言練習 通過移位演算法10進制轉2進制

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【C++】Microsoft C++、C 和匯編程式檔案

    ......

    uj5u.com 2020-09-10 00:57:23 more
  • 例外宣告

    相比于斷言適用于排除邏輯上不可能存在的狀態,例外通常是用于邏輯上可能發生的錯誤。 例外宣告 Item 1:當函式不可能拋出例外或不能接受拋出例外時,使用noexcept 理由 如果不打算拋出例外的話,程式就會認為無法處理這種錯誤,并且應當盡早終止,如此可以有效地阻止例外的傳播與擴散。 示例 //不可 ......

    uj5u.com 2020-09-10 00:57:27 more
  • Codeforces 1400E Clear the Multiset(貪心 + 分治)

    鏈接:https://codeforces.com/problemset/problem/1400/E 來源:Codeforces 思路:給你一個陣列,現在你可以進行兩種操作,操作1:將一段沒有 0 的區間進行減一的操作,操作2:將 i 位置上的元素歸零。最終問:將這個陣列的全部元素歸零后操作的最少 ......

    uj5u.com 2020-09-10 00:57:30 more
  • UVA11610 【Reverse Prime】

    本人看到此題沒有翻譯,就附帶了一個自己的翻譯版本 思考 這一題,它的第一個要求是找出所有 $7$ 位反向質數及其質因數的個數。 我們應該需要質數篩篩選1~$10^{7}$的所有數,這里就不慢慢介紹了。但是,重讀題,我們突然發現反向質數都是 $7$ 位,而將它反過來后的數字卻是 $6$ 位數,這就說明 ......

    uj5u.com 2020-09-10 00:57:36 more
  • 統計區間素數數量

    1 #pragma GCC optimize(2) 2 #include <bits/stdc++.h> 3 using namespace std; 4 bool isprime[1000000010]; 5 vector<int> prime; 6 inline int getlist(int ......

    uj5u.com 2020-09-10 00:57:47 more
  • C/C++編程筆記:C++中的 const 變數詳解,教你正確認識const用法

    1、C中的const 1、區域const變數存放在堆疊區中,會分配記憶體(也就是說可以通過地址間接修改變數的值)。測驗代碼如下: 運行結果: 2、全域const變數存放在只讀資料段(不能通過地址修改,會發生寫入錯誤), 默認為外部聯編,可以給其他源檔案使用(需要用extern關鍵字修飾) 運行結果: ......

    uj5u.com 2020-09-10 00:58:04 more
  • 【C++犯錯記錄】VS2019 MFC添加資源不懂如何修改資源宏ID

    1. 首先在資源視圖中,添加資源 2. 點擊新添加的資源,復制自動生成的ID 3. 在解決方案資源管理器中找到Resource.h檔案,編輯,使用整個專案搜索和替換的方式快速替換 宏宣告 4. Ctrl+Shift+F 全域搜索,點擊查找全部,然后逐個替換 5. 為什么使用搜索替換而不使用屬性視窗直 ......

    uj5u.com 2020-09-10 00:59:11 more
  • 【C++犯錯記錄】VS2019 MFC不懂的批量添加資源

    1. 打開資源頭檔案Resource.h,在其中預先定義好宏 ID(不清楚其實ID值應該設定多少,可以先新建一個相同的資源項,再在這個資源的ID值的基礎上遞增即可) 2. 在資源視圖中選中專案資源,按F7編輯資源檔案,按 ID 型別 相對路徑的形式添加 資源。(別忘了先把檔案拷貝到專案中的res檔案 ......

    uj5u.com 2020-09-10 01:00:19 more
  • C/C++編程筆記:關于C++的參考型別,專供新手入門使用

    今天要講的是C++中我最喜歡的一個用法——參考,也叫別名。 參考就是給一個變數名取一個變數名,方便我們間接地使用這個變數。我們可以給一個變數創建N個參考,這N + 1個變數共享了同一塊記憶體區域。(參考型別的變數會占用記憶體空間,占用的記憶體空間的大小和指標型別的大小是相同的。雖然參考是一個物件的別名,但 ......

    uj5u.com 2020-09-10 01:00:22 more
  • 【C/C++編程筆記】從頭開始學習C ++:初學者完整指南

    眾所周知,C ++的學習曲線陡峭,但是花時間學習這種語言將為您的職業帶來奇跡,并使您與其他開發人員區分開。您會更輕松地學習新語言,形成真正的解決問題的技能,并在編程的基礎上打下堅實的基礎。 C ++將幫助您養成良好的編程習慣(即清晰一致的編碼風格,在撰寫代碼時注釋代碼,并限制類內部的可見性),并且由 ......

    uj5u.com 2020-09-10 01:00:41 more
最新发布
  • Rust中的智能指標:Box<T> Rc<T> Arc<T> Cell<T> RefCell<T> Weak

    Rust中的智能指標是什么 智能指標(smart pointers)是一類資料結構,是擁有資料所有權和額外功能的指標。是指標的進一步發展 指標(pointer)是一個包含記憶體地址的變數的通用概念。這個地址參考,或 ” 指向”(points at)一些其 他資料 。參考以 & 符號為標志并借用了他們所 ......

    uj5u.com 2023-04-20 07:24:10 more
  • Java的值傳遞和參考傳遞

    值傳遞不會改變本身,參考傳遞(如果傳遞的值需要實體化到堆里)如果發生修改了會改變本身。 1.基本資料型別都是值傳遞 package com.example.basic; public class Test { public static void main(String[] args) { int ......

    uj5u.com 2023-04-20 07:24:04 more
  • [2]SpinalHDL教程——Scala簡單入門

    第一個 Scala 程式 shell里面輸入 $ scala scala> 1 + 1 res0: Int = 2 scala> println("Hello World!") Hello World! 檔案形式 object HelloWorld { /* 這是我的第一個 Scala 程式 * 以 ......

    uj5u.com 2023-04-20 07:23:58 more
  • 理解函式指標和回呼函式

    理解 函式指標 指向函式的指標。比如: 理解函式指標的偽代碼 void (*p)(int type, char *data); // 定義一個函式指標p void func(int type, char *data); // 宣告一個函式func p = func; // 將指標p指向函式func ......

    uj5u.com 2023-04-20 07:23:52 more
  • Django筆記二十五之資料庫函式之日期函式

    本文首發于公眾號:Hunter后端 原文鏈接:Django筆記二十五之資料庫函式之日期函式 日期函式主要介紹兩個大類,Extract() 和 Trunc() Extract() 函式作用是提取日期,比如我們可以提取一個日期欄位的年份,月份,日等資料 Trunc() 的作用則是截取,比如 2022-0 ......

    uj5u.com 2023-04-20 07:23:45 more
  • 一天吃透JVM面試八股文

    什么是JVM? JVM,全稱Java Virtual Machine(Java虛擬機),是通過在實際的計算機上仿真模擬各種計算機功能來實作的。由一套位元組碼指令集、一組暫存器、一個堆疊、一個垃圾回收堆和一個存盤方法域等組成。JVM屏蔽了與作業系統平臺相關的資訊,使得Java程式只需要生成在Java虛擬機 ......

    uj5u.com 2023-04-20 07:23:31 more
  • 使用Java接入小程式訂閱訊息!

    更新完微信服務號的模板訊息之后,我又趕緊把微信小程式的訂閱訊息給實作了!之前我一直以為微信小程式也是要企業才能申請,沒想到小程式個人就能申請。 訊息推送平臺🔥推送下發【郵件】【短信】【微信服務號】【微信小程式】【企業微信】【釘釘】等訊息型別。 https://gitee.com/zhongfuch ......

    uj5u.com 2023-04-20 07:22:59 more
  • java -- 緩沖流、轉換流、序列化流

    緩沖流 緩沖流, 也叫高效流, 按照資料型別分類: 位元組緩沖流:BufferedInputStream,BufferedOutputStream 字符緩沖流:BufferedReader,BufferedWriter 緩沖流的基本原理,是在創建流物件時,會創建一個內置的默認大小的緩沖區陣列,通過緩沖 ......

    uj5u.com 2023-04-20 07:22:49 more
  • Java-SpringBoot-Range請求頭設定實作視頻分段傳輸

    老實說,人太懶了,現在基本都不喜歡寫筆記了,但是網上有關Range請求頭的文章都太水了 下面是抄的一段StackOverflow的代碼...自己大修改過的,寫的注釋挺全的,應該直接看得懂,就不解釋了 寫的不好...只是希望能給視頻網站開發的新手一點點幫助吧. 業務場景:視頻分段傳輸、視頻多段傳輸(理 ......

    uj5u.com 2023-04-20 07:22:42 more
  • Windows 10開發教程_編程入門自學教程_菜鳥教程-免費教程分享

    教程簡介 Windows 10開發入門教程 - 從簡單的步驟了解Windows 10開發,從基本到高級概念,包括簡介,UWP,第一個應用程式,商店,XAML控制元件,資料系結,XAML性能,自適應設計,自適應UI,自適應代碼,檔案管理,SQLite資料庫,應用程式到應用程式通信,應用程式本地化,應用程式 ......

    uj5u.com 2023-04-20 07:22:35 more