數獨求解器3.0 增加latex格式讀取

首先說明兩種讀入格式

latex輸入格式說明

\documentclass{article}
\begin{document}This is some text before
```oku.\begin{array}{|l|l|l|l|l|l|l|l|l|}
\hline
```&   &   &   & 5 &   & 2 & 9 \\
\hline&   & 5 &
```1 &   & 7 &   \\ % A comment here
\hline&   & 3 &
```& 8 &   &   \\
\hline& 5 & 2 &   &   &   &
```\\
\hline&   &   & 5 & 7 & 3 &   &   & 8 \\
```ine
3 &   &   &   &   &   &   & 1 & 5 \\
\hline
2 &
```& 5 & 7 &   &   &   \\
\hline&   &   & 6 & 9
```& 3 & 7 \\
\hline& 3 &   & 8 &   &   &
```\\
\hline
\end{array}Or using tabular:\begin{tabular}{|c|c|c
```|c|c|}
\hline
5&3& & &7& & & & \\
\hline
```& &1&9&5& & & \\
\hline
&9&8& & & & &6& \\
```ine
8& & & &6& & & &3\\
\hline
4& & &8& &3& & &
```\hline
7& & & &2& & & &6\\
\hline
&6& & & &
```\
\hline
& & &4&1&9& & &5\\
\hline
&
```& &7&9\\
\hline
\end{tabular}Some text after.\end
```t}

然后是csv讀入格式

csv:
文件內容應該是9行,每行包含9個數字(1-9代表預填數字,0或空單元格代表空格),用逗號分隔。

5,3,0,0
```6,0,0,1,9,5,0,0,0
0
```,6,0
8,0,0,0,6,0,0,0,3
```,0,8,0,3,0,0,1
7,0,0,0,2,0,0
```0,6,0,0,0,0,2,8,0
0,0,0,4,1,
```0,0,0,0,8,0,0,7,9
import tkinter as tk
from tkinter import messagebox, filedialog
import csv
import time
import re  # 導入re模塊,用于正則表達式解析LaTeX# DLXNode, DLX, SudokuDLXSolver 類的代碼保持不變,此處省略以保持簡潔
# ... (粘貼之前的 DLXNode, DLX, SudokuDLXSolver 代碼)
class DLXNode:"""Dancing Links 節點類"""def __init__(self, row_idx=-1, col_idx=-1):self.L = selfself.R = selfself.U = selfself.D = selfself.col_header = selfself.row_idx = row_idxself.col_idx = col_idxself.size = 0class DLX:"""Dancing Links 算法實現"""def __init__(self, num_columns):self.num_columns = num_columnsself.header = DLXNode(col_idx=-1)self.columns = []self.solution = []self.search_steps = 0self.gui_update_callback = Noneself.row_candidates_map = Nonefor j in range(num_columns):col_node = DLXNode(col_idx=j)self.columns.append(col_node)col_node.L = self.header.Lcol_node.R = self.headerself.header.L.R = col_nodeself.header.L = col_nodedef add_row(self, row_elements_indices, row_idx):first_node_in_row = Nonefor col_idx in row_elements_indices:col_header_node = self.columns[col_idx]col_header_node.size += 1new_node = DLXNode(row_idx=row_idx)new_node.col_header = col_header_nodenew_node.U = col_header_node.Unew_node.D = col_header_nodecol_header_node.U.D = new_nodecol_header_node.U = new_nodeif first_node_in_row is None:first_node_in_row = new_nodeelse:new_node.L = first_node_in_row.Lnew_node.R = first_node_in_rowfirst_node_in_row.L.R = new_nodefirst_node_in_row.L = new_nodereturn first_node_in_rowdef _cover(self, target_col_header):target_col_header.R.L = target_col_header.Ltarget_col_header.L.R = target_col_header.Ri_node = target_col_header.Dwhile i_node != target_col_header:j_node = i_node.Rwhile j_node != i_node:j_node.D.U = j_node.Uj_node.U.D = j_node.Dif j_node.col_header:j_node.col_header.size -= 1j_node = j_node.Ri_node = i_node.Ddef _uncover(self, target_col_header):i_node = target_col_header.Uwhile i_node != target_col_header:j_node = i_node.Lwhile j_node != i_node:if j_node.col_header:j_node.col_header.size += 1j_node.D.U = j_nodej_node.U.D = j_nodej_node = j_node.Li_node = i_node.Utarget_col_header.R.L = target_col_headertarget_col_header.L.R = target_col_headerdef search(self):self.search_steps += 1if self.header.R == self.header:return Truec = Nonemin_size = float('inf')current_col = self.header.Rwhile current_col != self.header:if current_col.size < min_size:min_size = current_col.sizec = current_colcurrent_col = current_col.Rif c is None or c.size == 0:return Falseself._cover(c)r_node = c.Dwhile r_node != c:self.solution.append(r_node.row_idx)if self.gui_update_callback and self.row_candidates_map:self.gui_update_callback(r_node.row_idx, 'add', self.row_candidates_map)j_node = r_node.Rwhile j_node != r_node:self._cover(j_node.col_header)j_node = j_node.Rif self.search():return Truepopped_row_idx = self.solution.pop()if self.gui_update_callback and self.row_candidates_map:self.gui_update_callback(popped_row_idx, 'remove', self.row_candidates_map)j_node = r_node.Lwhile j_node != r_node:self._uncover(j_node.col_header)j_node = j_node.Lr_node = r_node.Dself._uncover(c)return Falseclass SudokuDLXSolver:def __init__(self, board_input):self.initial_board = [row[:] for row in board_input]self.size = 9self.box_size = 3self.dlx = DLX(self.size * self.size * 4)self.row_candidates_map = {}def _build_exact_cover_matrix(self):dlx_row_idx = 0for r in range(self.size):for c in range(self.size):for val_candidate in range(1, self.size + 1):if self.initial_board[r][c] == 0 or self.initial_board[r][c] == val_candidate:col_idx_cell = r * self.size + ccol_idx_row = (self.size * self.size) + (r * self.size) + (val_candidate - 1)col_idx_col = (self.size * self.size * 2) + (c * self.size) + (val_candidate - 1)box_r, box_c = r // self.box_size, c // self.box_sizebox_idx = box_r * self.box_size + box_ccol_idx_box = (self.size * self.size * 3) + (box_idx * self.size) + (val_candidate - 1)current_dlx_row_elements = [col_idx_cell, col_idx_row, col_idx_col, col_idx_box]self.dlx.add_row(current_dlx_row_elements, dlx_row_idx)self.row_candidates_map[dlx_row_idx] = (r, c, val_candidate)dlx_row_idx += 1def solve(self, gui_update_callback=None):self._build_exact_cover_matrix()if gui_update_callback:self.dlx.gui_update_callback = gui_update_callbackself.dlx.row_candidates_map = self.row_candidates_mapif self.dlx.search():solution_board = [[0 for _ in range(self.size)] for _ in range(self.size)]for row_idx in self.dlx.solution:r, c, val = self.row_candidates_map[row_idx]solution_board[r][c] = valfor r_init in range(self.size):for c_init in range(self.size):if self.initial_board[r_init][c_init] != 0 and \self.initial_board[r_init][c_init] != solution_board[r_init][c_init]:return Nonereturn solution_boardelse:return Noneclass SudokuGUI:def __init__(self, root):self.root = rootself.root.title("數獨求解器 (DLX) - 玉貓專版")self.cells = [[tk.StringVar() for _ in range(9)] for _ in range(9)]self.entries = [[None for _ in range(9)] for _ in range(9)]self.initial_fill = [[False for _ in range(9)] for _ in range(9)]self.frames = [[tk.Frame(self.root, borderwidth=1, relief="solid")for _ in range(3)] for _ in range(3)]for r_block in range(3):for c_block in range(3):frame = self.frames[r_block][c_block]frame.grid(row=r_block, column=c_block, padx=1, pady=1, sticky="nsew")for r_in_block in range(3):for c_in_block in range(3):r = r_block * 3 + r_in_blockc = c_block * 3 + c_in_blockentry = tk.Entry(frame, textvariable=self.cells[r][c],width=2, font=('Arial', 18, 'bold'), justify='center',borderwidth=1, relief="solid")entry.grid(row=r_in_block, column=c_in_block, padx=1, pady=1, ipady=5, sticky="nsew")self.entries[r][c] = entryvalidate_cmd = (frame.register(self.validate_input), '%P')entry.config(validate="key", validatecommand=validate_cmd)button_frame = tk.Frame(self.root)button_frame.grid(row=3, column=0, columnspan=3, pady=10)solve_button = tk.Button(button_frame, text="求解", command=self.solve_sudoku, font=('Arial', 12))solve_button.pack(side=tk.LEFT, padx=5)clear_button = tk.Button(button_frame, text="清空", command=self.clear_board, font=('Arial', 12))clear_button.pack(side=tk.LEFT, padx=5)example_button = tk.Button(button_frame, text="示例", command=self.load_example, font=('Arial', 12))example_button.pack(side=tk.LEFT, padx=5)csv_button = tk.Button(button_frame, text="從CSV加載", command=self.load_from_csv, font=('Arial', 12))csv_button.pack(side=tk.LEFT, padx=5)# --- 新增: 從LaTeX加載按鈕 ---latex_button = tk.Button(button_frame, text="從LaTeX加載", command=self.load_from_latex, font=('Arial', 12))latex_button.pack(side=tk.LEFT, padx=5)  # 將新按鈕添加到界面info_frame = tk.Frame(self.root)info_frame.grid(row=4, column=0, columnspan=3, pady=5)self.steps_label_var = tk.StringVar()self.steps_label_var.set("探索步數: 0")steps_display_label = tk.Label(info_frame, textvariable=self.steps_label_var, font=('Arial', 10))steps_display_label.pack()self.visualization_delay = 0.005def validate_input(self, P):if P == "" or (P.isdigit() and len(P) == 1 and P != '0'):return Truereturn Falsedef get_board_from_ui(self):board = [[0 for _ in range(9)] for _ in range(9)]self.initial_fill = [[False for _ in range(9)] for _ in range(9)]try:for r in range(9):for c in range(9):val_str = self.cells[r][c].get()if val_str:val_int = int(val_str)if not (1 <= val_int <= 9):messagebox.showerror("輸入錯誤",f"無效數字 {val_int} 在行 {r + 1}, 列 {c + 1}。只能是1-9。")return Noneboard[r][c] = val_intself.initial_fill[r][c] = Trueelse:board[r][c] = 0except ValueError:messagebox.showerror("輸入錯誤", "請輸入數字 (1-9) 或留空。")return Nonereturn boarddef display_board(self, board_data, solved_color="blue", initial_color="black"):if board_data is None:returnfor r in range(9):for c in range(9):self.cells[r][c].set(str(board_data[r][c]) if board_data[r][c] != 0 else "")if self.initial_fill[r][c]:self.entries[r][c].config(fg=initial_color)elif board_data[r][c] != 0:self.entries[r][c].config(fg=solved_color)else:self.entries[r][c].config(fg=initial_color)def _gui_step_update(self, dlx_row_idx, action, row_candidates_map_ref):if not row_candidates_map_ref or dlx_row_idx not in row_candidates_map_ref:returnr, c, val = row_candidates_map_ref[dlx_row_idx]if self.initial_fill[r][c]:returnif action == 'add':self.cells[r][c].set(str(val))self.entries[r][c].config(fg="orange")elif action == 'remove':self.cells[r][c].set("")self.entries[r][c].config(fg="black")self.root.update_idletasks()if self.visualization_delay > 0:time.sleep(self.visualization_delay)def solve_sudoku(self):self.steps_label_var.set("探索步數: 0")# 在獲取棋盤前,先記錄一次初始填充狀態,確保solve內部的display_board能正確區分# current_ui_board_for_initial_fill = self.get_board_from_ui() # 這會重置initial_fill,不好# 所以 get_board_from_ui 內部必須正確設置 initial_fillboard = self.get_board_from_ui()  # 獲取棋盤,此方法內部會更新 self.initial_fillif board is None:return# 清理之前解出的(非初始)數字的顏色和內容,為可視化做準備for r in range(9):for c in range(9):if not self.initial_fill[r][c]:  # 只處理非初始數字self.cells[r][c].set("")  # 清空內容,以便可視化“填入”的過程self.entries[r][c].config(fg="black")  # 恢復默認顏色all_buttons = []button_container = Nonefor child in self.root.winfo_children():if isinstance(child, tk.Frame):try:  # 使用try-except避免grid_info()對pack布局的Frame報錯if child.grid_info()['row'] == '3':button_container = childbreakexcept tk.TclError:  # 如果frame是pack布局的,grid_info()會失敗# 可以通過其他方式識別,例如檢查其子控件是否都是按鈕is_button_bar = Trueif not child.winfo_children(): is_button_bar = False  # 空Frame不是for sub_child in child.winfo_children():if not isinstance(sub_child, tk.Button):is_button_bar = Falsebreakif is_button_bar and child.winfo_children():  # 確保有按鈕# 這里的假設是按鈕欄是第一個被pack的Frame (除了格子Frame)# 這依賴于pack的順序,更穩妥的方式是給button_frame一個name屬性if child.winfo_children()[0].winfo_class() == 'Button':  # 粗略判斷button_container = childbreakif button_container:for btn_widget in button_container.winfo_children():  # 改變量名避免與外層btn沖突if isinstance(btn_widget, tk.Button):btn_widget.config(state=tk.DISABLED)all_buttons.append(btn_widget)  # all_buttons現在是控件列表self.root.update_idletasks()solver = SudokuDLXSolver(board)  # 使用已經通過get_board_from_ui得到的boardsolution = solver.solve(gui_update_callback=self._gui_step_update)if button_container:  # 恢復按鈕for btn_widget in button_container.winfo_children():if isinstance(btn_widget, tk.Button):btn_widget.config(state=tk.NORMAL)self.steps_label_var.set(f"探索步數: {solver.dlx.search_steps}")if solution:# self.initial_fill 需要在display_board時是正確的,它由get_board_from_ui()設置self.display_board(solution)messagebox.showinfo("成功", "數獨已解決!")else:messagebox.showinfo("無解", "未能找到此數獨的解。")# 清理盤面,只留下初始數字current_initial_board = [[val if self.initial_fill[r][c] else 0 for c, val in enumerate(row)] for r, row inenumerate(self.get_board_from_ui())]  # 重新獲取,以防萬一# 上面這行邏輯復雜了,直接用 self.initial_board (SudokuSolver內部存的) 或者重新構造# self.display_board(solver.initial_board) # 顯示最初的盤面for r in range(9):for c in range(9):if not self.initial_fill[r][c]:  # 只處理非初始數字self.cells[r][c].set("")self.entries[r][c].config(fg="black")else:  # 確保初始數字顏色正確,以防萬一在可視化過程中被更改self.entries[r][c].config(fg="black")def clear_board(self):for r in range(9):for c in range(9):self.cells[r][c].set("")self.entries[r][c].config(fg="black")self.initial_fill[r][c] = Falseself.steps_label_var.set("探索步數: 0")def load_example(self):self.clear_board()example_board = [[5, 3, 0, 0, 7, 0, 0, 0, 0], [6, 0, 0, 1, 9, 5, 0, 0, 0], [0, 9, 8, 0, 0, 0, 0, 6, 0],[8, 0, 0, 0, 6, 0, 0, 0, 3], [4, 0, 0, 8, 0, 3, 0, 0, 1], [7, 0, 0, 0, 2, 0, 0, 0, 6],[0, 6, 0, 0, 0, 0, 2, 8, 0], [0, 0, 0, 4, 1, 9, 0, 0, 5], [0, 0, 0, 0, 8, 0, 0, 7, 9]]for r in range(9):for c in range(9):if example_board[r][c] != 0:self.cells[r][c].set(str(example_board[r][c]))self.initial_fill[r][c] = Trueself.entries[r][c].config(fg="black")def load_from_csv(self):self.clear_board()file_path = filedialog.askopenfilename(title="選擇CSV數獨文件",filetypes=(("CSV 文件", "*.csv"), ("所有文件", "*.*")))if not file_path:returnnew_board = []try:with open(file_path, 'r', newline='') as csvfile:reader = csv.reader(csvfile)for row_idx, row in enumerate(reader):if row_idx >= 9:  # 最多讀9行messagebox.showwarning("CSV警告", f"文件 '{file_path}' 行數超過9行,只處理前9行。")breakif len(row) != 9:messagebox.showerror("CSV錯誤", f"文件 '{file_path}' 中的行 {row_idx + 1} 數據不符合9列標準。")self.clear_board()returncurrent_row = []for val_str in row:val_str_cleaned = val_str.strip()if not val_str_cleaned or val_str_cleaned == '0':current_row.append(0)elif val_str_cleaned.isdigit() and 1 <= int(val_str_cleaned) <= 9:current_row.append(int(val_str_cleaned))else:messagebox.showerror("CSV錯誤",f"文件 '{file_path}' 包含無效字符 '{val_str}'。請使用0-9或空格/空。")self.clear_board()returnnew_board.append(current_row)if len(new_board) != 9:messagebox.showerror("CSV錯誤", f"文件 '{file_path}' 未能構成完整的9行數據。實際行數: {len(new_board)}。")self.clear_board()returnfor r in range(9):for c in range(9):if new_board[r][c] != 0:self.cells[r][c].set(str(new_board[r][c]))self.initial_fill[r][c] = Trueself.entries[r][c].config(fg="black")except FileNotFoundError:messagebox.showerror("錯誤", f"文件 '{file_path}' 未找到。")self.clear_board()except Exception as e:messagebox.showerror("讀取錯誤", f"讀取CSV文件時發生錯誤: {e}")self.clear_board()# --- 新增: 從LaTeX array加載數獨的方法 ---def load_from_latex(self):"""從包含LaTeX array環境的文本文件加載數獨棋盤"""self.clear_board()  # 清空當前棋盤file_path = filedialog.askopenfilename(title="選擇LaTeX數獨文件",# 允許.tex和純文本文件filetypes=(("LaTeX 文件", "*.tex"), ("文本文件", "*.txt"), ("所有文件", "*.*")))if not file_path:  # 如果用戶取消選擇returnnew_board = []  # 用于存儲從LaTeX解析出的棋盤數據try:with open(file_path, 'r', encoding='utf-8') as f:  # 使用utf-8編碼打開文件content = f.read()# 1. 使用正則表達式查找 array 環境內容#    這個正則表達式會匹配 \begin{array}{...} ... \end{array}#    re.DOTALL 使得 . 可以匹配換行符match = re.search(r"\\begin\{array\}.*?\n(.*?)%?\s*\\end\{array\}", content, re.DOTALL | re.IGNORECASE)if not match:match = re.search(r"\\begin\{tabular\}.*?\n(.*?)%?\s*\\end\{tabular\}", content,re.DOTALL | re.IGNORECASE)  # 也嘗試tabularif not match:messagebox.showerror("LaTeX錯誤", f"在文件 '{file_path}' 中未找到 'array' 或 'tabular' 環境。")returnarray_content = match.group(1).strip()  # 獲取括號內的匹配內容,并去除首尾空格# 2. 逐行解析array內容lines = array_content.splitlines()  # 按行分割board_rows = 0for line_idx, line_str in enumerate(lines):line_str = line_str.strip()if not line_str or line_str.lower().startswith(r"\hline"):  # 忽略空行和 \hlinecontinueif board_rows >= 9:  # 最多處理9行數據messagebox.showwarning("LaTeX警告",f"文件 '{file_path}' array/tabular環境內數據行超過9行,只處理前9行。")break# 移除行尾的 \\ 和可能存在的注釋 %...line_str = re.sub(r"%.*$", "", line_str)  # 移除注釋line_str = line_str.replace(r"\\", "").strip()  # 移除 \\ 并再次stripcells_str = line_str.split('&')  # 按 & 分割單元格if len(cells_str) != 9:messagebox.showerror("LaTeX錯誤",f"文件 '{file_path}' 中array/tabular的第 {line_idx + 1} 數據行 (內容: '{line_str[:30]}...') 不包含9個單元格 (實際: {len(cells_str)})。")self.clear_board()returncurrent_row = []for cell_content in cells_str:cell_content_cleaned = cell_content.strip()# 嘗試移除常見的LaTeX大括號如 {1} -> 1braced_match = re.fullmatch(r"\{(.)\}", cell_content_cleaned)if braced_match:cell_content_cleaned = braced_match.group(1)if not cell_content_cleaned:  # 空單元格current_row.append(0)elif cell_content_cleaned.isdigit() and 1 <= int(cell_content_cleaned) <= 9:current_row.append(int(cell_content_cleaned))else:  # 非數字或無效數字,視為0或錯誤# 如果希望更嚴格,可以報錯:# messagebox.showerror("LaTeX錯誤", f"單元格內容 '{cell_content}' 無效。")# self.clear_board()# returncurrent_row.append(0)  # 這里選擇將其視為0new_board.append(current_row)board_rows += 1if board_rows != 9:messagebox.showerror("LaTeX錯誤",f"文件 '{file_path}' 未能從array/tabular環境解析出完整的9行數據。實際解析行數: {board_rows}。")self.clear_board()return# 3. 將解析到的棋盤數據加載到GUIfor r in range(9):for c in range(9):if new_board[r][c] != 0:self.cells[r][c].set(str(new_board[r][c]))self.initial_fill[r][c] = Trueself.entries[r][c].config(fg="black")except FileNotFoundError:messagebox.showerror("錯誤", f"文件 '{file_path}' 未找到。")self.clear_board()except Exception as e:messagebox.showerror("讀取錯誤", f"讀取或解析LaTeX文件時發生錯誤: {e}")self.clear_board()if __name__ == "__main__":main_root = tk.Tk()app = SudokuGUI(main_root)main_root.mainloop()

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/81772.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/81772.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/81772.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

20250520在全志H3平臺的Nano Pi NEO CORE開發板上運行Ubuntu Core16.04.3時跑通4G模塊EC20

1、h3-sd-friendlycore-xenial-4.14-armhf-20210618.img.gz 在WIN10下使用7-ZIP解壓縮/ubuntu20.04下使用tar 2、Win32DiskImager.exe 寫如32GB的TF卡。【以管理員身份運行】 3、TF卡如果已經做過會有3個磁盤分區&#xff0c;可以使用SD Card Formatter/SDCardFormatterv5_WinE…

精益數據分析(74/126):從愿景到落地的精益開發路徑——Rally的全流程管理實踐

精益數據分析&#xff08;74/126&#xff09;&#xff1a;從愿景到落地的精益開發路徑——Rally的全流程管理實踐 在創業的黏性階段&#xff0c;如何將抽象的愿景轉化為可落地的產品功能&#xff1f;如何在快速迭代中保持戰略聚焦&#xff1f;今天&#xff0c;我們通過Rally軟…

Javascript 編程基礎(4)函數 | 4.3、apply() 與 call() 方法

文章目錄 一、apply() 與 call() 方法1、核心概念1.1、call() 方法1.2、apply() 方法 2、使用示例2.1、基本用法2.2、處理 this 指向問題 3、call() 與 apply() 的區別 一、apply() 與 call() 方法 apply() 和 call() 都是 JavaScript 函數對象的方法&#xff0c;用于顯式設置函…

讀一本書第一遍是快讀還是細讀?

在時間充足且計劃對重要書籍進行多遍閱讀的前提下&#xff0c;第一遍閱讀的策略可以結合**「快讀搭建框架」與「標記重點」**&#xff0c;為后續細讀奠定基礎。以下是具體建議及操作邏輯&#xff1a; 一、第一遍&#xff1a;快讀為主&#xff0c;目標是「建立全局認知」 1. 快…

基于大模型的全面驚厥性癲癇持續狀態技術方案

目錄 一、數據收集與預處理系統1.1 多模態數據集成模塊1.2 數據預處理流程二、大模型構建與訓練系統2.1 模型架構設計2.2 訓練流程三、術前評估系統3.1 癲癇發作風險預測3.2 手術可行性評估流程四、術中決策支持系統4.1 實時監測數據處理4.2 麻醉方案優化流程五、術后護理系統5…

React 19 中的useRef得到了進一步加強。

文章目錄 前言一 useRef 的核心原理1.1 為什么需要 useRef&#xff1f;1.2 基本語法 二、React 19 中 useRef 的常見用法2.1 訪問 DOM 元素2.2 保存跨渲染的數據 三、React 19 中的改進ref 作為一個屬性案例演示(觸發子組件焦點事件) 注意 總結 前言 在 React 的世界里&#x…

idea查看class文件源碼

1、在idea中查看.class文件源碼 在idea的一個工程里面將.class文件復制進去&#xff0c;會提示如下&#xff1a; 這時候&#xff0c;打開一個其他類&#xff0c;右鍵-》"show in explorer"&#xff0c;打開資源文件夾&#xff0c;這時候將class文件粘貼在此處&#…

基于 Vue + CEF3 的瀏覽器批量管理系統(附功能詳解)

&#x1f310; 基于 Vue CEF3 的瀏覽器批量管理系統&#xff08;附功能詳解&#xff09; 在當前多任務操作需求日益增長的背景下&#xff0c;如何高效管理多個瀏覽器實例成為了一個值得探討的問題。今天給大家介紹一款基于 Vue 和 CEF3 構建的瀏覽器批量管理系統&#xff0c;…

JS實現古詩豎排從右至左

一個老題目&#xff0c;將下面古詩文由橫排&#xff0c;變成古文豎排模式&#xff1a; 靜夜思 李白 床前明月光&#xff0c; 疑似地上霜。 舉頭望明月&#xff0c; 低頭思故鄉。變成&#xff1a; 低|舉|疑|床|靜 頭|頭|似|前|夜 思|望|地|明|思 故|明|上|月| 鄉|月|霜|光|李…

在 Android 中實現支持多手勢交互的自定義 View(Kotlin 完整指南)

本文將手把手教你創建一個支持拖動、縮放、旋轉等多種手勢交互的自定義 View&#xff0c;并提供完整的代碼實現和優化建議。 一、基礎實現 1.1 創建自定義 View 骨架 import android.content.Context import android.graphics.* import android.util.AttributeSet import an…

Kotlin 協程 (一)

1. Kotlin 協程的核心概念 1.1 協程&#xff08;Coroutine&#xff09; 定義&#xff1a;協程是一種輕量級的執行上下文&#xff0c;可以在任何時候掛起和恢復&#xff0c;而不需要阻塞線程。特點&#xff1a; 比傳統線程更輕量&#xff0c;開銷更小。支持掛起和恢復&#xf…

機器學習 集成學習方法之隨機森林

集成學習方法之隨機森林 1 集成學習2 隨機森林的算法原理2.1 Sklearn API2.2 示例 1 集成學習 機器學習中有一種大類叫集成學習&#xff08;Ensemble Learning&#xff09;&#xff0c;集成學習的基本思想就是將多個分類器組合&#xff0c;從而實現一個預測效果更好的集成分類…

thinkphp6實現統一監聽并記錄所有執行的sql語句除查詢外

創建文件app/middleware/SqlLogger.php <?php namespace app\middleware;use think\facade\Db; use think\facade\Session;class SqlLogger {public function handle($request, \Closure $next){// 監聽所有SQL $request->ip()Db::listen(function($sql, $time) {if (p…

pytorch訓練可視化工具---TensorBoard

一、目的&#xff1a;為什么使用 TensorBoard 調控模型 使用 TensorBoard 可以幫我們&#xff1a; 實時查看 loss / acc 曲線 → 判斷是否過擬合、欠擬合&#xff1b; 對比不同模型或超參數的效果&#xff1b; 可視化模型結構 → 幫助調試模型設計&#xff1b; 查看權重/梯…

機器學習知識自然語言處理入門

一、引言&#xff1a;當文字遇上數學 —— 自然語言的數字化革命 在自然語言處理&#xff08;NLP&#xff09;的世界里&#xff0c;計算機要理解人類語言&#xff0c;首先需要將文字轉化為數學向量。早期的 One-Hot 編碼如同給每個詞語分配一個唯一的 “房間號”&#xff0c;例…

Linux-線程概念和控制

1.Linux線程概念 1.1什么是線程 ? 在?個程序?的?個執?路線就叫做線程&#xff08;thread&#xff09;。更準確的定義是&#xff1a;線程是“?個進程內部 的控制序列” ? ?切進程?少都有?個執?線程 ? 線程在進程內部運?&#xff0c;本質是在進程地址空間內運?…

【氮化鎵】低劑量率對GaN HEMT柵極漏電的影響

2024 年 2 月 22 日,中國科學院新疆理化技術研究所的Li等人在《IEEE ACCESS》期刊發表了題為《Degradation Mechanisms of Gate Leakage in GaN-Based HEMTs at Low Dose Rate Irradiation》的文章,基于實驗分析和 TCAD 仿真,研究了低劑量率輻照下基于 GaN 的 p 型柵高電子遷…

.NET Core 中 Swagger 配置詳解:常用配置與實戰技巧

隨著微服務架構和 RESTful API 的廣泛應用&#xff0c;API 文檔的管理和自動化生成成為了開發中的重要部分。Swagger&#xff08;現為 OpenAPI&#xff09;是一款功能強大的工具&#xff0c;它可以自動生成 API 文檔&#xff0c;并提供交互式 UI&#xff0c;幫助開發者、測試人…

海康工業相機白平衡比選擇器對應的值被重置后,如何恢復原成像

做項目的時候&#xff0c;有時候手抖&#xff0c;一不小心把一個成熟穩定的項目的相機配置&#xff0c;重置了&#xff0c;如何進行恢復呢&#xff0c;在不知道之前配置數據的情況下。 我在做項目的時候&#xff0c;為了讓這個相機成像穩定一點&#xff0c;尤其是做顏色檢測時…

【八股戰神篇】Java虛擬機(JVM)高頻面試題

目錄 專欄簡介 一 請解釋Java虛擬機(JVM)及其主要功能 延伸 1. JVM的基本概念 2. JVM的主要功能 二 對象創建的過程了解嗎 延伸 1.Java 創建對象的四種常見方式 三 什么是雙親委派模型 延伸 1.雙親委派機制的作用: 2.雙親委派模型的核心思想: 3.雙親委派模型的…