Algorithms—140.Word Break II

本文介绍了一种使用动态规划方法解决单词拆分问题的算法实现。通过递归调用和缓存中间结果来避免重复计算,提高了算法效率。文章详细展示了如何利用两个哈希表分别记录已知可行的单词组合及无法分解的字符串。

思路:动态规划,很简单,就是写的比较糟糕,而且好多逻辑错误判定是time limit。。也是蛋疼。注意用一个新map存储走不通的路径。

public class Solution {
	Map<String,List<String>> map=new HashMap<String, List<String>>();
	Map<String,Boolean> bmap=new HashMap<String, Boolean>();
    public List<String> wordBreak(String s, Set<String> wordDict) {
    	List<String> list=new ArrayList<String>();
    	if(s==null||s.length()==0){
    		return list;
    	}
    	if (map.get(s)!=null) {
			return map.get(s);
		}
    	if(bmap.get(s)!=null){
    		return null;
    	}
    	for (int i = 0; i < s.length()-1; i++) {
			String k=s.substring(0,i+1);
			if(wordDict.contains(k)){
				String t=s.substring(i+1,s.length());
				if(bmap.get(t)==null){
					List<String> l=map.get(t);
					if (l!=null) {
						for (int j = 0; j < l.size(); j++) {
							list.add(k+" "+l.get(j));
						}
					}else {
						List<String> a=wordBreak(t,wordDict);
						if (a!=null) {
							for (int j = 0; j < a.size(); j++) {
								list.add(k+" "+a.get(j));
							}
						}
					}
				}
			}
		}
    	if(wordDict.contains(s)){
    		list.add(s);
    	}
    	if (list.size()==0) {
    		bmap.put(s, false);
			return list;
		}
    	map.put(s, list);
    	return list;
    }
}



import tkinter as tk from tkinter import ttk, messagebox, filedialog import socket import threading import struct import os from cryptography.hazmat.primitives.asymmetric import rsa, padding from cryptography.hazmat.primitives import serialization, hashes from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes from cryptography.hazmat.backends import default_backend class SecureServer: def __init__(self, root): self.root = root self.root.title("安全通信服务器") self.root.geometry("600x500") self.session_key = None # 生成RSA密钥对 self.private_key = rsa.generate_private_key( public_exponent=65537, key_size=2048, backend=default_backend() ) self.public_key = self.private_key.public_key() # 界面布局 self.create_widgets() self.server_socket = None self.client_socket = None self.running = False def create_widgets(self): # 服务器控制区域 control_frame = ttk.Frame(self.root, padding=10) control_frame.pack(fill=tk.X) ttk.Label(control_frame, text="端口:").grid(row=0, column=0, padx=5) self.port_entry = ttk.Entry(control_frame, width=10) self.port_entry.grid(row=0, column=1, padx=5) self.port_entry.insert(0, "12345") self.start_btn = ttk.Button(control_frame, text="启动服务器", command=self.start_server) self.start_btn.grid(row=0, column=2, padx=5) self.stop_btn = ttk.Button(control_frame, text="停止服务器", command=self.stop_server, state=tk.DISABLED) self.stop_btn.grid(row=0, column=3, padx=5) # 状态显示 status_frame = ttk.LabelFrame(self.root, text="服务器状态", padding=10) status_frame.pack(fill=tk.X, padx=10, pady=5) self.status_text = tk.Text(status_frame, height=8, width=70) self.status_text.pack(fill=tk.BOTH, expand=True) self.status_text.config(state=tk.DISABLED) # 文件接收区域 file_frame = ttk.LabelFrame(self.root, text="接收文件", padding=10) file_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=5) self.file_list = ttk.Treeview(file_frame, columns=("size", "status"), show="headings") self.file_list.heading("#0", text="文件名") self.file_list.heading("size", text="大小") self.file_list.heading("status", text="状态") self.file_list.column("#0", width=200) self.file_list.column("size", width=100) self.file_list.column("status", width=100) self.file_list.pack(fill=tk.BOTH, expand=True, pady=5) self.save_btn = ttk.Button(file_frame, text="保存文件", command=self.save_file, state=tk.DISABLED) self.save_btn.pack(pady=5) # 消息区域 msg_frame = ttk.LabelFrame(self.root, text="消息", padding=10) msg_frame.pack(fill=tk.X, padx=10, pady=5) self.msg_entry = ttk.Entry(msg_frame) self.msg_entry.pack(side=tk.LEFT, fill=tk.X, expand=True, padx=5) self.send_btn = ttk.Button(msg_frame, text="发送", command=self.send_message, state=tk.DISABLED) self.send_btn.pack(side=tk.RIGHT, padx=5) def log(self, message): self.status_text.config(state=tk.NORMAL) self.status_text.insert(tk.END, message + "\n") self.status_text.see(tk.END) self.status_text.config(state=tk.DISABLED) def start_server(self): port = int(self.port_entry.get()) try: self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.server_socket.bind(('', port)) self.server_socket.listen(1) self.running = True threading.Thread(target=self.accept_connections, daemon=True).start() self.log(f"服务器已启动,监听端口 {port}") self.start_btn.config(state=tk.DISABLED) self.stop_btn.config(state=tk.NORMAL) except Exception as e: messagebox.showerror("错误", f"启动服务器失败: {str(e)}") def stop_server(self): self.running = False try: if self.client_socket: self.client_socket.close() if self.server_socket: self.server_socket.close() self.log("服务器已停止") except: pass self.start_btn.config(state=tk.NORMAL) self.stop_btn.config(state=tk.DISABLED) self.send_btn.config(state=tk.DISABLED) self.save_btn.config(state=tk.DISABLED) def accept_connections(self): while self.running: try: self.log("等待客户端连接...") self.client_socket, addr = self.server_socket.accept() self.log(f"客户端已连接: {addr[0]}:{addr[1]}") # 发送公钥给客户端 pubkey_bytes = self.public_key.public_bytes( encoding=serialization.Encoding.PEM, format=serialization.PublicFormat.SubjectPublicKeyInfo ) self.send_data(self.client_socket, 0x01, pubkey_bytes) self.log("已发送服务器公钥") # 接收会话密钥 _, enc_session_key = self.recv_data(self.client_socket) self.session_key = self.private_key.decrypt( enc_session_key, padding.OAEP( mgf=padding.MGF1(algorithm=hashes.SHA256()), algorithm=hashes.SHA256(), label=None ) ) self.log("已接收并解密会话密钥") self.send_btn.config(state=tk.NORMAL) threading.Thread(target=self.receive_data, daemon=True).start() except Exception as e: if self.running: self.log(f"连接错误: {str(e)}") break def send_data(self, sock, msg_type, data): header = struct.pack('!BI', msg_type, len(data)) sock.sendall(header + data) def recv_data(self, sock): header = sock.recv(5) if not header: return None, None msg_type, length = struct.unpack('!BI', header) data = b'' while len(data) < length: packet = sock.recv(length - len(data)) if not packet: break data += packet return msg_type, data def receive_data(self): while self.running: try: msg_type, data = self.recv_data(self.client_socket) if msg_type is None: break if msg_type == 0x03: # 文本消息 iv = data[:12] tag = data[12:28] ciphertext = data[28:] cipher = Cipher(algorithms.AES(self.session_key), modes.GCM(iv, tag), backend=default_backend()) decryptor = cipher.decryptor() message = decryptor.update(ciphertext) + decryptor.finalize() self.log(f"客户端: {message.decode()}") elif msg_type == 0x04: # 文件元数据 iv = data[:12] tag = data[12:28] ciphertext = data[28:] cipher = Cipher(algorithms.AES(self.session_key), modes.GCM(iv, tag), backend=default_backend()) decryptor = cipher.decryptor() meta = decryptor.update(ciphertext) + decryptor.finalize() filename, filesize = meta.decode().split('|') self.receiving_file = { 'name': filename, 'size': int(filesize), 'data': b'', 'received': 0 } self.file_list.insert("", "end", text=filename, values=(f"{int(filesize)/1024:.1f} KB", "传输中")) self.save_btn.config(state=tk.DISABLED) self.log(f"开始接收文件: {filename} ({filesize} 字节)") elif msg_type == 0x05: # 文件数据 iv = data[:12] tag = data[12:28] ciphertext = data[28:] cipher = Cipher(algorithms.AES(self.session_key), modes.GCM(iv, tag), backend=default_backend()) decryptor = cipher.decryptor() file_data = decryptor.update(ciphertext) + decryptor.finalize() self.receiving_file['data'] += file_data self.receiving_file['received'] += len(file_data) # 更新进度 progress = self.receiving_file['received'] / self.receiving_file['size'] * 100 for item in self.file_list.get_children(): if self.file_list.item(item, "text") == self.receiving_file['name']: self.file_list.item(item, values=(f"{self.receiving_file['size']/1024:.1f} KB", f"{progress:.1f}%")) # 文件接收完成 if self.receiving_file['received'] >= self.receiving_file['size']: self.receiving_file['data'] = self.receiving_file['data'][:self.receiving_file['size']] for item in self.file_list.get_children(): if self.file_list.item(item, "text") == self.receiving_file['name']: self.file_list.item(item, values=(f"{self.receiving_file['size']/1024:.1f} KB", "已接收")) self.save_btn.config(state=tk.NORMAL) self.log(f"文件接收完成: {self.receiving_file['name']}") except Exception as e: if self.running: self.log(f"接收错误: {str(e)}") break def send_message(self): message = self.msg_entry.get() if not message or not self.client_socket: return try: iv = os.urandom(12) cipher = Cipher(algorithms.AES(self.session_key), modes.GCM(iv), backend=default_backend()) encryptor = cipher.encryptor() ciphertext = encryptor.update(message.encode()) + encryptor.finalize() tag = encryptor.tag data = iv + tag + ciphertext self.send_data(self.client_socket, 0x03, data) self.log(f"服务器: {message}") self.msg_entry.delete(0, tk.END) except Exception as e: self.log(f"发送消息失败: {str(e)}") def save_file(self): if not hasattr(self, 'receiving_file') or not self.receiving_file['data']: return file_path = filedialog.asksaveasfilename( initialfile=self.receiving_file['name'], filetypes=[("所有文件", "*.*")] ) if file_path: try: with open(file_path, 'wb') as f: f.write(self.receiving_file['data']) self.log(f"文件已保存: {file_path}") except Exception as e: messagebox.showerror("错误", f"保存文件失败: {str(e)}") if __name__ == "__main__": root = tk.Tk() app = SecureServer(root) root.mainloop() 请根据上面的代码再加上我上面所述的要求,重新修改服务端代码
最新发布
08-28
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值