数据结构与算法--javascript(持续更新中...)

news2024/11/18 8:24:02

一. 概论

1. 数据结构
队列:一种遵循先进先出 (FIFO / First In First Out) 原则的一组有序的项;队列在尾部添加新元素,并从头部移除元素。最新添加的元素必须排在队列的末尾。(例如:去食堂排队打饭,排在前面的人先打到饭,先离开;排在后面的人后打到饭,后离开。)
在这里插入图片描述
栈:一种遵从先进后出 (LIFO) 原则的有序集合;新添加的或待删除的元素都保存在栈的末尾,称作栈顶,另一端为栈底。在栈里,新元素都靠近栈顶,旧元素都接近栈底。(例如:往口袋里面装东西,先装进去的放在最下面,后装进去的放在最上面,取出的时候只能从上往下取。)
在这里插入图片描述
在这里插入图片描述
链表:存储有序的元素集合,但不同于数组,链表中的元素在内存中并不是连续放置的;每个元素由一个存储元素本身的节点和一个指向下一个元素的引用(指针/链接)组成。
在这里插入图片描述
集合:由一组无序且唯一(即不能重复)的项组成;这个数据结构使用了与有限集合相同的数学概念,但应用在计算机科学的数据结构中。

字典:以 [键,值] 对为数据形态的数据结构,其中键名用来查询特定元素,类似于 Javascript 中的Object。

哈希表:根据关键码值(Key value)而直接进行访问的数据结构。通过把关键码值映射到表中某个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫散列表。
给定表M,存在函数f(key),对任意给定的关键字值key,代入函数后若能得到包含该关键字的记录在表中的地址,则称表M为哈希(Hash)表,函数f(key)为哈希(Hash) 函数。

树:由 n(n>=1)个有限节点组成一个具有层次关系的集合;把它叫做“树”是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的,基本呈一对多关系,树也可以看做是图的特殊形式。

图:图是网络结构的抽象模型;图是一组由边连接的节点(顶点);任何二元关系都可以用图来表示,常见的比如:道路图、关系图,呈多对多关系。

2. 算法
排序算法:
冒泡排序(升序):逐一比较相邻两个元素,如果前面的元素比后面的元素大则交换两者顺序;元素项向上移动至正确的顺序,好似气泡上升至表面一般,因此得名。(冒泡排序每一轮至少有一个元素会出现在正确位置)

快速排序(升序):选择一个基准值,每一个元素与基准值比较。比基准值小的元素放在基准值左边,比基准值大的元素放在基准值右边,左右两边递归执行此操作。通常选择中间的元素作为基准值。

选择排序:每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,以此循环,直至排序完毕。

插入排序:将一个数据插入到已经排好序的有序数据中,从而得到一个新的、个数加一的有序数据,此算法适用于少量数据的排序。

归并排序:将原始序列切分成较小的序列,只到每个小序列无法再切分,然后执行合并,即将小序列归并成大的序列,合并过程进行比较排序,只到最后只有一个排序完毕的大序列,时间复杂度为 O(n log n)。
在这里插入图片描述
各种时间复杂度的直观比较:
在这里插入图片描述
在这里插入图片描述
搜索算法:
顺序搜索:让目标元素与列表中的每一个元素逐个比较,直到找出与给定元素相同的元素为止,缺点是效率低下。

二分搜索:在一个有序列表,以中间值为基准拆分为两个子列表,拿目标元素与中间值作比较从而再在目标的子列表中递归此方法,直至找到目标元素。

其他算法:
贪心算法:在对问题求解时,不考虑全局,总是做出局部最优解的方法。

动态规划:在对问题求解时,由以求出的局部最优解来推导全局最优解。

复杂度概念:一个方法在执行的整个生命周期,所需要占用的资源,主要包括:时间资源、空间资源。

二. 数据结构

队列
概念:一种遵循先进先出 (FIFO / First In First Out) 原则的一组有序的项;队列在尾部添加新元素,并从头部移除元素。最新添加的元素必须排在队列的末尾。

在 Javascript 中实现一个队列类。
1.创建一个类:

class Queue{
	 constructor(items) {
        this.items = items || []
    }
	
	// 1. 在末尾添加元素
	enqueue(element){
        this.items.push(element)
    }
	
	// 2. 在头部删除元素
	dequeue(){
        return this.items.shift()
    }
	
	// 3. 获取头部元素
	front(){
        return this.items[0]
    }

	// 4. 获取队列长度
	get size(){
        return this.items.length
    }

	// 5. 判断是否是空队列
	 get isEmpty(){
        return !this.items.length
    }

	// 6. 清空队列
	clear(){
        this.items = []
    }
}

2.使用类:

const queue = new Queue()  // 类的实例化
queue.isEmpty  // true

queue.enqueue('John')   // {items: ['John']}
queue.enqueue('Jack')   // {items: ['John','Jack']}
queue.enqueue('Camila')  // {items: ['John','Jack','Camila']}

queue.size  // 3
queue.isEmpty  // false

queue.dequeue()   // John
queue.dequeue()   // Jack
queue.dequeue()   // Camila

优先队列
概念元素的添加和移除是基于优先级的,不在满足完全意义的先进先出。例如机场登机的顺序,头等舱和商务舱乘客的优先级要高于经济舱乘客,这些乘客不需要通过正常排队登机。或是去医院看病,医生也会根据病情程度优先处理病情严重的。

在 Javascript 中实现一个队列类:
1.创建一个类:

class PriorityQueue {

    constructor() {
        this.items = []
    }

    enqueue(element, priority){
        const queueElement = { element, priority }
        if (this.isEmpty) {
            this.items.push(queueElement)
        } else {
// 在列表中找到第一个比后进入的元素的priority大的元素的位置,如果有,将这个元素插入这里。如果没有,将这个元素放在最后面。
            const preIndex = this.items.findIndex((item) => queueElement.priority < item.priority)
            if (preIndex > -1) {
                this.items.splice(preIndex, 0, queueElement)
            } else {
                this.items.push(queueElement)
            }
        }
    }

    dequeue(){
        return this.items.shift()
    }

    front(){
        return this.items[0]
    }

    clear(){
        this.items = []
    }

    get size(){
        return this.items.length
    }

    get isEmpty(){
        return !this.items.length
    }

    print() {
        console.log(this.items)
    }
}

2.使用类:

const priorityQueue = new PriorityQueue()
priorityQueue.enqueue('Wangjiajia', 2) // {items: [{element: 'Wangjiajia', priority: 2}]}
priorityQueue.enqueue('Wangtongtong', 1) // {items: [{element: 'Wangtongtong', priority: 1},{element: 'Wangjiajia', priority: 2}]}
priorityQueue.enqueue('Davide', 4)  // {items: [{element: 'Wangtongtong', priority: 1},{element: 'Wangjiajia', priority: 2},{element: 'Davide', priority: 4}]}
priorityQueue.enqueue('Tom', 3)  // {items: [{element: 'Wangtongtong', priority: 1},{element: 'Wangjiajia', priority: 2},{element: 'Tom', priority: 3},{element: 'Davide', priority: 4}]}
priorityQueue.enqueue('James', 2)  // {items: [{element: 'Wangtongtong', priority: 1},{element: 'Wangjiajia', priority: 2},{element: 'James', priority: 2},{element: 'Tom', priority: 3},{element: 'Davide', priority: 4}]}

循环队列
概念:为充分利用向量空间,克服"假溢出"现象将向量空间想象为一个首尾相接的圆环,并称这种向量为循环向量。存储在其中的队列称为循环队列(Circular Queue)。通俗来说:循环队列是把顺序队列首尾相连,把存储队列元素的表从逻辑上看成一个环,成为循环队列。
假溢出: 队列的空间未利用完,但是却造成了元素的溢出。
在这里插入图片描述
基于首次实现的队列类,简单实现一个循环引用的示例:

class LoopQueue extends Queue {

    constructor(items) {
        super(items)
    }

    getIndex(index) {
        const length = this.items.length
        return index > length ? (index % length) : index
    }

    find(index) {
        return !this.isEmpty ? this.items[this.getIndex(index)] : null
    }
}

使用:

const loopQueue = new LoopQueue(['Surmon'])
loopQueue.enqueue('SkyRover')
loopQueue.enqueue('Even')
loopQueue.enqueue('Alice')
console.log(loopQueue.size, loopQueue.isEmpty) // 4 false

(loopQueue.find(26) // 'Evan'
(loopQueue.find(87651) // 'Alice'

栈:
概念:一种遵从先进后出 (LIFO) 原则的有序集合;新添加的或待删除的元素都保存在栈的末尾,称作栈顶,另一端为栈底,出去的时候从栈顶开始出去。在栈里,新元素都靠近栈顶,旧元素都接近栈底。`

用javascript基于数组的方法实现一个栈的功能:

class Stack {

    constructor() {
        this.items = []
    }

    // 入栈
    push(element) {
         this.items.push(element)
    }

    // 出栈
    pop() {
        return this.items.pop()
    }

    // 末位
    get peek() {
        return this.items[this.items.length - 1]
    }

    // 是否为空栈
    get isEmpty() {
        return !this.items.length
    }

    // 尺寸
    get size() {
        return this.items.length
    }

    // 清空栈
    clear() {
        this.items = []
    }

    // 打印栈数据
    print() {
        console.log(this.items.toString())
    }
}

使用栈:

// 实例化一个栈
const stack = new Stack()
console.log(stack.isEmpty) // true

// 添加元素
stack.push(5)   // [5]
stack.push(8)   // [5,8]

// 读取属性再添加
console.log(stack.peek) // 8
stack.push(11)  // [5,8,11]
stack.pop()  // 11
console.log(stack.size) // 3
console.log(stack.isEmpty) // false

链表:
概念:存储有序的元素集合,但不同于数组,链表中的元素在内存中并不是连续放置的;每个元素由一个存储元素本身的节点和一个指向下一个元素的引用(指针/链接)组成
分类:单向链表,双向链表,循环链表
链表和数组的区别
* 数组在添加或者删除元素的时候需要移动其他元素,链表不需要。链表需要使用指针,因此使用的时候需要额外注意一下。
* 数组可以访问其中任何一个元素,链表需要从头开始迭代,直到找到所需的元素。

链表的常见方法:
1、append(element):向列表尾部添加一个新的项
2、insert(position, element):向列表的特定位置插入一个新的项。
3、remove(element):从列表中移除一项。
4、removeAt(position):从列表的特定位置移除一项。
5、indexOf(element):返回元素在列表中的索引。如果列表中没有该元素则返回-1。
6、getElementAt(index): 返回链表中特定位置的元素, 如果不存在这样的元素则返回undefined
7、isEmpty():如果链表中不包含任何元素,返回true,如果链表长度大于0则返回false。
8、size():返回链表包含的元素个数。与数组的length属性类似。
9、toString():由于列表项使用了Node类,就需要重写继承自JavaScript对象默认的toString方法,让其只输出元素的值element。

整体操作方法和数组非常类似, 因为链表本身就是一种可以代替数组的结构.
使用javascript描述一个单向链表

单向链表:
在这里插入图片描述
生活中的例子:火车就可以看做链表,每一节都是由一节车厢和车厢之间的连接带组成,这个连接带就可以看成是指针。
在这里插入图片描述
用javascript来描述一个单向链表:

// 链表节点
class Node {
    constructor(element) {
        this.element = element
        this.next = null
    }
}

// 单向链表
class LinkedList {
    constructor() {
        this.head = null
        this.length = 0
    }

    // 1. 追加元素
    // 向链表尾部追加数据可能有两种情况:
	// 链表本身为空, 新添加的数据是唯一的节点.
	// 链表不为空, 需要向其他节点后面追加节点.
    append(element) {
        const node = new Node(element)
        let current = null
        // 链表本身为空, 新添加的数据是唯一的节点.
        if (this.head === null) {
            this.head = node
        } else {
       		// 链表不为空, 需要向其他节点后面追加节点.
            current = this.head
            while(current.next) {
                current = current.next
            }
            current.next = node
        }
        this.length++
    }

    // 2. 任意位置插入元素
    insert(position, element) {
        // 1.检测越界问题: 越界插入失败, 返回false
    	if (position < 0 || position > this.length) return false

	    // 2.找到正确的位置, 并且插入数据
	    // 定义要插入的变量newNode, current当前节点, previous上一个节点
	    let newNode = new Node(element)
	    let current = this.head // 初始值为head, 对第一个元素的引用
	    let previous = null // 存储当前current的上一个节点
	    let index = 0  // 位置
	
	    // 3.判断是否列表是否在第一个位置插入
	    if (position == 0) {
	        newNode.next = current
	        this.head = newNode
	    } else {
	        while (index++ < position) { // 向前赶, 直到找到当前位置position
	            previous = current
	            current = current.next
	        }
	        // index === position, 找到要插入的位置
	        newNode.next = current
	        previous.next = newNode
	    }
	    
	    // 4.length+1
	    this.length++
    }

    // 3. 从链表中任意移除一项
    removeAny(position) {
         //边界检查,越界返回false
        if(position < 0 || position > this.length-1){
            return false
        }
         let current = this.head
         let previous = null
         let index = 0
         // 如果删除第一个元素
         if(position == 0){
			this.head = current.next
		 }else{
		 	// 不是删除第一个找到删除的位置
			while(index++ < position){
				previous = current
				current = current.next
			}
			previous.next = current.next
		}
        this.length--
        return current.element
    }

    // 4. 寻找元素下标
    findIndex(element) {
        let current = this.head
        let index = 0
        //遍历链表直到找到data匹配的position
        while (current) {
            if (element === current.element) {
                return index
            }
            current = current.next
            index++
        }
        return false
    }

    // 5. 从链表的特定位置移除一项。
    remove(element) {
        const index = this.indexOf(element)
        return this.removeAt(index)
    }

	// 6. 判断是否为空链表
    isEmpty() {
        return !this.length
    }

	// 7. 获取链表长度
    size() {
        return this.length
    }

    // 8. 转为字符串
    toString() {
        let current = this.head
        let str = ''
        while (current) {
            str += ` ${current.element}`
            current = current.next
        }
        return str
    }
}

链表类的使用:

const linkedList = new LinkedList()

console.log(linkedList)  //  LinkedList {head: null, length: 0}
// 1. 在末尾追加元素
linkedList.append(2)  // LinkedList {head: {element:2,next:null}, length: 1}
linkedList.append(4)  // LinkedList {head: {element:2,next:{element:4,next:null}}, length: 2}
linkedList.append(6) // LinkedList {head: {element:2,next:{element:4,next:{element:6,next:null}}}, length: 3}

// 2. 在任意位置插入一个元素
linkedList.insert(2, 18) // LinkedList {head: {element:2,next:{element:4,next:{element:18,next:{element:6,next:null}}}}, length: 4}

// 3. 从链表中任意位置删除一项
linkedList.removeAny(2) // 18

// 4. 寻找元素下标
linkedList.findIndex(6)  // 2
linkedList.findIndex(18)  // false
linkedList.findIndex(20)  // false

// 5. 从链表的特定位置移除一项。
linkedList.remove(4)

// 6. 判断是否为空链表
linkedList.isEmpty()  // false

// 7. 获取链表长度
linkedList.size()  // 2

// 8. 转为字符串
linkedList.toString()  // ' 2 4 18 6'

双向链表:
概念:双向链表和普通链表的区别在于,在链表中, 一个节点只有链向下一个节点的链接,而在双向链表中,链接是双向的:一个链向下一个元素, 另一个链向前一个元素,如下图所示:
在这里插入图片描述
使用javacsript来实现一个双向链表类:

class Node{
	constructor(element){
		this.element = element
		this.next = null 
		this.prev = null 
	}
}

// 双向链表
class DoublyLinkedList {
    constructor() { 
        this.head = null
        this.tail = null
        this.length = 0
    }

	// 1. 任意位置插入
	insert(position,element){
		// 1.1 检测越界问题: 越界插入失败, 返回false
    	if (position < 0 || position > this.length) return false
    	let newNode = new Node(element)
	    let current = this.head // 初始值为head, 对第一个元素的引用
	    let previous = null // 存储当前current的上一个节点
	    let index = 0  // 位置
	    // 1.2 如果插在了首位
	    if(position == 0){
			// 空链表
			if(!head){
				this.head = node 
				this.tail = node 
			}else{
				this.head = node
				node.next = current
				current.prev = node
			}
		}
		// 1.3 如果插在了末位
		else if(position == this.length) {
			this.tail = node
			current.next = node
            node.prev = current
		}else {
			// 如果插在了中间位置
			// 找到插入的位置
			while(idex++ < position){
				previous = current
	            current = current.next
			}
			// 插入进去
			node.next = current
            previous.next = node
            node.pre = previous
            current.pre = node
			this.length++
            return true
		}
	}
	
	// 2. 移除任意位置元素
	removeAny(position){
		// 2.1 边界检查,越界返回false
		if(position < 0 || position > this.length-1) return false
		let current = this.head
        let previous = null
        let index = 0
		// 2.2 如果删除的是首位
		if(position == 0){
			this.head = current.next
			this.head.prev = null
		}else if(position == this.length - 1){
			// 2.3 如果删除的是末位
			this.tail = current.pre
			this.tail.next = null 
		}else {
			// 2.4 中间项
			// 找到删除的位置
			while(index++ < position){
				previous = current
				current = current.next
			}
			previous.next = current.next
			current.prev = current.next.prev
			this.length--
         	return current.element
		}
	} 
}

循环链表:
概念:循环链表可以像单向链表一样只有单向引用,也可以向双向链表一样具有双向引用。
单向循环链表:最后一个元素指向下一个元素的指针(tail.next)不是引用null, 而是指向第一个元素(head),如下图所示:
在这里插入图片描述
双向循环链表:最后一个元素指向下一个元素的指针tail.next不是nul,而是指向第一个元素(head),同时第一个元素指向前一个元素的指针head.prev不是null,而是最后一个元素tail。如图所示:
在这里插入图片描述
链表的优势:无需移动链表中的元素,就能轻松地添加和移除元素。因此,当你需要添加和移除很多元素 时,最好的选择就是链表,而非数组。

集合:
概念:集合是由一组无序且唯一(不能重复)的项组成的。目前在ES6中已经内置了Set的实现。
集合中常用的一些方法
add() 添加元素
delete() 删除元素,返回布尔值,删除成功返回true,删除失败返回false
has() 判断是否含有某个元素,返回布尔值
clear() 清空set数据结构
size 没有括号,返回此结构长度

在ES6中使用集合:

const arr = [1,2,2,3,3,3,4,4,5]
const str = 'wangjiajiawwwjiajiawwwww'
// 1.添加元素
new Set(arr)   // Set{1,2,3,4,5}
new Set(str )    // Set{'w', 'a', 'n', 'g', 'j', 'i'}
new Set(arr).add(8)    // Set{1,2,3,4,5,8}

// 2.删除元素 
new Set(arr).delete(2)    // true
new Set(arr).delete(9)    // false

// 3.判断是否含有某个元素
new Set(arr).has(2)    // true
new Set(arr).has(9)    // false

// 4.清空set数据结构
new Set(arr).clear()  // undefined

// 5.没有括号,返回此结构长度
new Set(arr).size    // 5

在javascript中使用集合:

// hasOwnProperty(propertyName)方法 是用来检测属性是否为对象的自有属性,如果是,返回true,否则返回false; 参数propertyName指要检测的属性名;
// hasOwnProperty() 方法是 Object 的原型方法(也称实例方法),它定义在 Object.prototype 对象之上,所有 Object 的实例对象都会继承 hasOwnProperty() 方法。
class Set {
    constructor() {
        this.items = {}
    }

    has(value) {
        return this.items.hasOwnProperty(value)
    }

    add(value) {
        if (!this.has(value)) {
            this.items[value] = value
            return true
        }     
        return false
    }

    remove(value) {
        if (this.has(value)) {
            delete this.items[value]
            return true
        }
        return false
    }

    get size() {
        return Object.keys(this.items).length
    }

    get values() {
        return Object.keys(this.items)
    }
}
const set = new Set()
set.add(1)
console.log(set.values)  // ["1"] 
console.log(set.has(1))  // true 
console.log(set.size) // 1 
set.add(2) 
console.log(set.values)  // ["1", "2"] 
console.log(set.has(2))  // true 
console.log(set.size) // 2 
set.remove(1) 
console.log(set.values) // ["2"] 
console.log(set.has(1))  // false
set.remove(2) 
console.log(set.values) // []

对集合可以执行如下操作:
并集:对于给定的两个集合,返回一个包含两个集合中所有元素的新集合。
交集:对于给定的两个集合,返回一个包含两个集合中共有元素的新集合。
差集:对于给定的两个集合,返回一个包含所有存在于第一个集合且不存在于第二个集合的元素的新集合。

并集:
并集的数学概念:集合A和B的并集,表示为A∪B,定义如下:A∪B = { x | x∈A V x∈B },意思是x(元素)存在于A中,或x存在于B中。如图:

在这里插入图片描述
基于刚才的 Set 类实现一个并集方法:

union(otherSet) {
    const unionSet = new Set()
    // 先添加其中一个集合的元素放在unionSet中
    this.values.forEach((v, i) => unionSet.add(this.values[i]))
    // 在把另一个集合的元素放入unionSet中
    otherSet.values.forEach((v, i) => unionSet.add(otherSet.values[i]))
    return unionSet
}

交集:
并集的数学概念:集合A和B的交集,表示为A∩B,定义如下:A∩B = { x | x∈A ∧ x∈B },意思是x(元素)存在于A中,且x存在于B中。如图:

在这里插入图片描述
基于刚才的 Set 类实现一个交集方法:

intersection(otherSet) {
    const intersectionSet = new Set()
    // 从集合A开始循环判断,如果这个元素也在集合B中,那就说明这个元素是集合A,B公有的。这时候把这个元素放到一个新的集合中
    this.values.forEach((v, i) => {
        if (otherSet.has(v)) {
            intersectionSet.add(v)
        }
    })
    return intersectionSet
}

差集:
差集的数学概念:集合A和B的差集,表示为A-B,定义如下:A-B = { x | x∈A ∧ x∉B },意思是x(元素)存在于A中,且不x存在于B中。如图:
在这里插入图片描述
基于刚才的 Set 类实现一个差集 A-B 的方法:

difference(otherSet) {
	// 从集合A开始循环判断,如果这个元素不在集合B中。说明这个元素是A私有的,此时把这个元素放入一个新的集合中。
    const differenceSet = new Set()
    this.values.forEach((v, i) => {
        if (!otherSet.has(v)) {
            differenceSet.add(v)
        }
    })
    return differenceSet
}

子集:
子集的数学概念:集合A是B的子集,或者说集合B包含了集合A,如图:
在这里插入图片描述
基于刚才的 Set 类实现一个子集方法:

// 在这里this代表集合A,otherSet代表集合B
subset(otherSet){
	if(this.size > otherSet.size){
		return false
	}else{
		// 只要A里面有一个元素不在B里面就说明A不是B的子集,后面元素不用在判断了
		this.values.every(v => !otherSet.has(v))
	}
}

字典:
集合、字典、散列表都可以存储不重复的数据。字典以键值对的形式存储数据,类似于javascript中的Object对象。

在javascript中实现字典:

class Dictionary {
    constructor() {
        this.items = {}
    }

    set(key, value) {
        this.items[key] = value
    }

    get(key) {
        return this.items[key]
    }

    remove(key) {
        delete this.items[key]
    }

    get keys() {
        return Object.keys(this.items)
    }

    get values() {
        /*
        也可以使用ES7中的values方法
        return Object.values(this.items)
        */

        // 在这里我们通过循环生成一个数组并输出
        return Object.keys(this.items).reduce((r, c, i) => {
            r.push(this.items[c])
            return r
        }, [])
    }
}

使用字典:

const dictionary = new Dictionary()
dictionary.set('Wangjiajia', 'Wangjiajia@email.com')
dictionary.set('Wangtongtong', 'Wangtongtong@email.com')
dictionary.set('davide', 'davide@email.com') 

console.log(dictionary)  // {items:{'Wangjiajia', 'Wangjiajia@email.com','Wangtongtong', 'Wangtongtong@email.com','davide', 'davide@email.com'}}
console.log(dictionary.keys)  // ['Wangjiajia','Wangtongtong','davide']
console.log(dictionary.values) // [Wangjiajia@email.com','Wangtongtong@email.com','davide@email.com']
console.log(dictionary.items)  // {'Wangjiajia': 'Wangjiajia@email.com','Wangtongtong': 'Wangtongtong@email.com','davide':'davide@email.com'}

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

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

相关文章

JsonView下载安装

文章目录 一、JsonView概述二、JsonView下载三、JsonView安装四、JsonView测试 一、JsonView概述 SONView是一款非常好用的Json格式查看器。在日常开发调试中经常会遇到Json格式的数据需要解析阅读&#xff0c;但Json格式数据阅读性极差&#xff0c;JSONView可以帮我们解决Jso…

基于协同过滤算法的智能推荐点餐系统小程序/基于微信小程序的点餐系统

摘 要 在社会的发展和科学技术的进步&#xff0c;现在我们所生活的世纪是一个集信息高度数字化&#xff0c;网络化&#xff0c;信息化的&#xff0c;以网络为核心的社会。随着移动互联网的飞速发展&#xff0c;微信客户端的应用也逐渐广泛起来。与此同时&#xff0c;我国每个人…

上手CUDA编程

上手CUDA编程 文章目录 上手CUDA编程矩阵加法例子编译 查看本机GPU信息内存管理函数专门二维数组拷贝函数 Reference>>>>> 欢迎关注公众号【三戒纪元】 <<<<< 矩阵加法例子 编写 CUDA C 程序时&#xff0c; 要将文件命名为 *.cu&#xff0c;cu文…

新版危险废物标签二维码制作教程

生态环境部发布的《危险废物识别标志设置技术规范》已经在2023年7月1日正式实施&#xff0c;除了对危废标签格式、内容的规范&#xff0c;明确规定新版危废标签需要包含数字识别码和二维码&#xff0c;实现危险废物“一物一码”管理。 其中危险废物标签中的二维码部分&#xff…

【SuperPoint】语义SLAM深度学习用于特征提取

1. 概况 作者的写作思路很清晰&#xff0c;把各个技术点这么做的原因写的很清楚&#xff0c;一共三篇&#xff0c;另外两篇分别是2016年和2017年发表的&#xff0c;这三篇文章通读下来&#xff0c;可以看清作者在使用深度学习进行位姿估计这一方法上的思路演变过程&#xff0c…

IDEA中 jps+jmap+jconsole命令查看堆内存情况

结论 1.获取进程idjps2.jmap 某个时刻堆内存的情况jdk8之前jmap -heap pid 15876jdk8之后jhsdb jmap --heap --pid 158763.jconsole 动态查看堆内存情况&#xff0c;直接jconsole ,然后弹出可视化窗口jconsole其中12 要结合使用&#xff0c;且是静态的查看&#xff1b;3可以单…

【c++报错】无法打开自己的工程项目(C++ 无法打开文件“xxx.lib”)

问题&#xff1a; C 无法打开文件“xxx.lib” 问题分析&#xff1a; 在进行单个生成的时候&#xff0c;可以生成成功&#xff0c;也可以运行程序。但是点击全部重新生成时&#xff0c;就显示无法打开文件“xxx.lib”。 观察生成顺序&#xff0c;发现exe的程序&#xff08;调用…

基于”Python+”多技术融合在蒸散发与植被总初级生产力估算中的实践

熟悉蒸散发ET及其组分&#xff08;植被蒸腾Ec、土壤蒸发Es、冠层截留Ei&#xff09;、植被总初级生产力GPP的概念和碳水耦合的基本原理&#xff1b;掌握利用Python与ArcGIS工具进行课程相关的操作&#xff1b;熟练掌握国际上流行的Penman-Monteith模型&#xff0c;并能够应用该…

yarn 无法加载文件 CUsersAdministratorAppDataRoamingnpmyarn.ps1,因为在此系统上禁止运行脚本。的解决方案

yarn : 无法加载文件 C:\Users\Administrator\AppData\Roaming\npm\yarn.ps1&#xff0c;因为在此系统上禁止运行脚本。 1、问题描述 执行yarn相关命令时报错&#xff1a; yarn : 无法加载文件 C:\Users\Administrator\AppData\Roaming\npm\yarn.ps1&#xff0c;因为在此系统…

PHP 学生信息管理系统mysql数据库web结构apache计算机软件工程网页wamp

一、源码特点 PHP 学生信息管理系统 是一套完善的web设计系统&#xff0c;对理解php编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。 代码下载 https://download.csdn.net/download/qq_41221322/88027229https://down…

7 个顶级免费网站在线图像压缩工具!

在将图像上传到网站之前对其进行压缩是缩短网站加载时间的最简单、最有效的方法之一&#xff0c;从而改善访问者的网站体验并提高搜索排名。 大图像会显着降低网站的性能&#xff0c;这总体来说是个坏消息。幸运的是&#xff0c;您可以使用一些很棒的工具来帮助您轻松优化图像…

实现windows系统文件传输到Linux系统中的工具

1、实现windows系统文件传输到Linux系统中的工具 yum -y install lrzsz然后就可以将windows中的文件&#xff0c;直接拖到Xshell窗口即可。

Springboot快速回顾(集成Dubbo)

Dubbo是实现远程调用的一个框架&#xff0c;阿里巴巴开源的。远程调用就是B服务器可以调用A服务器的方法。大型项目会被拆分成多个模块&#xff0c;部署在不同的服务器上。若将公共模块集中部署在一台服务器上&#xff0c;可以方便其他服务器调用。因此&#xff0c;需要Dubbo。…

深度学习实践大全

文章目录 1.可视化调试1.1 各通道相加可视化1.2 降维到3维或2维 1.可视化调试 可视化方法可分为&#xff1a;各通到相加可视化、 1.1 各通道相加可视化 def visualize_feature_map(img_batch,out_path,type,BI):feature_map torch.squeeze(img_batch)feature_map feature_…

C++教程(二)——第一个程序:编写hello world

1、点击左上角【文件】&#xff0c;再点击创建【项目】&#xff0c;设置项目名称&#xff0c;选择存储地址&#xff0c;再应用。 2、首先在解决方案资源管理器中点击【源文件】&#xff0c;右键【添加】--->【新建项】。 3、在弹出窗口中选择C文件(.cpp)&#xff0c;设置名称…

【考研思维题】【哈希表 || 什么时候用哈希表呢?快速查询的时候】【我们一起60天准备考研算法面试(大全)-第九天 9/60】

专注 效率 记忆 预习 笔记 复习 做题 欢迎观看我的博客&#xff0c;如有问题交流&#xff0c;欢迎评论区留言&#xff0c;一定尽快回复&#xff01;&#xff08;大家可以去看我的专栏&#xff0c;是所有文章的目录&#xff09;   文章字体风格&#xff1a; 红色文字表示&#…

【webrtc】ProcessThreadAttached

RegisterModule 调用所在的线程指针传递给ProcessThreadAttached ProcessThreadAttached 调用不是在worker thread 而是在 registers/deregister 这个module或者 start stop 这个module的时候 ** ** pacedsender是一个moudle -实现了

【Zabbix 监控设置】

目录 一、添加 zbx-agent01 客户端主机1、服务端和客户端都配置时间同步2、服务端和客户端都设置 hosts 解析3、设置 zabbix 的下载源&#xff0c;安装 zabbix-agent24、修改 agent2 配置文件5、启动 zabbix-agent26、在服务端验证 zabbix-agent2 的连通性1、常用的键值 7、在 …

Nginx 技术

Nginx (engine x) 是一个高性能的 HTTP 和反向代理 web 服务器&#xff0c;同时也提供了 IMAP/POP3/SMTP 服务。Nginx 是由伊戈尔赛索耶夫为俄罗斯访问量第二的 Rambler.ru 站点开发的&#xff0c;公开版本1.19.6发布于2020年12月15日。 其将源代码以类 BSD 许可证的形式发布&…

论文阅读 | UniFormer

UniFormer: Unified Multi-view Fusion Transformer for Spatial-Temporal Representation in Bird’s-Eye-View 文章目录 UniFormer: Unified Multi-view Fusion Transformer for Spatial-Temporal Representation in Bird’s-Eye-View摘要介绍Question: 说了半天这个时空融合…