做时时彩开奖网站犯法吗/seo的全称是什么
本文目录
- 03 栈 Stack
- S1 说明
- S2 示例
- 基于列表的实现
- 基于链表的实现
- S3 问题:复杂嵌套结构的括号匹配问题
- 求解思路
- Python3程序
- S4 问题:基于栈的阶乘计算VS递归实现
- 求解思路
- Python3程序
- S5 问题:逆波兰表示法(后缀表达式)求值
- 求解思路
- Python3程序
往期链接
01 数组 | 02 链表 |
---|
03 栈 Stack
S1 说明
栈是一种线性数据结构,具有后进先出(LIFO, Last In First Out)的特点。栈的主要操作包括插入(压栈)和删除(弹栈),这些操作只能在栈的顶端进行。
基本操作
- 压栈(Push):将一个元素添加到栈顶。
- 弹栈(Pop):从栈顶移除并返回一个元素。
- 查看栈顶元素(Peek/Top):返回栈顶元素,但不删除它。
- 检查栈是否为空(IsEmpty):判断栈中是否还有元素。
- 获取栈的大小(Size):返回栈中元素的数量。
性质
- 后进先出(LIFO):最后压入栈的元素最先弹出。
- 只能在栈顶进行操作,无法直接访问栈中间或底部的元素。
S2 示例
基于列表的实现
class Stack:def __init__(self):self.items = [] # 使用列表存储栈元素def push(self, item):"""压栈操作"""self.items.append(item)def pop(self):"""弹栈操作"""if not self.is_empty():return self.items.pop()raise IndexError("弹栈失败,栈为空")def peek(self):"""查看栈顶元素"""if not self.is_empty():return self.items[-1]raise IndexError("查看栈顶元素失败,栈为空")def is_empty(self):"""检查栈是否为空"""return len(self.items) == 0def size(self):"""获取栈的大小"""return len(self.items)# 使用示例
if __name__ == "__main__":stack = Stack()stack.push(1)stack.push(2)stack.push(3)print("栈顶元素:", stack.peek()) # 输出 3print("弹出元素:", stack.pop()) # 输出 3print("当前栈大小:", stack.size()) # 输出 2
输出
栈顶元素: 3
弹出元素: 3
当前栈大小: 2
基于链表的实现
class Node:"""链表节点类"""def __init__(self, value):self.value = value # 节点存储的值self.next = None # 指向下一个节点的指针class LinkedListStack:"""基于链表的栈类"""def __init__(self):self.top = None # 栈顶指针def push(self, value):"""压栈操作"""new_node = Node(value) # 创建新节点new_node.next = self.top # 新节点指向当前栈顶self.top = new_node # 更新栈顶为新节点def pop(self):"""弹栈操作"""if self.is_empty():raise IndexError("弹栈失败,栈为空")popped_value = self.top.value # 保存栈顶值self.top = self.top.next # 更新栈顶为下一个节点return popped_value # 返回弹出的值def peek(self):"""查看栈顶元素"""if self.is_empty():raise IndexError("查看栈顶元素失败,栈为空")return self.top.value # 返回栈顶值def is_empty(self):"""检查栈是否为空"""return self.top is None # 栈顶指针为空则栈为空def size(self):"""获取栈的大小"""count = 0current = self.topwhile current:count += 1current = current.nextreturn count# 使用示例
if __name__ == "__main__":stack = LinkedListStack()stack.push(10)stack.push(20)stack.push(30)print("栈顶元素:", stack.peek()) # 输出 30print("弹出元素:", stack.pop()) # 输出 30print("当前栈大小:", stack.size()) # 输出 2print("栈是否为空:", stack.is_empty()) # 输出 False# 弹出剩余元素print("弹出元素:", stack.pop()) # 输出 20print("弹出元素:", stack.pop()) # 输出 10print("栈是否为空:", stack.is_empty()) # 输出 True
输出
栈顶元素: 30
弹出元素: 30
当前栈大小: 2
栈是否为空: False
弹出元素: 20
弹出元素: 10
栈是否为空: True
S3 问题:复杂嵌套结构的括号匹配问题
括号匹配问题是一个在算法和数据结构中常见的问题,主要目标是通过检查输入的括号序列是否平衡和闭合,以确定它们是否匹配。这个问题涉及到各种类型的括号,如圆括号、花括号和大括号。
括号匹配问题的核心在于检查输入的括号序列中的左括号和右括号是否能够正确配对,并且配对的顺序是否正确。例如,在算术表达式中,需要确保每一个左括号(如“(”或“[”)都有一个相应的右括号(如“)”或“]”)来闭合它,并且这些括号必须按照正确的顺序闭合。如果输入的括号序列无法满足这些条件,则称该序列不匹配。
要判断的括号字符串:
expressions = ["({[()]}{[()]})", # 匹配"{([()][()])}{[()]()}", # 匹配"({[()]}{[(])})", # 不匹配"({[()]}([]{}))" # 不匹配
]
求解思路
- 使用一个栈(用Python的列表实现)来跟踪开放的括号。
- 定义开放括号和闭合括号的集合,以及一个配对字典。
- 遍历输入字符串中的每个字符:
- 如果是开放括号,将其推入栈中。
- 如果是闭合括号,检查栈是否为空(如果为空,则不平衡),然后检查栈顶元素是否与当前闭合括号匹配。如果匹配,则弹出栈顶元素;如果不匹配,则表达式不平衡。
- 最后,如果栈为空,则表达式平衡;否则不平衡。
Python3程序
def is_balanced(expression):# 初始化一个空栈,用于存储开放括号stack = []# 定义开放括号的集合opening = "({["# 定义闭合括号的集合closing = ")}]"# 定义括号对应关系的字典pairs = {")": "(", "}": "{", "]": "["}# 遍历表达式中的每个字符for char in expression:# 如果是开放括号,将其压入栈中if char in opening:stack.append(char)# 如果是闭合括号elif char in closing:# 如果栈为空,说明闭合括号没有对应的开放括号,返回Falseif not stack:return False# 如果栈顶的开放括号与当前闭合括号匹配if stack[-1] == pairs[char]:# 弹出栈顶元素stack.pop()else:# 如果不匹配,返回Falsereturn False# 遍历结束后,如果栈为空,说明所有括号都匹配,返回True;否则返回Falsereturn len(stack) == 0# 测试样例
expressions = ["({[()]}{[()]})", # 匹配"{([()][()])}{[()]()}", # 匹配"({[()]}{[(])})", # 不匹配"({[()]}([]{}))" # 不匹配
]# 遍历所有测试样例
for expr in expressions:# 调用is_balanced函数检查是否平衡,并打印结果print(f"'{expr}'是{'匹配的' if is_balanced(expr) else '不匹配的'}")
输出
'({[()]}{[()]})'是匹配的
'{([()][()])}{[()]()}'是匹配的
'({[()]}{[(])})'是不匹配的
'({[()]}([]{}))'是匹配的
S4 问题:基于栈的阶乘计算VS递归实现
求解思路
使用栈实现的非递归版本。它的工作原理如下:
- 初始化一个栈和结果变量。
- 将初始值n压入栈中。
- 当栈不为空时,循环处理:
- 弹出栈顶元素。
- 如果是0或1,直接继续(因为0!和1!都等于1)。
- 否则,将当前值乘到结果中,并将下一个要处理的值(当前值-1)压入栈中。
- 循环结束后,返回最终结果。
Python3程序
# 递归版本的阶乘计算
def factorial_recursive(n):if n == 0 or n == 1:return 1else:return n * factorial_recursive(n - 1)# 使用栈的非递归版本的阶乘计算
def factorial_iterative(n):# 初始化一个栈来模拟递归调用stack = []result = 1# 将初始值压入栈中stack.append(n)# 当栈不为空时,继续处理while stack:# 从栈顶取出当前要处理的值current = stack.pop()if current == 0 or current == 1:# 0!和1!的值都是1,不需要further处理continueelse:# 将当前值乘到结果中result *= current# 将下一个要处理的值压入栈中stack.append(current - 1)return result# 测试两个版本的阶乘函数
test_numbers = [100]print("递归版本结果:")
for num in test_numbers:print(f"{num}! = {factorial_recursive(num)}")print("\n非递归版本结果:")
for num in test_numbers:print(f"{num}! = {factorial_iterative(num)}")
输出
递归版本结果:
100! = 93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000非递归版本结果:
100! = 93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000
S5 问题:逆波兰表示法(后缀表达式)求值
逆波兰表示法(Reverse Polish Notation, RPN)是一种数学表达式的表示方式,其中运算符跟在操作数后面。这种表示法的优点是可以不使用括号来明确运算的优先级,因为操作数的顺序和运算符的顺序自然决定了计算的顺序。逆波兰表示法的特点
- 无括号:在逆波兰表示法中,运算符总是位于操作数之后,因此不需要括号来改变运算顺序。
- 后进先出(LIFO)原则:通常使用栈来计算逆波兰表达式。操作数被压入栈中,运算符则从栈中弹出操作数进行计算。
为什么要将看似简单的中缀表达式转换为复杂的逆波兰式?原因就在于对计算机而言 中序表达式(中缀表达式,我们常用的数学表达式的表示方式,带有括号,并且有运算优先级) 是非常复杂的结构。相对的,逆波兰式在计算机看来却是比较简单易懂的结构。因为计算机普遍采用的内存结构是栈式结构,它执行先进后出的顺序。
中缀表达式:3 + (51 * 2) - 80 / (4 - 2)
后缀表达式:转换后的形式为 3 51 2 * + 80 4 2 - / -
后缀表达式的计算
从左到右开始读取后缀表达式:
(1) 读到 3,入栈。此时栈:[3]
(2) 读到 51,入栈。此时栈:[3, 51]
(3) 读到 2,入栈。此时栈:[3, 51, 2]
(4) 读到 ∗ * ∗,取出栈顶两个数字进行乘法运算:51 * 2 = 102,结果入栈。此时栈:[3, 102]
(5) 读到 + + +,取出栈顶两个数字进行加法运算:3 + 102 = 105,结果入栈。此时栈:[105]
(6) 读到 80,入栈。此时栈:[105, 80]
(7) 读到 4,入栈。此时栈:[105, 80, 4]
(8) 读到 2,入栈。此时栈:[105, 80, 4, 2]
(9) 读到 − - −,取出栈顶两个数字进行减法运算:4 - 2 = 2,结果入栈。此时栈:[105, 80, 2]
(10) 读到 / / /,取出栈顶两个数字进行除法运算:80 / 2 = 40,结果入栈。此时栈:[105, 40]
(11) 读到 − - −,取出栈顶两个数字进行减法运算:105 - 40 = 65,结果入栈。此时栈:[65]
计算结束,栈中只剩下一个数字,这就是最终结果。因此,表达式 3 51 2 * + 80 4 2 - / - 的计算结果是65。
现在计算下面中缀表达式的后缀表达并求值:
求解思路
- 使用正则表达式将输入字符串分割成 tokens。
['(', '-', '5', '+', '3', ')', '*', '2', '-', '4', '/', '(', '2', '-', '√', '(', '16', '-', '2', ')', ')', '+', '3', '^', '2']
遍历 tokens,使用栈来处理运算符和括号。
- 定义运算优先级,并根据运算符优先级决定何时将运算符加入输出或压入栈。
def precedence(op):"""定义运算符优先级"""if op in {'+', '-'}:return 1if op in {'*', '/'}:return 2if op == '^':return 3if op == '√':return 4return 0
- 将运算符号和数学计算对应起来
operators = {'+': lambda x, y: x + y,'-': lambda x, y: x - y,'*': lambda x, y: x * y,'/': lambda x, y: x / y if y != 0 else float('inf'), # 处理除以零的情况'^': lambda x, y: math.pow(x, y),'√': lambda x: math.sqrt(x) if x >= 0 else float('nan') # 处理负数开方的情况}
- 计算得到的后缀表达式的值
Python3程序
import re
import mathdef infix_to_postfix(expression):def precedence(op):"""定义运算符优先级"""if op in {'+', '-'}:return 1if op in {'*', '/'}:return 2if op == '^':return 3if op == '√':return 4return 0def is_operator(token):"""检查token是否为运算符"""return token in {'+', '-', '*', '/', '^', '√'}output = [] # 用于存储后缀表达式stack = [] # 用于临时存储运算符# 使用正则表达式分割表达式为tokentokens = re.findall(r'√|\d+\.?\d*|\+|\-|\*|\/|\^|\(|\)', expression)i = 0while i < len(tokens):token = tokens[i]if token.replace('.', '').isdigit():# 处理数字if i > 0 and (tokens[i-1] == ')' or tokens[i-1].replace('.', '').isdigit()):# 在两个数字或右括号和数字之间插入乘号(处理隐式乘法)while stack and precedence(stack[-1]) >= precedence('*'):output.append(stack.pop())stack.append('*')output.append(token)elif token == '(':# 处理左括号if i > 0 and (tokens[i-1] == ')' or tokens[i-1].replace('.', '').isdigit()):# 在数字和左括号之间插入乘号(处理隐式乘法)while stack and precedence(stack[-1]) >= precedence('*'):output.append(stack.pop())stack.append('*')stack.append(token)elif token == ')':# 处理右括号while stack and stack[-1] != '(':output.append(stack.pop())if stack and stack[-1] == '(':stack.pop() # 弹出左括号else:raise ValueError("括号不匹配")elif is_operator(token):# 处理运算符if token == '√':# 处理根号if i + 1 < len(tokens) and tokens[i+1] == '(':# 如果根号后面跟着左括号,找到匹配的右括号bracket_count = 1j = i + 2while j < len(tokens) and bracket_count > 0:if tokens[j] == '(':bracket_count += 1elif tokens[j] == ')':bracket_count -= 1j += 1if bracket_count != 0:raise ValueError("括号不匹配")# 递归处理根号内的表达式sub_expr = ''.join(tokens[i+2:j-1])sub_postfix = infix_to_postfix(sub_expr)output.extend(sub_postfix)output.append(token)i = j - 1 # 更新索引到右括号的位置else:# 如果根号后面不是左括号,按普通运算符处理while stack and precedence(stack[-1]) >= precedence(token):output.append(stack.pop())stack.append(token)else:# 处理一元减号if token == '-' and (i == 0 or tokens[i-1] == '(' or is_operator(tokens[i-1])):output.append('0')while stack and precedence(stack[-1]) >= precedence(token):output.append(stack.pop())stack.append(token)i += 1# 将栈中剩余的运算符添加到输出while stack:if stack[-1] == '(':raise ValueError("括号不匹配")output.append(stack.pop())return outputdef evaluate_rpn(tokens):"""计算后缀表达式的值"""stack = []operators = {'+': lambda x, y: x + y,'-': lambda x, y: x - y,'*': lambda x, y: x * y,'/': lambda x, y: x / y if y != 0 else float('inf'), # 处理除以零的情况'^': lambda x, y: math.pow(x, y),'√': lambda x: math.sqrt(x) if x >= 0 else float('nan') # 处理负数开方的情况}for token in tokens:if token in operators:if token == '√':# 处理一元运算符(开方)if not stack:raise ValueError("无效的表达式:√ 缺少操作数")a = stack.pop()result = operators[token](a)else:# 处理二元运算符if len(stack) < 2:raise ValueError(f"无效的表达式:{token} 缺少操作数")b = stack.pop()a = stack.pop()result = operators[token](a, b)stack.append(result)else:# 将数字转换为浮点数并压入栈try:stack.append(float(token))except ValueError:raise ValueError(f"无效的token: {token}")# 确保最后栈中只剩一个数(结果)if len(stack) != 1:raise ValueError("无效的表达式")return stack[0]def calculate(expression):"""主计算函数,处理异常并返回结果"""try:postfix = infix_to_postfix(expression)result = evaluate_rpn(postfix)return resultexcept Exception as e:return f"错误: {str(e)}"if __name__ == '__main__':# 测试expressions = '(-5 + 3) * 2 - 4 / (2 - √(16-2)) + 3^2'postfix = infix_to_postfix(expressions)result = evaluate_rpn(postfix)print(f"中缀表达式: {expressions}")print(f"后缀表达式: {' '.join(postfix)}")print(f"计算结果: {result}")
结果
中缀表达式: (-5 + 3) * 2 - 4 / (2 - √(16-2)) + 3^2
后缀表达式: 0 5 - 3 + 2 * 4 2 16 2 - √ - / - 3 2 ^ +
计算结果: 7.296662954709577
相关文章:

数据结构编程实践20讲(Python版)—03栈
本文目录 03 栈 StackS1 说明S2 示例基于列表的实现基于链表的实现 S3 问题:复杂嵌套结构的括号匹配问题求解思路Python3程序 S4 问题:基于栈的阶乘计算VS递归实现求解思路Python3程序 S5 问题:逆波兰表示法(后缀表达式)求值求解思路Python3程…...

【注册/登录安全分析报告:孔夫子旧书网】
前言 由于网站注册入口容易被黑客攻击,存在如下安全问题: 暴力破解密码,造成用户信息泄露短信盗刷的安全问题,影响业务及导致用户投诉带来经济损失,尤其是后付费客户,风险巨大,造成亏损无底洞…...

PMP--二模--解题--141-150
文章目录 14.敏捷--创建敏捷环境--团队构成--混合项目环境,通常是自组织团队,即团队成员自己决定谁做什么,而不是项目经理决定。易混--常见场景--一个新人加入141、 [单选] 在一个混合项目的执行过程中,不得不更换一个开发人员。新…...

我的领域-关怀三次元成长的二次元虚拟陪伴 | OPENAIGC开发者大赛高校组AI创作力奖
在第二届拯救者杯OPENAIGC开发者大赛中,涌现出一批技术突出、创意卓越的作品。为了让这些优秀项目被更多人看到,我们特意开设了优秀作品报道专栏,旨在展示其独特之处和开发者的精彩故事。 无论您是技术专家还是爱好者,希望能带给…...

个人账号(学校+个人)申请专利过程中遇见的问题
一、请指定一位申请人作为代表人 因为是拿个人账号申请的专利,同时要求学校是第一申请人,所以可以再添加一个第二申请人,然后勾选第二申请人为代表人就可以提交申请了(注意:两个申请人只能减免75%,也就是要…...

在ubuntu系统中,如何让其按下物理关机键时,系统不处理,但qt程序能检测到关机键按下的事件,并处理信号
要让 Ubuntu 系统在按下物理关机键时,系统不直接处理该事件,但让你的 Qt 程序能够检测到并处理关机键的按下事件,可以参考以下步骤: 1. 禁用系统对关机键的默认处理 Ubuntu 系统默认会捕获电源键的按下事件并执行关机操作。首先你…...

先进制造aps专题二十六 基于强化学习的人工智能ai生产排程aps模型简介
基于强化学习的人工智能ai生产排程模型简介 人工智能ai能不能做生产排程? 答案是肯定的。 ai的算法分两类,一类是学习,一类是搜索。 而生产排程问题,它是一个搜索问题,本质上,它和下围棋是一样的 我们…...

各领域/行业硬件一览表
专班硬件装备制造agv小车、机械臂、PDA、服务器、大屏、扭矩传感器、温湿度检测仪、粉尘传感器、陀螺仪传感器、3D打印设备、在线质量检测仪器、新能源水表、电表、气表、汽表、服务器、大屏、温度传感器、压力传感器、光照度传感器、RTU医药化工温湿度传感器、压力传感器、流量…...

机器学习-SVM
线性感知机分类 支持向量机 线性感知机(Perceptron) 感知机是线性二值分类器。 注意:什么是线性?线性分割面就是,就是在分割面中,任意两个的连线也在分割面中,这个分割面,就是线…...

翻译器在线翻译:开启多语言交流新时代
随着国际交流、商务合作、文化交融以及互联网的飞速发展,人们对于跨越语言鸿沟的需求日益迫切。翻译工具成为了我们必备的一个工具,这篇文章我们一起来探讨一些好用的翻译器在线翻译工具吧。 1.在线福昕翻译 链接直达>>https://fanyi.pdf365.cn/…...

网络编程(10)——json序列化
十、day10 今天学习如何使用jsoncpp将json数据解析为c对象,将c对象序列化为json数据。jsoncp经常在网络通信中使用,也就是服务器和客户端的通信一般使用json(可视化好);而protobuf一般在服务器之间的通信中使用 json…...

基于FreeRTOS的STM32多功能手表设计
在智能穿戴设备迅速发展的今天,多功能手表因其便携性和实用性而受到广泛关注。本项目旨在设计一款基于FreeRTOS操作系统的STM32多功能手表,通过实时多任务处理,实现时间显示、多级菜单、万年历、模拟手电筒、温湿度显示、电子闹钟和设置等功能…...

18.Linux-配置DNF仓库
DNF仓库产生背景 在现实的场景中,我们经常要安装一些软件包,但由于现场不提供网络。 需要使用光盘或文件下载的方式去安装。 对于linux有两种离线安装方式:二进制文件安装和源码安装 其中二进制文件是比较简单的安装方式,不同的l…...

GeoPB:高效处理地理空间数据的Protobuf解决方案
在地理信息系统(GIS)和地理空间数据处理的领域,数据的交换和存储格式至关重要。随着技术的不断发展,如何高效、安全地处理和转换地理空间数据成为了一个核心问题。本文将详细介绍GeoPB——一个基于Protobuf(Protocol B…...

华为仓颉语言入门(6):if条件表达式
解锁Python编程的无限可能:《奇妙的Python》带你漫游代码世界 仓颉语言中的 if 表达式用于根据条件的值来决定是否执行相关代码逻辑。if 表达式有三种形式:单分支的 if 表达式、双分支的 if 表达式和嵌套的 if 表达式。 单分支的 if 表达式 单分支的 …...

openlayers中一些问题的解决方案
一、使用地图时可能会出现的需求 1、定位:需要将地图的中心视野,定位到研究区域的中心点; 2、地图蒙版:只研究特定区域,将其他部分区域用蒙层遮罩,突显重点; 3、变色:设置整体的地图…...

java通过redis完成幂等性操作
4 幂等 产生 “重复数据或数据不一致”( 假定程序业务代码没问题 ),绝大部分就是发生了重复的请求,重复请求是指"同一个请求因为某些原因被多次提交"。导致这个情况会有几种场景: 微服务场景,在…...

48 旋转图像
解题思路: \qquad 这道题同样需要用模拟解决,原地算法要求空间复杂度尽量小,最好为 O ( 1 ) O(1) O(1)。模拟的关键是找到旋转的内在规律,即旋转前后的位置坐标的变化规律。 \qquad 正方形矩阵类似洋葱,可以由不同大小…...

TDengine 签约青山钢铁,实现冶金全流程质量管控智能化
在不锈钢生产领域,企业面临着信息孤岛和数据分散的挑战,尤其在冶炼、连铸和轧钢等关键工艺以及能源管理上,这种现象导致生产要素(人、机、料、法、环)的分析管理模型难以全面、深入地实施。为了应对这一挑战࿰…...

__pycache__文件夹
__pycache__ 文件夹是 Python 在运行时自动生成的目录,用于存储已编译的字节码文件。这些字节码文件以 .pyc 扩展名结尾,用于加速程序的启动时间,因为不需要每次运行时都重新编译源代码。 主要特点 自动生成:__pycache__ 文件夹…...

利用 Local Data 导入文件到 OceanBase 的方法
背景 在很多传统方法中,数据的传输常依赖于csv格式。为了提高传输效率,属于同一张表的多个csv文件往往会被打包成gz文件进行传输。 当gz文件从上游传递到下游后,为了将其中的csv数据导入数据库,一种直接的做法是: 1…...

改变安全策略的五大实践
随着网络威胁形势的加剧,网络安全计划必须不断发展以保护组织的使命。 为了管理这种持续的网络安全发展,应遵循五项关键的安全计划变更管理实践: 1. 识别并吸引受安全风险影响的业务利益相关者 随着新的网络安全风险被发现,受影…...

在MacOS上安装MongoDB数据库
一、安装方法 1.1 安装包安装 首先,打开MongoDB 官网下载安装包,下载链接:https://www.mongodb.com/try/download/community。 根据自己的系统环境自行选择下载的版本。将下载好的 MongoDB 安装包解压缩,并将文件夹名改为 mon…...

负载均衡--会话保持失败原因及解决方案(五)
会话保持失败可能由多种因素导致,以下是一些主要原因及其解释: 一、服务器及网络问题 服务器故障: 服务器出现故障或不稳定,导致无法正确处理会话信息。这可能是由于硬件故障、网络问题或软件错误等引起的。网络问题:…...

24 Vue3之集成TailwindCSS
Tailwind CSS Tailwind CSS是一个由js编写的CSS 框架 他是基于postCss 去解析的 官网地址Tailwind CSS 中文文档 - Tailwind CSS - 只需书写 HTML 代码,无需书写 CSS,即可快速构建美观的网站。 | TailwindCSS中文文档 | TailwindCSS中文网 对于PostCSS…...

iOS OC 底层原理之 category、load、initialize
文章目录 category底层结构runtime 执行 category 底层原理添加成员变量 load调用形式系统调用形式的内部原理源码实现逻辑 initialize调用形式源码核心函数(由上到下依次调用)如果分类实现了 initialize category 底层结构 本质是结构体。struct _cat…...

另外知识与网络总结
一、重谈NAT(工作在网络层) 为什么会有NAT 为了解决ipv4地址太少问题,到了公网的末端就会有运营商路由器来构建私网,在不同私网中私有IP可以重复,这就可以缓解IP地址太少问题,但是这就导致私有IP是重复的…...

怎样用云手机进行TikTok矩阵运营?
在运营TikTok矩阵时,许多用户常常面临操作复杂、设备过多等问题。如果你也感到操作繁琐,不妨考虑使用云手机。云手机具备丰富的功能,能够帮助电商卖家快速打造高效的TikTok矩阵。接下来,我们将详细解析这些功能如何提升你的运营效…...

RTMP播放器全解析
一、RTMP 播放器概述 (一)RTMP 播放器的定义与作用 RTMP 播放器是一种专门用于播放采用 RTMP(Real Time Messaging Protocol)协议的视频流的工具。在当今的流媒体播放领域中,它扮演着至关重要的角色。RTMP 播放器能够…...

定期清洗ip是为了什么?怎么清洗iip
定期清洗IP(也称为“IP清理”)的目的是确保使用的IP池保持高效、可靠、安全,避免因使用无效或被封禁的IP导致网络操作失败。尤其在数据爬取、负载均衡等使用代理的场景中,定期清洗IP有助于提升整体的性能和数据抓取成功率。 定期…...