数据结构在JavaScript中的体现

一.概述


        数据结构是计算机中存储、组织数据的方式。通常情况下,精心选择的数据结构可以带来最优效率的算法,其实算法并不是一个很高级的东西,它充斥在每一种代码组织方式中;而且各种语言关于数据结构方面的内容都是大同小异的,会了一种语言的数据结构方面的内容就可以快速掌握其它语言的的数据结构;有一部分人对JavaScript有偏见,觉得这种语言没有档次,但又有多少人在学完JavaScript敢说精通它。

二.见识数据结构


(1)>>数组


        你没有看错,常见的数组就是一种数据结构,对于数组就是掌握一下它的各种方法,如push(),pop(),shift(),unshift(),indexOf(),sort(),slice(),splice()等,在这里就不赘述了。

(2)>>栈


 A.图解

               遵循的是后进先出

  B.封装代码 

class Stack {//加#是为了保证其是私有属性,不让外界随意调用#items = [];pop() {return this.#items.pop()}push(data) {return this.#items.push(data)}//返回栈顶peek() {return this.#items.at(-1)}isEmpty() {return this.#items.length > 0 ? false : true}size() {return this.#items.length}clear() {this.#items = []}toString(){return this.#items.join(' ')}
}

C.应用场景

        将十进制数转换为其它进制的数时用到了辗转相除法,刚好是把得到的余数从后到前输出得到对应进制下的数,如果把这些数从前到后推到栈里,再取出来岂不妙哉。

function convert(decNumber, binaryNumber) {let number = decNumberlet stack = new Stack()let string = ''//防止转换成十六进制的时候乱码let baseString = '0123456789ABCDEF'while (number > 0) {stack.push(number % binaryNumber)number = Math.floor(number / binaryNumber)}while (!(stack.isEmpty())) {string += baseString[stack.pop()]}return string
}console.log(convert(50, 2));

(3)>>队列


 A.图解

        先进先出,后端进,前端出,类似于排队

 B.封装代码

             有缺点的封装方式
class Queue {#items = [];//一旦元素变多,还用shift会造成运行效率低deleteQueue() {return this.#items.shift()}enterQueue(data) {return this.#items.push(data)}//返回队头frontQueue() {return this.#items.at(0)}isEmpty() {return this.#items.length > 0 ? false : true}size() {return this.#items.length}clear() {this.#items = []}toString() {return this.#items.join(' ')}
}
        修正之后的封装方式 
class Queue {#items = {};#count = 0;#lowCount = 0;//出队deleteQueue() {if (this.isEmpty()) {return undefined}let res = this.#items[this.#lowCount]delete this.#items[this.#lowCount]this.#lowCount++return res}//进队enterQueue(data) {this.#items[this.#count] = datathis.#count++}//返回队头frontQueue() {return this.#items[this.#lowCount]}isEmpty() {return this.size === 0}size() {return this.#count - this.#lowCount}clear() {this.#items = {}this.#count = 0this.#lowCount = 0}toString() {let str = ""for (let i = this.#lowCount; i < this.#count; i++) {str += `${this.#items[i]} `}return str.trim()}
}

C.应用场景 

类似于击鼓传花,传指定次数,最终东西在谁手上谁淘汰,一直淘汰到队列里只剩一个人为最终的胜者

function game(list, num) {let queue = new Queue()for (let i = 0; i < list.length; i++) {queue.enterQueue(list[i])}while (queue.size() > 1) {for (i = 0; i < num; i++) {queue.enterQueue(queue.deleteQueue())}console.log(queue.deleteQueue(), '淘汰');}console.log(queue.deleteQueue());//最终获胜者return queue.deleteQueue()
}game(['aks', 'uej', 'jsm', 'duj', 'llq'], 7)

D.双端队列

与一般的队列有所不同的情况是,可以从队头进队,队尾可以出队,简而言之就是两端都能进出队伍。

class DeQueue {#items = {};#count = 0;#lowCount = 0;removeFront() {if (this.isEmpty()) {return undefined}let res = this.#items[this.#lowCount]delete this.#items[this.#lowCount]this.#lowCount++return res}addBack(data) {this.#items[this.#count] = datathis.#count++}//在队头添加addFront(data) {if (this.isEmpty()) {this.addBack()} else {if (this.#lowCount > 0) {this.#lowCount--this.#items[this.#lowCount] = data} else {for (let i = this.#count; i > 0; i--) {this.#items[i] = this.#items[i - 1]}this.#items[0] = datathis.#count++}}}//在队尾删除removeBack() {if (this.isEmpty()) {return} else {this.#count--let res = this.#items[this.#count]delete this.#items[this.#count]return res}}//返回队头peekFront() {return this.#items[this.#lowCount]}//返回队尾peekBack() {return this.#items.at(-1)}isEmpty() {return this.size === 0}size() {return this.#count - this.#lowCount}clear() {this.#items = {}this.#count = 0this.#lowCount = 0}toString() {let str = ""for (let i = this.#lowCount; i < this.#count; i++) {str += `${this.#items[i]} `}return str.trim()}
}//回文应用
function test(str) {//将输入有空格的字符串转化为无空格的const lowStr = str.toLocaleLowerCase().split(' ').join('') let dequeue = new DeQueue()for (let i = 0; i < lowStr.length; i++) {dequeue.addBack(lowStr[i])}while (dequeue.size() > 1) {if (dequeue.removeFront() !== dequeue.removeBack()) {console.log('不是回文');break} else {console.log('是回文结构');}}
}test('dadadb') //不是回文

(4)>>链表


1.单链表

A.图解

        可以把next看成一个指针,其能指向表中下一个存储的数据

B.封装代码
//根据节点的需要创建相应的元素
class Node {constructor(element) {this.element = elementthis.next = null}
}
//单链表
class LinkList {constructor() {this.head = nullthis.count = 0}//从表尾放入新节点push(element) {const node = new Node(element)if (this.head === null) {this.head = node} else {let current = this.headwhile (current.next != null) {current = current.next}current.next = node}this.count++}size() {return this.count}isEmpty() {return this.size() === 0}//指定位置删除removeAt(index) {if (index >= 0 && index < this.count) {let current = this.headif (index === 0) {this.head = this.head.next} else {let previousfor (let i = 0; i < index; i++) {previous = currentcurrent = current.next}previous.next = current.next}this.count--return current.element}return undefined}//同样也是指定位置删除,但用到了后面封装的getNodeAt方法removeAt2(index) {if (index >= 0 && index < this.count) {let current = this.headif (index === 0) {this.head = this.head.next} else {let previous = this.getNodeAt(index - 1)current = previous.nextprevious.next = current.next}this.count--return current.element}return undefined}//根据索引值找到相应的节点getNodeAt(index) {if (index >= 0 && index < this.count) {let node = this.headfor (let i = 0; i < index; i++) {node = node.next}return node}return undefined}indexOf(element) {let current = this.headfor (let i = 0; i < this.count; i++) {//防止其直接输入一个对象变量if (JSON.stringify(element) === JSON.stringify(current.element)) {return i}current = current.next}return -1}//指定元素删除remove(element) {let index = this.indexOf(element)let removeElement = this.removeAt(index)return removeElement}insert(element, index) {if (index >= 0 && index <= this.count) {const node = new Node(element)if (index === 0) {let current = this.headnode.next = currentthis.head = nodethis.count++} else {let previous = this.getNodeAt(index - 1)let current = previous.nextprevious.next = nodenode.next = currentthis.count++}return true}return false}
}

2.双向链表

A.图解        

节点除了存储数据以外,还有两个指针分别指向前一个节点地址(prev)和下一个节点地址(next) 

B.封装代码
//前人栽树,后人乘凉,继承自之前的Node类
class DoubleNode extends Node {constructor(element) {super(element)this.prev = null}
}//继承自LinkList类加方法重写
class DoubleLinkList extends LinkList {constructor() {super()this.tail = null}push(element) {const doubleNode = new DoubleNode(element)if (this.head === null) {this.head = doubleNodethis.tail = doubleNode} else {this.tail.next = doubleNodedoubleNode.prev = this.tailthis.tail = doubleNode}this.count++}insert(element, index) {if (index >= 0 && index <= this.count) {const doubleNode = new DoubleNode(element)if (index === 0) {//分链表是否有元素if (this.head === null) {this.head = doubleNodethis.tail = doubleNode} else {this.head.prev = doubleNodedoubleNode.next = this.headthis.head = doubleNode}} else if (index === this.count) {this.tail.next = doubleLinkListdoubleLinkList.prev = this.tailthis.tail = doubleLinkList} else {let previouslet current = this.headfor (let i = 0; i < index; i++) {current = current.nextprevious = current.prev}current.prev = doubleNodedoubleNode.next = currentdoubleNode.prev = previousprevious.next = doubleNode}this.count++return true}return false}removeAt(index) {if (index >= 0 && index < this.count) {let current = this.headif (index === 0) {this.head = current.nextif (this.count === 1) {this.tail = null} else {this.head.prev = null}} else if (index === this.count - 1) {current = this.tailthis.tail = current.prevthis.tail.next = null} else {current = this.getNodeAt(index)let previous = current.prevlet future = current.nextprevious.next = futurefuture.prev = previous}this.count--return current.element}return undefined}}

3.循环链表 

A.图解

B.封装代码
//循环链表类继承自单链表类
class CirculateLinkList extends LinkList {constructor() {super()}push(element) {const node = new Node(element)let currentif (this.head === null) {this.head = node} else {current = this.getNodeAt(this.size() - 1)current.next = node}node.next = this.headthis.count++}insert(element, index) {if (index >= 0 && index <= this.count) {const node = new Node(element)let current = this.headif (index === 0) {if (this.head === null) {this.head = nodenode.next = this.head} else {node.next = this.headcurrent = this.getNodeAt(this.size() - 1)this.head = nodecurrent.next = node}} else {if (index === this.count) {current = this.getNodeAt(index - 1)current.next = nodenode.next = this.head} else {let previous = this.getNodeAt(index - 1)previous.next = nodenode.next = previous.next}}this.count++return true}return false}removeAt(index) {if (index >= 0 && index < this.count) {let current = this.headif (index === 0) {if (this.count === 1) {this.head = null} else {let last = this.getNodeAt(this.size() - 1)this.head = current.nextlast.next = this.head}} else {let previous = this.getNodeAt(index - 1)current = previous.nextprevious.next = current.next}this.count--return current.element}return undefined}
}

(5)>>集合


Set结构,其实已经是JavaScript里封装好的,它是以值:值进行存储,且存入的值不能够重复

A.封装代码
class Set {items = {}add(element) {if (!this.has(element)) {this.items[element] = elementreturn true}return false}delete(element) {if (this.has(element)) {delete this.items[element]return true}return false}has(element) {return element in this.items}clear() {this.items = {}}size() {return Object.keys(this.items).length}values() {return Object.values(this.items)}
}const mySet = new Set()
let arr = [2, 1, 3, 3, 4, 5, 2, 1]
arr.forEach((item) => {mySet.add(item)
})
console.log(mySet.values());//[ 1, 2, 3, 4, 5 ]
 B.原装set使用

Set结构生成的是一个迭代器的结构,并且由于是集合,可以进行相关的并集交集差集等运算,可以进行相关的,详细的相关使用请查看下方代码

let mySet = new Set()
mySet.add(1)
mySet.add(2)
mySet.add(3)let item = mySet.values() //生成的是一个迭代器
console.log(item); //[Set Iterator] { 1, 2, 3 }
console.log(item.next()); //{ value: 1, done: false }
console.log(item.next()); //{ value: 2, done: false }
console.log(item.next()); //{ value: 3, done: false }// for (let i of item) {
//     console.log(i);
// } //1 2 3// console.log([...item]);   //[ 1, 2, 3 ]// const A = new Set([1, 2, 3, 4])
// const B = new Set([2, 3, 4, 5])
// //取并集
// const C = new Set([...A, ...B])
// console.log(C);  //Set(5) { 1, 2, 3, 4, 5 }// //取交集
// const D = new Set([...A].filter(item => B.has(item)))
// console.log(D);  //Set(3) { 2, 3, 4 }// //取差集
// const E = new Set([...A].filter(item => !B.has(item)))
// console.log(E);  //Set(1) { 1 }

(6)>>字典

字典和集合很相似,集合以[值,值]的形式存储元素,字 典则是以[键,值]的形式来存储元素。字典也称作映射、符号表或关联数组。

A.字典的封装

class Dictionary {table = {}//保证当存入的键是对象的时候,强制它转换为json字符串的形式toStrFn(item) {if (item === null) {return "null"} else if (item === undefined) {return "undefined"} else if (typeof item === 'string' || item instanceof String) {return item}return JSON.stringify(item)}hasKey(key) {return this.table[this.toStrFn(key)] != null}set(key, value) {if (key != null && value != null) {const tableKey = this.toStrFn(key)// this.table[tableKey] = valuethis.table[tableKey] = new ValuePair(key, value)return true}return false}get(key) {let result = this.table[this.toStrFn(key)]return result == null ? undefined : result.value}remove(key) {if (this.hasKey(key)) {delete this.table[this.toStrFn(key)]return true}return false}keys() {return this.keyValues().map(item => item.key)}values() {return this.keyValues().map(item => item.value)}keyValues() {return Object.values(this.table)}size() {return Object.keys(this.table).length}isEmpty() {return this.size() === 0}clear() {this.table = {}}forEach(ch) {const valuePair = this.keyValues()for (let i = 0; i < valuePair; i++) {ch(valuePair[i].key, valuePair[i].value)}}
}class ValuePair {constructor(key, value) {this.key = keythis.value = value}
}

B.散列表

HashMap 类,它是 Dictionary 类的一种散列表 实现方式。.散列算法的作用是尽可能快地在数据结构中找到一个值。这样在面对海量数据的时候可以加快查询的速度

class HashTable {table = {}toStrFn(item) {if (item === null) {return "null"} else if (item === undefined) {return "undefined"} else if (typeof item === 'string' || item instanceof String) {return item}return JSON.stringify(item)}// hashCode(key) {//     if (typeof key === 'number') {//         return key//     } else {//         const tableKey = this.toStrFn(key)//         let hash = 0//         for (let i = 0; i < tableKey.length; i++) {//             hash += tableKey.charCodeAt(i)//         }//         return hash % 35//     }// }//将对应字符串或对象转成的字符串的ASCII值进行转换生成相应的数值hashCode(key) {const tableKey = this.toStrFn(key)let hash = 5381for (let i = 0; i < tableKey.length; i++) {hash = (hash * 33) + tableKey.charCodeAt(i)}return hash % 1013}set(key, value) {if (key != null && value != null) {let position = this.hashCode(key)this.table[position] = new ValuePair(key, value)}}get(key) {let result = this.table[this.hashCode(key)]return result == null ? undefined : result.value}remove(key) {if (this.table[this.hashCode(key)] != null) {delete this.table[this.hashCode(key)]return true}return false}
}class ValuePair {constructor(key, value) {this.key = keythis.value = value}
}

3.ES6中的Map

var mymap = new Map()
mymap.set("name","kerwin")
mymap.set({a:1},"aaaaaa")mymap.get("name")
mymap.delete("name")

 (7)>>树


树是一种分层数据的抽象模型。

 1.二叉树

         二叉树中的节点最多只能有两个子节点:一个是左侧子节点,另一个是右侧子节点。

2.二叉搜索树

        二叉搜索树(BST)是二叉树的一种,但是只允许你在左侧节点存储(比父节点)小的值, 在右侧节点存储(比父节点)大的值。

  >>关于遍历

  • 中序遍历是一种以上行顺序访问 BST 所有节点的遍历方式,也就是以从最小到最大的顺序 访问所有节点。 中序遍历的一种应用就是对树进行排序操作。

  • 先序遍历是以优先于后代节点的顺序访问每个节点的。先序遍历的一种应用是打印一个结构 化的文档。(访问根节点,遍历左子树,遍历右子树)

  • 后序遍历则是先访问节点的后代节点,再访问节点本身。后序遍历的一种应用是计算一个目 录及其子目录中所有文件所占空间的大小。(简而言之就是在树中从最末尾的那一代开始从左到右打印,一直到整个树都被遍历完成)

>>关于移除要考虑的情况

A.封装代码
class Node {constructor(key) {this.key = keythis.left = nullthis.right = null}
}class BST {constructor() {this.root = null}insert(key) {if (this.root == null) {this.root = new Node(key)} else {this.insertNode(this.root, key)}}insertNode(node, key) {if (this.compareFn(key, node.key) === -1) {if (node.left == null) {node.left = new Node(key)} else {this.insertNode(node.left, key)}} else {if (node.right == null) {node.right = new Node(key)} else {this.insertNode(node.right, key)}}}compareFn(a, b) {if (a === b) {return 0}return a < b ? -1 : 1}//中序遍历,注意递归调用的顺序middleMap(callback) {this.middleMapNode(this.root, callback)}middleMapNode(node, callback) {if (node != null) {this.middleMapNode(node.left, callback)callback(node.key)this.middleMapNode(node.right, callback)}}//先序遍历prevMap(callback) {this.prevMapNode(this.root, callback)}prevMapNode(node, callback) {if (node != null) {callback(node.key)this.prevMapNode(node.left, callback)this.prevMapNode(node.right, callback)}}//后序遍历behindMap(callback) {this.behindMapNode(this.root, callback)}behindMapNode(node, callback) {if (node != null) {this.behindMapNode(node.left, callback)this.behindMapNode(node.right, callback)callback(node.key)}}min() {return this.minNode(this.root)}minNode(node) {let current = nodewhile (current != null && current.left != null) {current = current.left}return current.key}max() {return this.maxNode(this.root)}maxNode(node) {let current = nodewhile (current != null && current.right != null) {current = current.right}return current.key}search(key) {return this.searchNode(this.root, key)}searchNode(node, key) {if (node === null) {return false}if (this.compareFn(key, node.key) === -1) {return this.searchNode(node.left, key)} else if (this.compareFn(key, node.key) === 1) {return this.searchNode(node.right, key)} else {return true}}remove(key) {this.removeNode(this.root, key)}removeNode(node, key) {if (node == null) {return null}if (this.compareFn(key, node.key) === -1) {node.left = this.removeNode(node.left, key)console.log(node);return node} else if (this.compareFn(key, node.key) === 1) {node.right = this.removeNode(node.right, key)console.log(node);return node} else {if (node.left == null && node.right == null) {node = nullreturn node}if (node.left == null) {node = node.rightreturn node} else if (node.right == null) {node = node.leftreturn node}const target = this.minNode(node.right)node.key = target.keynode.right = this.removeNode(node.right, target.key)return node}}
}const tree = new BST()
tree.insert(6)
tree.insert(4)
tree.insert(8)
tree.insert(3)
tree.insert(5)
tree.middleMap((value) => console.log(value)) //3 4 5 6 8
tree.prevMap((value) => console.log(value))   //6 4 3 5 8
tree.behindMap((value) => console.log(value)) //3 5 4 8 6

(8)>>二叉堆

二叉堆是一种特殊的二叉树,有两种特性

  • 它是一棵完全二叉树,表示树的每一层都有左侧和右侧子节点(除了最后一层的叶节点), 并且最后一层的叶节点尽可能都是左侧子节点,这叫作结构特性。

  • 二叉堆不是最小堆就是最大堆。最小堆允许你快速导出树的最小值,最大堆允许你快速 导出树的最大值。所有的节点都大于等于(最大堆)或小于等于(最小堆)每个它的子 节点。这叫作堆特性。

1.最小堆

//把二叉堆的数据按数组的格式存储起来
class minHeap {heap = []//根据现有节点计算左子节点getLeftSonIndex(index) {return 2 * index + 1}getRightSonIndex(index) {return 2 * index + 2}getParentIndex(index) {if (index === 0) {return undefined} else {return Math.floor((index - 1) / 2)}}insert(value) {if (value != null) {this.heap.push(value)this.shiftUp(this.heap.length - 1)return true}return false}shiftUp(index) {let parent = this.getParentIndex(index)while (index > 0 && this.compareFn(this.heap[parent], this.heap[index]) === 1) {this.swap(this.heap, parent, index)index = parentparent = this.getParentIndex(index)}}compareFn(a, b) {if (a === b) {return 0}return a < b ? -1 : 1}swap(arr, a, b) {let temp = arr[a]arr[a] = arr[b]arr[b] = temp}size() {return this.heap.length}isEmpty() {return this.size() === 0}findMinimun() {return this.heap[0]}//去除根节点及后面的操作extractFirst() {if (this.isEmpty()) {return undefined}if (this.size() === 1) {return this.heap.shift()}const removedValue = this.heap[0]this.heap[0] = this.heap.pop()this.shiftDown(0)return removedValue}shiftDown(index) {let current = indexlet left = this.getLeftSonIndex(index)let right = this.getRightSonIndex(index)if (left < this.size() && this.compareFn(this.heap[current], this.heap[left]) === 1) {current = left}if (right < this.size() && this.compareFn(this.heap[current], this.heap[right]) === 1) {current = right}if (index !== current) {this.swap(this.heap, index, current)this.shiftDown(current)}}
}

2.最大堆

可以偷个懒,直接继承并随便改写一下比较两数大小的方法


class maxHeap extends minHeap {constructor() {super()}compareFn(a, b) {if (a === b) {return 0}return a > b ? -1 : 1}
}

三.总结

        数据结构是个神奇的东西,它充斥在代码中,却仿佛离我们那么遥远,学习数据结构不仅是在面对不同的数据时要施加不同的策略,而且可以提高我们的代码阅读能力。当然了,对于数据结构的学习依然任重而道远,各位同仁加油吧,希望可以点赞收藏加关注嘿嘿。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/682561.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【复现】某某ERP 信息泄露漏洞_49

目录 一.概述 二 .漏洞影响 三.漏洞复现 1. 漏洞一&#xff1a; 四.修复建议&#xff1a; 五. 搜索语法&#xff1a; 六.免责声明 一.概述 该ERP基于SpringBoot框架和SaaS模式&#xff0c;立志为中小企业提供开源好用的ERP软件&#xff0c;目前专注进销存财务生产功能。…

七天入门大模型 :LLM大模型基础知识最全汇总

七天入门LLM大模型学习 旨在帮助初学者理解和学习LLM的基础概念和实践。 未来七天&#xff0c;我将每天为大家推出一篇课程内容&#xff0c;感兴趣的小伙伴们可关注我们 文章目录 技术交流群用通俗易懂方式讲解系列基础模型研究模型定制新范式LLM类型介绍多模态模型Agent模型C…

【MySQL】待修改

外键约束 含义 外键&#xff1a;用来让两张表的数据之间建立连接&#xff0c;从而保证数据的完整性和一致性。 员工表emp&#xff08;子表&#xff09; idnameagejobsalaryentrydatemanageriddept_id1金庸66总裁200002000-01-01null52张无忌20项目经理125002005-12-05113杨…

lv15 平台总线驱动开发——ID匹配 3

一、ID匹配之框架代码 id匹配&#xff08;可想象成八字匹配&#xff09;&#xff1a;一个驱动可以对应多个设备 ------优先级次低&#xff08;上一章名称匹配只能1对1&#xff09; 注意事项&#xff1a; device模块中&#xff0c;id的name成员必须与struct platform_device中…

猫头虎分享已解决Bug || ValueError: No gradients provided for any variable

博主猫头虎的技术世界 &#x1f31f; 欢迎来到猫头虎的博客 — 探索技术的无限可能&#xff01; 专栏链接&#xff1a; &#x1f517; 精选专栏&#xff1a; 《面试题大全》 — 面试准备的宝典&#xff01;《IDEA开发秘籍》 — 提升你的IDEA技能&#xff01;《100天精通鸿蒙》 …

2019年通信工程师初级 实务 真题

文章目录 一、第9章 通信动力与环境通信电源系统的主要功能&#xff1a;“供”、“配”、“储”、“发”、“变” 二、第2章 传输网三、第3章 接入网四、第4章 互联网 一、第9章 通信动力与环境 【问题一】 网络通信设备对动力与环境的质量要求可以归纳为 &#xff08;1&#…

计算机服务器中了360后缀勒索病毒怎么办?360后缀勒索病毒处理流程

网络技术的不断应用与发展&#xff0c;为企业的生产运营提供了有利保障&#xff0c;越来越多的企业走向数字化办公模式&#xff0c;并且企业的发展离不开数据支撑&#xff0c;重视数据安全成为了众多企业关心的主要话题。春节前后&#xff0c;云天数据恢复中心接到很多企业的求…

C++:IO流

目录 关于CIO流 C/C中的日期输入 连续输入的问题 C文件IO流 运算符>>的运用 二进制读写 文本读写 stringstream 关于CIO流 C系统中ios为基类&#xff0c;其他类都是直接或间接派生自ios类 C标准库提供了4个全局流对象cin、cout、cerr、clog (在使用时候必须要包…

LeetCode刷题计划

LeetCode刷题计划 推荐 代码随想录&#xff1a;https://github.com/youngyangyang04/leetcode-master 卡码网 练习ACM模式 https://kamacoder.com/ 01 #include <iostream> using namespace std;int main() {int a ,b;while(cin>>a>>b){cout<<ab<…

【AI视野·今日CV 计算机视觉论文速览 第293期】Fri, 19 Jan 2024

AI视野今日CS.CV 计算机视觉论文速览 Fri, 19 Jan 2024 Totally 103 papers &#x1f449;上期速览✈更多精彩请移步主页 Daily Computer Vision Papers ParaHome: Parameterizing Everyday Home Activities Towards 3D Generative Modeling of Human-Object Interactions Aut…

PyTorch深度学习快速入门教程 - 【小土堆学习笔记】

小土堆Pytorch视频教程链接 声明&#xff1a; 博主本人技术力不高&#xff0c;这篇博客可能会因为个人水平问题出现一些错误&#xff0c;但作为小白&#xff0c;还是希望能写下一些碰到的坑&#xff0c;尽力帮到其他小白 1 环境配置 1.1 pycharm pycharm建议使用2020的&…

petalinux2018.3安装步骤

1、虚拟机安装ubuntu-16.04.7-desktop-amd64.iso &#xff08;注意&#xff1a;安装ubuntu-18.04.6-desktop-amd64.iso和ubuntu-16.04.6-desktop-i386.iso会报以下错误&#xff09; environment: line 314: ((: 10 #15~1 > 10 #3: syntax error in expression (error toke…

Excel

1、Excel的学习路径 2、掌握excel的基础要求 01、保证新版本 02、培养好的数据表格习惯 03、主动性探索 04、多联系 一、函数 二、文本清洗函数 三、常见文本的清洗函数 获取k的位置 FIND("k",P2,1) 从第1个位置开始在位置P2&#xff0c;查询字段k&#x…

Java+SpringBoot+Vue:高校科研管理的技术革新

✍✍计算机编程指导师 ⭐⭐个人介绍&#xff1a;自己非常喜欢研究技术问题&#xff01;专业做Java、Python、微信小程序、安卓、大数据、爬虫、Golang、大屏等实战项目。 ⛽⛽实战项目&#xff1a;有源码或者技术上的问题欢迎在评论区一起讨论交流&#xff01; ⚡⚡ Java实战 |…

ChatGPT高效提问—prompt实践(智能开发)

ChatGPT高效提问—prompt实践&#xff08;智能开发&#xff09; ​ 如果你是一名程序员&#xff0c;一定有过这样的经历&#xff1a;排查某个bug话费好几个小时&#xff0c;在各个搜索引擎尝试搜索&#xff0c;浏览了几十甚至上百个网站&#xff0c;结果搜到的答案千篇一律&am…

websocket简易基操

一、概述 1.1 简介 WebSocket是HTML5下一种新的协议&#xff08;websocket协议本质上是一个基于tcp的协议&#xff09;&#xff0c;它实现了浏览器与服务器全双工通信&#xff0c;能更好的节省服务器资源和带宽并达到实时通讯的目的&#xff0c;Websocket是一个持久化的协议。…

【STM32 CubeMX】GPIO的工作模式

文章目录 前言一、有哪些工作模式&#xff1f;1.1 GPIO的详细介绍1.2 GPIO的内部框图输入模式输出部分 总结 前言 在嵌入式系统开发中&#xff0c;对于STM32微控制器的GPIO&#xff08;General Purpose Input/Output&#xff09;引脚的配置和使用是至关重要的。GPIO引脚可以通…

【解决】配置文件YAML: application.yml Cannot resolve configuration property ‘xxxx‘

配置文件YAML: application.yml Cannot resolve configuration property xxxx 问题排查解决 问题 在application.yml文件里面配置Bean的初始值&#xff0c;但是报错如下&#xff1a; Cannot resolve configuration property person.lastName 排查 我们先去Bean检查是否拼写…

基于函数计算AIGC图片识别

目录 在 OSS 中建立图片目录 在函数计算中基于模板创建ImageAI应用 体验ImageAI图像识别效果 我们不但可以基于函数计算创建AIGC应用&#xff0c;实现以文生图&#xff0c;同时我们也可以基于函数计算创建ImageAI应用&#xff0c;通过简单几步实现对图片中对象的识别。下面我…

【运维测试】测试理论+工具总结笔记第1篇:测试理论的主要内容(已分享,附代码)

本系列文章md笔记&#xff08;已分享&#xff09;主要讨论测试理论测试工具相关知识。Python测试理论的主要内容&#xff0c;掌握软件测试的基本流程&#xff0c;知道软件测试的V和W模型的优缺点&#xff0c;掌握测试用例设计的要素&#xff0c;掌握等价类划分法、边界值法、因…