当前位置: 首页 > news >正文

用python实现基本数据结构【04/4】

说明

        如果需要用到这些知识却没有掌握,则会让人感到沮丧,也可能导致面试被拒。无论是花几天时间“突击”,还是利用零碎的时间持续学习,在数据结构上下点功夫都是值得的。那么Python 中有哪些数据结构呢?列表、字典、集合,还有……栈?Python 有栈吗?本系列文章将给出详细拼图。


13章: Binary Tree

The binary Tree: 二叉树,每个节点做多只有两个子节点

class _BinTreeNode:def __init__(self, data):self.data = dataself.left = Noneself.right = None# 三种depth-first遍历
def preorderTrav(subtree):""" 先(根)序遍历"""if subtree is not None:print(subtree.data)preorderTrav(subtree.left)preorderTrav(subtree.right)def inorderTrav(subtree):""" 中(根)序遍历"""if subtree is not None:preorderTrav(subtree.left)print(subtree.data)preorderTrav(subtree.right)def postorderTrav(subtree):""" 后(根)序遍历"""if subtree is not None:preorderTrav(subtree.left)preorderTrav(subtree.right)print(subtree.data)# 宽度优先遍历(bradth-First Traversal): 一层一层遍历, 使用queue
def breadthFirstTrav(bintree):from queue import Queue    # py3q = Queue()q.put(bintree)while not q.empty():node = q.get()print(node.data)if node.left is not None:q.put(node.left)if node.right is not None:q.put(node.right)class _ExpTreeNode:__slots__ = ('element', 'left', 'right')def __init__(self, data):self.element = dataself.left = Noneself.right = Nonedef __repr__(self):return '<_ExpTreeNode: {} {} {}>'.format(self.element, self.left, self.right)from queue import Queue
class ExpressionTree:"""表达式树: 操作符存储在内节点操作数存储在叶子节点的二叉树。(符号树真难打出来)*/ \+   -/ \  / \9  3 8   4(9+3) * (8-4)Expression Tree Abstract Data Type,可以实现二元操作符ExpressionTree(expStr): user string as constructor paramevaluate(varDict): evaluates the expression and returns the numeric resulttoString(): constructs and retutns a string represention of the expressionUsage:vars = {'a': 5, 'b': 12}expTree = ExpressionTree("(a/(b-3))")print('The result = ', expTree.evaluate(vars))"""def __init__(self, expStr):self._expTree = Noneself._buildTree(expStr)def evaluate(self, varDict):return self._evalTree(self._expTree, varDict)def __str__(self):return self._buildString(self._expTree)def _buildString(self, treeNode):""" 在一个子树被遍历之前添加做括号,在子树被遍历之后添加右括号 """# print(treeNode)if treeNode.left is None and treeNode.right is None:return str(treeNode.element)    # 叶子节点是操作数直接返回else:expStr = '('expStr += self._buildString(treeNode.left)expStr += str(treeNode.element)expStr += self._buildString(treeNode.right)expStr += ')'return expStrdef _evalTree(self, subtree, varDict):# 是不是叶子节点, 是的话说明是操作数,直接返回if subtree.left is None and subtree.right is None:# 操作数是合法数字吗if subtree.element >= '0' and subtree.element <= '9':return int(subtree.element)else:    # 操作数是个变量assert subtree.element in varDict, 'invalid variable.'return varDict[subtree.element]else:    # 操作符则计算其子表达式lvalue = self._evalTree(subtree.left, varDict)rvalue = self._evalTree(subtree.right, varDict)print(subtree.element)return self._computeOp(lvalue, subtree.element, rvalue)def _computeOp(self, left, op, right):assert opop_func = {'+': lambda left, right: left + right,    # or import operator, operator.add'-': lambda left, right: left - right,'*': lambda left, right: left * right,'/': lambda left, right: left / right,'%': lambda left, right: left % right,}return op_func[op](left, right)def _buildTree(self, expStr):expQ = Queue()for token in expStr:    # 遍历表达式字符串的每个字符expQ.put(token)self._expTree = _ExpTreeNode(None)    # 创建root节点self._recBuildTree(self._expTree, expQ)def _recBuildTree(self, curNode, expQ):token = expQ.get()if token == '(':curNode.left = _ExpTreeNode(None)self._recBuildTree(curNode.left, expQ)# next token will be an operator: + = * / %curNode.element = expQ.get()curNode.right = _ExpTreeNode(None)self._recBuildTree(curNode.right, expQ)# the next token will be ')', remmove itexpQ.get()else:  # the token is a digit that has to be converted to an int.curNode.element = tokenvars = {'a': 5, 'b': 12}
expTree = ExpressionTree("((2*7)+8)")
print(expTree)
print('The result = ', expTree.evaluate(vars))

Heap(堆):二叉树最直接的一个应用就是实现堆。堆就是一颗完全二叉树,最大堆的非叶子节点的值都比孩子大,最小堆的非叶子结点的值都比孩子小。 python内置了heapq模块帮助我们实现堆操作,比如用内置的heapq模块实现个堆排序:

# 使用python内置的heapq实现heap sort
def heapsort(iterable):from heapq import heappush, heappoph = []for value in iterable:heappush(h, value)return [heappop(h) for i in range(len(h))]

但是一般实现堆的时候实际上并不是用数节点来实现的,而是使用数组实现,效率比较高。为什么可以用数组实现呢?因为完全二叉树的性质, 可以用下标之间的关系表示节点之间的关系,MaxHeap的docstring中已经说明了

class MaxHeap:"""Heaps:完全二叉树,最大堆的非叶子节点的值都比孩子大,最小堆的非叶子结点的值都比孩子小Heap包含两个属性,order property 和 shape property(a complete binary tree),在插入一个新节点的时候,始终要保持这两个属性插入操作:保持堆属性和完全二叉树属性, sift-up 操作维持堆属性extract操作:只获取根节点数据,并把树最底层最右节点copy到根节点后,sift-down操作维持堆属性用数组实现heap,从根节点开始,从上往下从左到右给每个节点编号,则根据完全二叉树的性质,给定一个节点i, 其父亲和孩子节点的编号分别是:parent = (i-1) // 2left = 2 * i + 1rgiht = 2 * i + 2使用数组实现堆一方面效率更高,节省树节点的内存占用,一方面还可以避免复杂的指针操作,减少调试难度。"""def __init__(self, maxSize):self._elements = Array(maxSize)    # 第二章实现的Array ADTself._count = 0def __len__(self):return self._countdef capacity(self):return len(self._elements)def add(self, value):assert self._count < self.capacity(), 'can not add to full heap'self._elements[self._count] = valueself._count += 1self._siftUp(self._count - 1)self.assert_keep_heap()    # 确定每一步add操作都保持堆属性def extract(self):assert self._count > 0, 'can not extract from an empty heap'value = self._elements[0]    # save root valueself._count -= 1self._elements[0] = self._elements[self._count]    # 最右下的节点放到root后siftDownself._siftDown(0)self.assert_keep_heap()return valuedef _siftUp(self, ndx):if ndx > 0:parent = (ndx - 1) // 2# print(ndx, parent)if self._elements[ndx] > self._elements[parent]:    # swapself._elements[ndx], self._elements[parent] = self._elements[parent], self._elements[ndx]self._siftUp(parent)    # 递归def _siftDown(self, ndx):left = 2 * ndx + 1right = 2 * ndx + 2# determine which node contains the larger valuelargest = ndxif (left < self._count andself._elements[left] >= self._elements[largest] andself._elements[left] >= self._elements[right]):  # 原书这个地方没写实际上找的未必是largestlargest = leftelif right < self._count and self._elements[right] >= self._elements[largest]:largest = rightif largest != ndx:self._elements[ndx], self._elements[largest] = self._elements[largest], self._elements[ndx]self._siftDown(largest)def __repr__(self):return ' '.join(map(str, self._elements))def assert_keep_heap(self):""" 我加了这个函数是用来验证每次add或者extract之后,仍保持最大堆的性质"""_len = len(self)for i in range(0, int((_len-1)/2)):    # 内部节点(非叶子结点)l = 2 * i + 1r = 2 * i + 2if l < _len and r < _len:assert self._elements[i] >= self._elements[l] and self._elements[i] >= self._elements[r]def test_MaxHeap():""" 最大堆实现的单元测试用例 """_len = 10h = MaxHeap(_len)for i in range(_len):h.add(i)h.assert_keep_heap()for i in range(_len):# 确定每次出来的都是最大的数字,添加的时候是从小到大添加的assert h.extract() == _len-i-1test_MaxHeap()def simpleHeapSort(theSeq):""" 用自己实现的MaxHeap实现堆排序,直接修改原数组实现inplace排序"""if not theSeq:return theSeq_len = len(theSeq)heap = MaxHeap(_len)for i in theSeq:heap.add(i)for i in reversed(range(_len)):theSeq[i] = heap.extract()return theSeqdef test_simpleHeapSort():""" 用一些测试用例证明实现的堆排序是可以工作的 """def _is_sorted(seq):for i in range(len(seq)-1):if seq[i] > seq[i+1]:return Falsereturn Truefrom random import randintassert simpleHeapSort([]) == []for i in range(1000):_len = randint(1, 100)to_sort = []for i in range(_len):to_sort.append(randint(0, 100))simpleHeapSort(to_sort)    # 注意这里用了原地排序,直接更改了数组assert _is_sorted(to_sort)test_simpleHeapSort()

14章: Search Trees

二叉差找树性质:对每个内部节点V, 1. 所有key小于V.key的存储在V的左子树。 2. 所有key大于V.key的存储在V的右子树 对BST进行中序遍历会得到升序的key序列

class _BSTMapNode:__slots__ = ('key', 'value', 'left', 'right')def __init__(self, key, value):self.key = keyself.value = valueself.left = Noneself.right = Nonedef __repr__(self):return '<{}:{}> left:{}, right:{}'.format(self.key, self.value, self.left, self.right)__str__ = __repr__class BSTMap:""" BST,树节点包含key可payload。用BST来实现之前用hash实现过的Map ADT.性质:对每个内部节点V,1.对于节点V,所有key小于V.key的存储在V的左子树。2.所有key大于V.key的存储在V的右子树对BST进行中序遍历会得到升序的key序列"""def __init__(self):self._root = Noneself._size = 0self._rval = None     # 作为remove的返回值def __len__(self):return self._sizedef __iter__(self):return _BSTMapIterator(self._root, self._size)def __contains__(self, key):return self._bstSearch(self._root, key) is not Nonedef valueOf(self, key):node = self._bstSearch(self._root, key)assert node is not None, 'Invalid map key.'return node.valuedef _bstSearch(self, subtree, target):if subtree is None:    # 递归出口,遍历到树底没有找到key或是空树return Noneelif target < subtree.key:return self._bstSearch(subtree.left, target)elif target > subtree.key:return self._bstSearch(subtree.right, target)return subtree    # 返回引用def _bstMinumum(self, subtree):""" 顺着树一直往左下角递归找就是最小的,向右下角递归就是最大的 """if subtree is None:return Noneelif subtree.left is None:return subtreeelse:return subtree._bstMinumum(self, subtree.left)def add(self, key, value):""" 添加或者替代一个key的value, O(N) """node = self._bstSearch(self._root, key)if node is not None:    # if key already exists, update valuenode.value = valuereturn Falseelse:   # insert a new entryself._root = self._bstInsert(self._root, key, value)self._size += 1return Truedef _bstInsert(self, subtree, key, value):""" 新的节点总是插入在树的叶子结点上 """if subtree is None:subtree = _BSTMapNode(key, value)elif key < subtree.key:subtree.left = self._bstInsert(subtree.left, key, value)elif key > subtree.key:subtree.right = self._bstInsert(subtree.right, key, value)# 注意这里没有else语句了,应为在被调用处add函数里先判断了是否有重复keyreturn subtreedef remove(self, key):""" O(N)被删除的节点分为三种:1.叶子结点:直接把其父亲指向该节点的指针置None2.该节点有一个孩子: 删除该节点后,父亲指向一个合适的该节点的孩子3.该节点有俩孩子:(1)找到要删除节点N和其后继S(中序遍历后该节点下一个)(2)复制S的key到N(3)从N的右子树中删除后继S(即在N的右子树中最小的)"""assert key in self, 'invalid map key'self._root = self._bstRemove(self._root, key)self._size -= 1return self._rvaldef _bstRemove(self, subtree, target):# search for the item in the treeif subtree is None:return subtreeelif target < subtree.key:subtree.left = self._bstRemove(subtree.left, target)return subtreeelif target > subtree.key:subtree.right = self._bstRemove(subtree.right, target)return subtreeelse:    # found the node containing the itemself._rval = subtree.valueif subtree.left is None and subtree.right is None:# 叶子nodereturn Noneelif subtree.left is None or subtree.right is None:# 有一个孩子节点if subtree.left is not None:return subtree.leftelse:return subtree.rightelse:   # 有俩孩子节点successor = self._bstMinumum(subtree.right)subtree.key = successor.keysubtree.value = successor.valuesubtree.right = self._bstRemove(subtree.right, successor.key)return subtreedef __repr__(self):return '->'.join([str(i) for i in self])def assert_keep_bst_property(self, subtree):""" 写这个函数为了验证add和delete操作始终维持了bst的性质 """if subtree is None:returnif subtree.left is not None and subtree.right is not None:assert subtree.left.value <= subtree.valueassert subtree.right.value >= subtree.valueself.assert_keep_bst_property(subtree.left)self.assert_keep_bst_property(subtree.right)elif subtree.left is None and subtree.right is not None:assert subtree.right.value >= subtree.valueself.assert_keep_bst_property(subtree.right)elif subtree.left is not None and subtree.right is None:assert subtree.left.value <= subtree.valueself.assert_keep_bst_property(subtree.left)class _BSTMapIterator:def __init__(self, root, size):self._theKeys = Array(size)self._curItem = 0self._bstTraversal(root)self._curItem = 0def __iter__(self):return selfdef __next__(self):if self._curItem < len(self._theKeys):key = self._theKeys[self._curItem]self._curItem += 1return keyelse:raise StopIterationdef _bstTraversal(self, subtree):if subtree is not None:self._bstTraversal(subtree.left)self._theKeys[self._curItem] = subtree.keyself._curItem += 1self._bstTraversal(subtree.right)def test_BSTMap():l = [60, 25, 100, 35, 17, 80]bst = BSTMap()for i in l:bst.add(i)def test_HashMap():""" 之前用来测试用hash实现的map,改为用BST实现的Map测试 """# h = HashMap()h = BSTMap()assert len(h) == 0h.add('a', 'a')assert h.valueOf('a') == 'a'assert len(h) == 1a_v = h.remove('a')assert a_v == 'a'assert len(h) == 0h.add('a', 'a')h.add('b', 'b')assert len(h) == 2assert h.valueOf('b') == 'b'b_v = h.remove('b')assert b_v == 'b'assert len(h) == 1h.remove('a')assert len(h) == 0_len = 10for i in range(_len):h.add(str(i), i)assert len(h) == _lenfor i in range(_len):assert str(i) in hfor i in range(_len):print(len(h))print('bef', h)_ = h.remove(str(i))assert _ == iprint('aft', h)print(len(h))assert len(h) == 0test_HashMap()

相关文章:

用python实现基本数据结构【04/4】

说明 如果需要用到这些知识却没有掌握&#xff0c;则会让人感到沮丧&#xff0c;也可能导致面试被拒。无论是花几天时间“突击”&#xff0c;还是利用零碎的时间持续学习&#xff0c;在数据结构上下点功夫都是值得的。那么Python 中有哪些数据结构呢&#xff1f;列表、字典、集…...

“必抓!”算法

一个程序员一生中可能会邂逅各种各样的算法&#xff0c;但总有那么几种&#xff0c;是作为一个程序员一定会遇见且大概率需要掌握的算法。今天就来聊聊这些十分重要的“必抓&#xff01;”算法吧~ 你可以从以下几个方面进行创作&#xff08;仅供参考&#xff09; 一&#xff…...

【监控系统】Promethus整合Alertmanager监控告警邮件通知

【监控系统】Promethus整合Alertmanager监控告警邮件通知 Alertmanager是一种开源软件&#xff0c;用于管理和报警监视警报。它与Prometheus紧密集成&#xff0c;后者是一种流行的开源监视和警报系统。Alertmanager从多个源接收警报和通知&#xff0c;并根据一组配置规则来决定…...

【韩顺平】Linux基础

目录 1.网络连接三种方式 1.1 桥接模式&#xff1a;虚拟系统可以和外部系统通讯&#xff0c;但是容易造成IP冲突【1-225】 1.2 NAT模式&#xff1a;网络地址转换模式。虚拟系统可以和外部系统通讯&#xff0c;不造成IP冲突。 1.3 主机模式&#xff1a;独立的系统。 2.虚拟机…...

好奇一下各个大模型对华为mate60系列的看法

目前华为Mate60系列手机已上市并获抢购&#xff0c;个人觉得很不错&#xff0c;很好奇各个AI大模型对此事的看法&#xff0c;于是对chatGPT、文心一言、讯飞星火进行了一下粗浅的测试。 题目一&#xff08;看看三个模型的综合分析能力&#xff09; “目前华为Mate60系列手机已…...

UMA 2 - Unity Multipurpose Avatar☀️五.如何使用别人的Recipe和创建自己的服饰Recipe

文章目录 🟥 使用别人的Recipe1️⃣ 导入UMA资源效果展示2️⃣ 更新Library3️⃣ 试一下吧🟧 创建自己的服饰Recipe1️⃣ 创建自己的服饰Recipe2️⃣ 选择应用到的Base Recipe3️⃣ 指定显示名 / 佩戴位置 / 隐藏部位4️⃣ 给该服饰Recipe指定Slot / Overlay🚩 赋予Slot�…...

代码随想录训练营第五十六天| 583. 两个字符串的删除操作 、72. 编辑距离

583. 两个字符串的删除操作 题目链接/文章讲解/视频讲解&#xff1a;代码随想录 1.代码展示 //583.两个字符串的删除操作 int minDistance(string word1, string word2) {//step1 构建dp数组&#xff0c;dp[i][j]的含义是要使以i-1为结尾的word1和以j-1为结尾的word2//删除其元…...

hive解决了什么问题

hive出现的原因 Hive 出现的原因主要有以下几个&#xff1a; 传统数据仓库无法处理大规模数据&#xff1a;传统的数据仓库通常采用关系型数据库作为底层存储&#xff0c;这种数据库在处理大规模数据时效率较低。MapReduce 难以使用&#xff1a;MapReduce 是一种分布式计算框架…...

Lumion 和 Enscape 应该选择怎样的笔记本电脑?

Lumion 和 Enscape实时渲染对配置要求高&#xff0c;本地配置不够&#xff0c;如何快速解决&#xff1a; 本地普通电脑可一键申请高性能工作站&#xff0c;资产安全保障&#xff0c;供软件中心&#xff0c;各种软件插件一键获取&#xff0c;且即开即用&#xff0c;使用灵活&am…...

ICCV 2023 | MoCoDAD:一种基于人体骨架的运动条件扩散模型,实现高效视频异常检测

论文链接&#xff1a; https://arxiv.org/abs/2307.07205 视频异常检测&#xff08;Video Anomaly Detection&#xff0c;VAD&#xff09;扩展自经典的异常检测任务&#xff0c;由于异常情况样本非常少见&#xff0c;因此经典的异常检测通常被定义为一类分类问题&#xff08;On…...

Mac电脑怎么使用NTFS磁盘管理器 NTFS磁盘详细使用教程

Mac是可以识别NTFS硬盘的&#xff0c;但是macOS系统虽然能够正确识别NTFS硬盘&#xff0c;但只支持读取&#xff0c;不支持写入。换句话说&#xff0c;Mac不支持对NTFS硬盘进行编辑、创建、删除等写入操作&#xff0c;比如将Mac里的文件拖入NTFS硬盘&#xff0c;在NTFS硬盘里新…...

Java设计模式-结构性设计模式(代理设计模式)

简介 为其他对象提供⼀种代理以控制对这个对象的访问&#xff0c;属于结构型模式。客户端并不直接调⽤实际的对象&#xff0c;⽽是通过调⽤代理&#xff0c;来间接的调⽤实际的对象应用场景 各⼤数码专营店&#xff0c;代理⼚商进⾏销售对应的产品&#xff0c;代理商持有真正的…...

线性空间、子空间、基、基坐标、过渡矩阵

线性空间的定义 满足加法和数乘封闭。也就是该空间的所有向量都满足乘一个常数后或者和其它向量相加后仍然在这个空间里。进一步可以理解为该空间中的所有向量满足加法和数乘的组合封闭。即若 V 是一个线性空间&#xff0c;则首先需满足&#xff1a; 注&#xff1a;线性空间里面…...

【MySQL】CRUD (增删改查) 基础

CRUD&#xff08;增删改查&#xff09;基础 一. CRUD二. 新增 &#xff08;Create&#xff09;1. 单行数据 全列插入2. 多行数据 指定列插入 三. 查询&#xff08;Retrieve&#xff09;1. 全列查询2. 指定列查询3. 查询字段为表达式4. 别名5. 去重&#xff1a;DISTINCT6. 排序…...

Socks5代理IP:保障跨境电商的网络安全

在数字化时代&#xff0c;跨境电商已成为全球商业的重要一环。然而&#xff0c;随着其发展壮大&#xff0c;网络安全问题也逐渐浮出水面。为了确保跨境电商的安全和隐私&#xff0c;Socks5代理IP技术成为了一项不可或缺的工具。本文将深入探讨Socks5代理IP在跨境电商中的应用&a…...

macOS通过钥匙串访问找回WiFi密码

如果您忘记了Mac电脑上的WiFi密码&#xff0c;可以通过钥匙串访问来找回它。具体步骤如下&#xff1a; 1.打开Mac电脑的“启动台”&#xff0c;然后在其他文件中找到“钥匙串访问”。 2.运行“钥匙串访问”应用程序&#xff0c;点击左侧的“系统”&#xff0c;然后在右侧找到…...

Debian11之稳定版本Jenkins安装

官方网址 系统要求 机器要求 256 MB 内存&#xff0c;建议大于 512 MB 10 GB 的硬盘空间&#xff08;用于 Jenkins 和 Docker 镜像&#xff09;软件要求 Java 8 ( JRE 或者 JDK 都可以) Docker &#xff08;导航到网站顶部的Get Docker链接以访问适合您平台的Docker下载安装…...

kakfa 3.5 kafka服务端处理消费者客户端拉取数据请求源码

一、服务端接收消费者拉取数据的方法二、遍历请求中需要拉取数据的主题分区集合&#xff0c;分别执行查询数据操作&#xff0c;1、会选择合适的副本读取本地日志数据(2.4版本后支持主题分区多副本下的读写分离) 三、会判断当前请求是主题分区Follower发送的拉取数据请求还是消费…...

【Linux】进程概念I --操作系统概念与冯诺依曼体系结构

Halo&#xff0c;这里是Ppeua。平时主要更新C语言&#xff0c;C&#xff0c;数据结构算法…感兴趣就关注我吧&#xff01;你定不会失望。 本篇导航 1. 冯诺依曼体系结构为什么这样设计? 2. 操作系统概念为什么我们需要操作系统呢?操作系统怎么进行管理? 计算机是由两部分组…...

BRAM/URAM资源介绍

BRAM/URAM资源简介 Bram和URAM都是FPGA&#xff08;现场可编程门阵列&#xff09;中的RAM资源。 Bram是Block RAM的缩写&#xff0c;是Xilinx FPGA中常见的RAM资源之一&#xff0c;也是最常用的资源之一。它是一种单独的RAM模块&#xff0c;通常用于存储大量的数据&#xff0…...

分享一个基于python的个性推荐餐厅系统源码 餐厅管理系统代码

&#x1f495;&#x1f495;作者&#xff1a;计算机源码社 &#x1f495;&#x1f495;个人简介&#xff1a;本人七年开发经验&#xff0c;擅长Java、Python、PHP、.NET、Node.js、微信小程序、爬虫、大数据等&#xff0c;大家有这一块的问题可以一起交流&#xff01; &#x1…...

Mysql5.7开启SSL认证且支持Springboot客户端验证

Mysql5.7开启SSL认证 一、查看服务端mysql环境 1.查看是否开启了ssl,"have_ssl" 为YES的时候,数据库是开启加密连接方式的。 show global variables like %ssl%;2.查看数据库版本 select version();3.查看数据库端口 show variables like port;4.查看数据库存放…...

微信小程序的页面滚动事件监听

微信小程序中可以通过 Page 的 onPageScroll 方法来监听页面滚动事件。具体步骤如下&#xff1a; 在页面的 onLoad 方法中注册页面滚动事件监听器&#xff1a; Page({onLoad: function () {wx.pageScrollTo({scrollTop: 0,duration: 0});wx.showLoading({title: 加载中,});wx…...

数据可视化:四大发明的现代转化引擎

在科技和工业的蓬勃发展中&#xff0c;中国的四大发明——造纸术、印刷术、火药和指南针&#xff0c;早已不再是古代创新的象征&#xff0c;而是催生了众多衍生行业的崭新可能性。其中&#xff0c;数据可视化技术正成为这些行业的一颗璀璨明珠&#xff0c;开启了全新的时代。 1…...

HarmonyOS实现几种常见图片点击效果

一. 样例介绍 HarmonyOS提供了常用的图片、图片帧动画播放器组件&#xff0c;开发者可以根据实际场景和开发需求&#xff0c;实现不同的界面交互效果&#xff0c;包括&#xff1a;点击阴影效果、点击切换状态、点击动画效果、点击切换动效。 相关概念 image组件&#xff1a;图片…...

3D视觉测量:计算两个平面之间的夹角(附源码)

文章目录 1. 基本内容2. 代码实现文章目录:形位公差测量关键内容:通过视觉方法实现平面之间夹角的计算1. 基本内容 要计算两个平面之间的夹角,首先需要知道这两个平面的法向量。假设有两个平面,它们的法向量分别为 N 1 和 N 2 N_1 和 N_2...

deepin V23通过flathub安装steam畅玩游戏

deepin V23缺少32位库&#xff0c;在星火商店安装的steam,打开报错&#xff0c;无法使用&#xff01; 通过flathub网站安装steam,可以正常使用&#xff0c;详细教程如下&#xff1a; flathub网址&#xff1a;主页 | Flathub 注意&#xff1a;flathub下载速度慢&#xff0c;只…...

C语言是否快被时代所淘汰?

今日话题&#xff0c;C语言是否快被时代所淘汰&#xff1f;在移动互联网的冲击下&#xff0c;windows做的人越来越少&#xff0c;WP阵营没人做&#xff0c;后台简单的php&#xff0c;复杂的大数据处理的java&#xff0c;要求性能的c。主流一二线公司基本上没多少用C#的了。其实…...

简化转换器:使用您理解的单词进行最先进的 NLP — 第 1 部分 — 输入

一、说明 变形金刚是一种深度学习架构&#xff0c;为人工智能的发展做出了杰出贡献。这是人工智能和整个技术领域的一个重要阶段&#xff0c;但也有点复杂。截至今天&#xff0c;变形金刚上有很多很好的资源&#xff0c;那么为什么要再制作一个呢&#xff1f;两个原因&#xff…...

C++多线程编程(第三章 案例2,条件变量,生产者-消费者模型)

目录 1、condition_variable1.1、生产者消费者模型1.2、改变共享变量的线程步骤1.3、等待信号读取共享变量的线程步骤1.3.1、获得改变共享变量线程共同的mutex1.3.2、wait()等待信号通知1.3.2.1、无lambda表达式1.3.2.2 lambda表达式 样例代码 1、condition_variable 等待中&a…...

电话做网站的推广/线上产品推广方案

nlp文本建模算法This is part 3 of a 4 part post. Until now we have talked about:这是4部分帖子的第3部分。 到目前为止&#xff0c;我们一直在谈论&#xff1a; Pre-processing and Cleaning 预处理和清洁 Text Summarization 文字摘要 Topic Modeling using Latent Diric…...

wordpress 增加相册/推广产品最好的方式

我个人十分喜爱QT Creator的IDE界面与操作&#xff0c;但是也许是尚未完全成熟或者是为了代码跨平台&#xff0c;有些功能并没有直接提供。 比如Windows下做软件&#xff0c;至少作为主程序或启动程序的exe文件一般都应该有自己的图标&#xff0c;QT Creator虽然可以轻松地设置…...

平凉崆峒建设局网站/seo指导

?注意&#xff1a;按组合键前&#xff0c;先查询一下其功能&#xff0c;防止清空磁盘数据。 组合键说明 百度知道上的方法&#xff0c;自己都试过&#xff0c;没有效果。 解决方法&#xff1a; 参考mac开机卡在进度条的问题后面移动缓冲区的方法。关机后&#xff0c;按下电源键…...

怎么安装wordpress模板安装教程/免费seo网站推荐一下

如果白痴会飞&#xff0c;那我的公司简直是个机场。所有的男人生来平等&#xff0c;结婚的除外。咱们是否可以找个地方喝上一杯&#xff0c;交个朋友&#xff1f;或者说&#xff0c;还是我直接给把钱包给你&#xff1f;我想&#xff0c;只要我再稍微具有一些谦虚的品质&#xf…...

免费空间asp网站/企业网络营销策略

目录 目录软件环境RHEV简介RHEV与KVM的区别RHEV的组成RHEV-MManagerRHEV-HHypervisor 虚拟机管理程序存储RHEV的架构LDAPIPAADWeb ServicePostgreSQLVDSMJBoss软件环境 系统 RHEL 6.4软件 RHEV 3.1RHEV简介 RHEV(Red Hat Enterprise virtualization)红帽企业虚拟化&#xff0c;…...

如何做网站不容易被攻击/自己有货源怎么找客户

1.Perl的标量代表的是单数&#xff0c;列表和数组代表的是复数2.列表是标量的有序集、数组是包含列表的变量。3.列表是指数据&#xff0c;而数组是其变量名。4.可以有一些值&#xff08;列表&#xff09;但不属于数组&#xff1b;但每一个数组标量都有一个列表&#xff0c;虽然…...