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

数据结构和算法--仅仅用于理解里面的术语,入门级别

数据结构和算法

预先知识:java

黑马前29节

cmd命令:

文件夹路径不区分大小写

E:

dir:查看所有文件

cd 目录 :进入

cd… 返回上一级

cd 目录1\目录2

cd\ 回到根目录

cls 清屏

exit 退出

打开文件夹必须用cd 查找,但是文件不用,直接输入即可

上下键使用上次使用的命令

环境变量:

操作系统中一个用来存储有关操作系统或应用程序配置信息的动态值。这些变量的值在操作系统级别可被访问,它们对于程序的运行和系统行为具有重要的影响。

简单来说:在任意目录下都可以打开指定 的软件,或者可执行程序,音频等,就可以把软件的路径配置到环境变量中

例如:把本台电脑的微信放到环境变量中,方便打开,内存损耗小

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

上面是用户变量,电脑有多个用户时修改本用户的,用下面的系统变量是默认设置,对所有用户生效

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

系统在查找时从上往下查找,放到最前面节省内存和时间

idea的安装

结构:project>module>package>class

新建顺序也是这样一步一步来

创建文件时必须一步一步创建,否则会出现问题

变量命名规则:

变量,方法:第二个单词往后首字母大写

文件(类名):单词首字母都大写

1.复杂度

大O表示法:忽略常数,系数,低阶

注意:log函数统一为logn

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

1<logn<n<nlogn<n2<n3<2N<n!<nN

例题:求第n个斐波那契数列(fibonacci number)

0 1 1 2 3 5 后面一个数是前面两个数的和

解析:n=2,加一次;n=3,加两次;n=4,加三次…

所以要循环n-1次,即n–>1(先进行比较,在进行减一,后置就是最后进行加减操作)

package com.itheima.demo1;public class FibNum {public static void main(String[] args) {System.out.println(fib2(30));System.out.println(fib1(30));}public static int fib1(int n){if(n<=1){return n;}return fib1(n-1)+fib1(n-2);}public static int fib2(int n){if(n<2) return n;int first = 0;int second = 1;while(--n>0){second+=first;first = second-first;}return second;}
}

复杂度分析:时间复杂度+空间复杂度,一般只考虑时间复杂度,除非小型机的编程,例如单片机等,内存不大

例:外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

时间:O(1)空间:O(1)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

时间:O(n方),空间:O(1)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

时间:O(logn),空间:O(1)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

i+=i替代等换是一样的复杂度,意思就是i乘以几次2之后<n,log2(n)

注意:循环里执行几次是由后两个共同决定的,一定要看清楚

O(nlogn)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

空间复杂度:O(n)堆区创建数组n个位置内存;时间复杂度:O(n)

现在来分析fib复杂度:首先是不使用回调

public static int fib1(int n){if(n<=1){return n;}return fib1(n-1)+fib1(n-2);}

调用几次复杂度就是几直到调用到0或1,假设传入6

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

n = 6时:1+2+4+8+10 = 25,可以发现增长规律就行:是以前一行的指数型增长2N,发现增长的规律就行

O(2N)时间复杂度是最高的

public static int fib2(int n){if(n<2) return n;int first = 0;int second = 1;while(n-->1){second+=first;;first = second-first;}return second;}

一共循环n-1次,所以是O(n)

1.线性结构:

1.动态数组

static:保证数据只有一份

相当于C++中vector,以下是代码:

案例描述: 实现一个通用的数组类,要求如下:

  • 可以对内置数据类型以及自定义数据类型的数据进行存储
  • 将数组中的数据存储到堆区
  • 构造函数中可以传入数组的容量
  • 提供对应的拷贝构造函数以及operator=防止浅拷贝问题
  • 提供尾插法和尾删法对数组中的数据进行增加和删除
  • 可以通过下标的方式访问数组中的元素
  • 可以获取数组中当前元素个数和数组的容量

示例:

myArray.hpp中代码

#pragma once
#include <iostream>
using namespace std;template<class T>
class MyArray
{
public://构造函数MyArray(int capacity){this->m_Capacity = capacity;this->m_Size = 0;pAddress = new T[this->m_Capacity];}//拷贝构造//如果T为对象,而且还包含指针,必须需要重载 = 操作符,因为这个等号不是构造,而是赋值,// 普通类型可以直接= 但是指针类型需要深拷贝//指针类型必须进行深拷贝,否则会引起内存重复释放的问题MyArray(const MyArray & arr){this->m_Capacity = arr.m_Capacity;this->m_Size = arr.m_Size;this->pAddress = new T[this->m_Capacity];for (int i = 0; i < this->m_Size; i++){this->pAddress[i] = arr.pAddress[i];}}//重载= 操作符  防止浅拷贝问题//返回引用也就是返回实例,有助于链式编程思想MyArray& operator=(const MyArray& myarray) {//原来类中的堆区有无数据,不是外部是内部有没有在堆区的if (this->pAddress != NULL) {delete[] this->pAddress;this->m_Capacity = 0;this->m_Size = 0;}this->m_Capacity = myarray.m_Capacity;this->m_Size = myarray.m_Size;this->pAddress = new T[this->m_Capacity];for (int i = 0; i < this->m_Size; i++) {this->pAddress[i] = myarray[i];}return *this;}//注意重载运算符时的重复计算 //重载[] 操作符  arr[0]//这个时候出现【9】就会调用这个函数//返回引用值,就是实例对象,这样既能当作左值运算,又符合链式编程思想T& operator [](int index){return this->pAddress[index]; //不考虑越界,用户自己去处理}//尾插法,里面加法和插入是由顺序的,怎样简单怎么来,不一定非得要传入参数 void Push_back(const T & val){if (this->m_Capacity == this->m_Size){return;}this->pAddress[this->m_Size] = val;this->m_Size++;}//尾删法void Pop_back(){if (this->m_Size == 0){return;}this->m_Size--;}//获取数组容量int getCapacity(){return this->m_Capacity;}//获取数组大小int	getSize(){return this->m_Size;}//析构~MyArray(){//只有堆区有数据时才需要释放,其他情况不用//删除之后指向空,避免出现野指针的形象,析构时最好也进行初始化if (this->pAddress != NULL){delete[] this->pAddress;this->pAddress = NULL;this->m_Capacity = 0;this->m_Size = 0;}}private:T * pAddress;  //指向一个堆空间,这个空间存储真正的数据int m_Capacity; //容量int m_Size;   // 大小
};

//在涉及堆区释放内存问题时,拷贝构造不需要进行堆区指针的判断,默认时构造新的数据

类模板案例—数组类封装.cpp中

#include "myArray.hpp"
#include <string>void printIntArray(MyArray<int>& arr) {for (int i = 0; i < arr.getSize(); i++) {cout << arr[i] << " ";}cout << endl;
}//测试内置数据类型
void test01()
{MyArray<int> array1(10);for (int i = 0; i < 10; i++){array1.Push_back(i);}cout << "array1打印输出:" << endl;printIntArray(array1);cout << "array1的大小:" << array1.getSize() << endl;cout << "array1的容量:" << array1.getCapacity() << endl;cout << "--------------------------" << endl;MyArray<int> array2(array1);array2.Pop_back();cout << "array2打印输出:" << endl;printIntArray(array2);cout << "array2的大小:" << array2.getSize() << endl;cout << "array2的容量:" << array2.getCapacity() << endl;
}//测试自定义数据类型
class Person {
public://这里需要默认构造函数,因为类的构造函数是往后走的Person() {} Person(string name, int age) {this->m_Name = name;this->m_Age = age;}
public:string m_Name;int m_Age;
};void printPersonArray(MyArray<Person>& personArr)
{for (int i = 0; i < personArr.getSize(); i++) {cout << "姓名:" << personArr[i].m_Name << " 年龄: " << personArr[i].m_Age << endl;}}void test02()
{//创建数组MyArray<Person> pArray(10);Person p1("孙悟空", 30);Person p2("韩信", 20);Person p3("妲己", 18);Person p4("王昭君", 15);Person p5("赵云", 24);//插入数据pArray.Push_back(p1);pArray.Push_back(p2);pArray.Push_back(p3);pArray.Push_back(p4);pArray.Push_back(p5);printPersonArray(pArray);cout << "pArray的大小:" << pArray.getSize() << endl;cout << "pArray的容量:" << pArray.getCapacity() << endl;}int main() {//test01();test02();system("pause");return 0;
}

https://blog.csdn.net/weixin_43734095/article/details/104847976

看博客就好

牛逼

https://www.hello-algo.com/chapter_hashing/hash_map/

这个真的时神书

https://www.bilibili.com/read/cv29646692/?spm_id_from=333.999.0.0&jump_opus=1

https://www.hello-algo.com/chapter_preface/suggestions/

hello算法(python):

第一次:

def while_loop(n:int)->int:res = 0i = 1while i<=n:res+=ii+=1return resdef for_loop(n:int)->int:res = 0for i in range(1,n+1):res+=ireturn resdef nested_for_loop(n:int)->str:res = ""for i in range(1,n+1):for j in range(1,n+1):res += f"({i},{j}),"return resdef recur(n:int)->int:"""递归"""#终止条件if n == 1:return 1#递:递归调用res = recur(n-1)#归:返回结果return n+resdef tail_recur(n,res):"""尾递归"""#终止条件if n == 0:return res#尾递归调用return  tail_recur(n-1,res+n)def main():result = for_loop(100)print("sum is to ",result)def fib(n:int)->int:"""斐波那契数列"""#终止条件f(1) = 0,f(2) = 1if n==1 or n==2:return n-1#递归调用f(n) = f(n-1)+f(n-2)res = fib(n-1)+fib(n-2)#返回结果 f(n)return resdef for_loop_recur(n:int)->int:stack = []res = 0for i in range(n,0,-1):stack.append(i)while stack:res += stack.pop()return resif __name__ =="__main__":main()result = while_loop(100)print("sum1 is to ",result)result1 = nested_for_loop(10)print("sum2 is to ",result1)result3 = tail_recur(100,0)print("sum3 is to ",result3)result4 = fib(64)print("sum4 is to ",result4)

格式化字符串 : f""

print (‘%d 等于 %d * %d’ % (num,i,j))占位符和格式转换

python学习教程:

https://www.runoob.com/python/python-strings.html

注意python的变量赋值语法,一些常用特点

if __name__ == "__main__":语句的作用是判断当前模块是否作为主程序直接执行。如果模块是直接被执行的,则__name__变量的值为"__main__",在这种情况下,if __name__ == "__main__":后面的代码块将会被执行;如果模块是被导入的,则__name__变量的值为模块的名称,这时if __name__ == "__main__":后面的代码块将不会被执行。

需要执行的脚本不需要模块名为main,在这种上下文中,"main"通常指的是Python脚本文件作为主程序直接执行时的执行上下文。当Python脚本文件被直接执行时,Python解释器会将这个脚本文件作为主程序运行,此时该脚本文件的特殊变量__name__的值会被设为"__main__"。因此,if __name__ == "__main__":语句的作用就是检查当前模块是否在主程序上下文中运行。

在这个语境中,"main"并不是一个变量或模块名,而是一个特殊的字符串,用于表示当前模块是主程序。"main"一词来自C语言中的main函数,表示程序的入口点。

第二次

def slgorithm(n:int):a = 2a = a+1a = a*2#_占位符,只需要运行循环,不需要变量for _ in range(n):print(0)def array_traversal(nums:list[int])->int:#nums后面跟类型count = 0for num in nums:count+=1return  countdef bubble_sort(nums:list[int]):for i in range(0,len(nums)-1):#排序轮数for j in range(0,len(nums)-1-i):#每轮比较的次数if(nums[j]<nums[j+1]):temp = nums[j]nums[j] = nums[j+1]nums[j+1] = tempprint(nums)return 0if __name__ =="__main__":slgorithm(5)bubble_sort([1,5,3,4,8,2])
class ListNode:"""链表节点类"""def __init__(self, val: int):self.val: int = val  # 节点值self.next: ListNode | None = None  # 后继节点引用

在这段代码中,ListNode 是一个链表节点类,用于表示链表中的一个节点。它具有两个属性:

  1. val:表示节点的值,类型为整数(int)。
  2. next:表示指向下一个节点的引用。由于链表中的节点是一个个相互连接的,因此每个节点都需要有一个指向下一个节点的引用。next 属性的类型声明为 ListNode | None,这意味着它可以是一个指向 ListNode 类型对象的引用,也可以是 None,表示没有后继节点(即链表的最后一个节点)。
  3. 注意:冒号后面都是类型

这里使用了类型注释(type hinting)来指定属性的类型,以增加代码的可读性和可维护性。ListNode | None 使用了 Python 3.10 中的新特性,表示 next 属性可以是 ListNode 类型对象的引用,也可以是 None


for i ,num in enumerate(nums):

这段代码使用了 Python 中的 enumerate() 函数,用于在循环中同时获取元素的索引和值。

具体来说,enumerate(nums) 将返回一个由 (index, value) 组成的元组序列,其中 index 是元素的索引,value 是元素的值。在 for 循环中,inum 分别表示索引和值,通过 enumerate(nums) 得到的元组中的两个元素。

例如,假设 nums 是一个列表 [10, 20, 30],那么 for i, num in enumerate(nums): 循环将会迭代三次,每次迭代时 inum 的值分别是 (0, 10)(1, 20)(2, 30),分别表示列表中每个元素的索引和值。

数组

#初始化数组
import randomarr:list[int] = [0]*5
nums:list[int] = [1,3,2,5,4]def random_access(nums:list[int])->int:'随机访问元素'#区间[0,len(nums)-1]# 注意python里面区间是左闭右开,除随机函数外random_index = random.randint(0,len(nums)-1)random_num = nums[random_index]return random_numdef insert(nums:list[int],num:int,index:int):'在数组的索引index插入元素num'for i in range(len(nums)-1,index,-1):nums[i] = nums[i-1]nums[index] = numdef remove(nums:list[int],index:int):'删除index的元素'for i in range(index,len(nums)):nums[i] = nums[i+1]def traverse(nums:list[int]):'遍历数组'count = 0for i in range(len(nums)):count += nums[i]for num in nums:count +=numfor i ,num in enumerate(nums):count +=nums[i]count +=numdef find(nums:list[int],target:int)->int:'在数组中查找'for i in range(len(nums)):if nums[i] ==target:return  ireturn -1def extend(nums:list[int],enlarge:int)->list[int]:'扩展数组长度'res = [0]*(len(nums)+enlarge)for i in range(len(nums)):res[i] = nums[i]return res

链表

class Employee:'所有员工的基类'empCount = 0def __init__(self, name, salary):self.name = nameself.salary = salaryEmployee.empCount += 1

在这段代码中,Employee.empCount += 1 是对类变量 empCount 的增加操作,它位于类的作用域内。而 empCount += 1 则是尝试对一个在方法中未定义的变量进行操作,因此会引发一个 NameError

**在 Python 中,如果你想要对类变量进行操作,需要使用类名来引用它,以区分类变量和实例变量。类变量是属于整个类的,可以通过类名直接访问和修改。**在这个例子中,Employee.empCount += 1 表示对 Employee 类的 empCount 类变量进行增加操作。

如果你尝试使用 empCount += 1,Python 将会认为 empCount 是一个局部变量,并且它还没有被定义,因此会抛出一个 NameError 异常。

User
class ListNode:"""链表节点类"""def __init__(self, val: int):self.val: int = val               # 节点值self.next: ListNode | None = None # 指向下一节点的引用,self.next没有定义怎么可以使用

这行代码使用了类型注释(type hinting)语法,用于指定 self.next 这个实例变量的类型。

具体来说,self.next: ListNode | None = None 的含义如下:

  • self.next:表示实例变量的名称为 next
  • :表示类型注释的分隔符,用于将变量名和类型注释分开。
  • ListNode | None表示该变量的类型可以是 ListNode 类的实例,也可以是 NoneListNode 类型表示指向下一个节点的引用,而 None 表示没有后继节点。
  • =:表示赋值操作符,用于给变量一个初始值。
  • None:表示变量的初始值为 None,即表示当前节点没有后继节点。

因此,这行代码的作用是将 self.next 这个实例变量的类型注释为可以是 ListNode 类的实例,也可以是 None,并将其初始值设为 None

class ListNode:'链表节点类'val = 0next = ListNode|Nonedef __init__(self,val):self.val = valself.next = None

以上是错误的

在 Python 中,类型注释是用于提供类型信息的,但它们不应该在类的属性定义中使用在你的代码中,next = ListNode|None 并不是一个有效的类型注释,它看起来更像是一个试图指定属性类型的语法错误。正确的做法是在变量声明时使用 :,而不是 |,注意python的类型定义**

#注意这个类里面只有一个函数方法
class ListNode:'链表节点类'def __init__(self,val):self.val:int = valself.next:ListNode|None = Noneclass ListNode1:'双向链表节点类'def __init__(self,val:int):self.val:int = valself.next:ListNode1|None = Noneself.prev:ListNode1|None = Nonedef insert(n0:ListNode,P:ListNode):'在链表之后插入节点'n1 = n0.nextP.next = n1n0.next = Pdef remove(n0:ListNode):'删除之后的一个节点'if not n0.next:returnP = n0.nextn1 = P.nextn0.next = n1def accsee(head:ListNode,index:int)->ListNode|None:'访问链表确定节点'for _ in range(index):#遍历超出范围,返回空if not head:return Nonehead = head.nextreturn head
def find(head:ListNode,target:int)->int:'在链表中查找值为target的首个节点'index = 0while head:if head.val == target:return indexhead = head.nextindex += 1return -1#初始化链表1->3->2->5->4
n0 = ListNode(1)
n1 = ListNode(3)
n2 = ListNode(2)
n3 = ListNode(5)
n4 = ListNode(4)
#构建连接
n0.next = n1
n1.next = n2
n2.next = n3
n3.next = n4

列表(动态数组)

#初始化
nums1:list[int] = [6,7]
nums:list[int] = [1,3,2,5,4]#访问
num:int = nums[1]
nums[1] = 0#清空
#nums.clear()nums.append(1)
nums.append(2)nums.insert(3,6)
#删除索引3的元素
nums.pop(3)count = 0
for i in range(len(nums)):count += nums[i]
for num in nums:count +=num
nums +=nums1
nums.sort() #默认从小到大排序
class MyList:'列表类'def __init__(self):'构造方法'self._capacity:int = 0self._arr:list[int] = [0]*self._capacity#数组存储self._size:int = 0self._extend_ratio:int = 2 #扩容倍数def size(self)->int:'获取长度'return self._sizedef capacity(self)->int:'获取列表容量'return self._capacitydef get(self,index:int)->int:'访问元素'#索引越界,抛出异常if index<0 or index >=self._size:raise IndexError("索引越界")return self._arr[index]def set(self,num:int,index:int):'更新元素'if index < 0 or index >= self._size:raise IndexError("索引越界")self._arr[index] = numdef add(self,num:int):'在尾部添加元素'#元素数量超出容量时,触发扩容机制if self.size() ==self.capacity():self.extend_capacity()self._arr[self._size] = numself._size += 1def insert(self,num:int,index:int):'在中间插入元素'if index < 0 or index >= self._size:raise IndexError("索引越界")if self.size() ==self.capacity():self.extend_capacity()for j in range(self._size-1,index,-1):self._arr[j+1]  = self._arr[j]self._size +=1def remove(self,index:int)->int:'删除元素'if index < 0 or index >= self._size:raise IndexError("索引越界")num = self._arr[index]for j in range(index,self._size):self._arr[j] = self._arr[j+1]self._size -= 1return numdef extend_capacity(self):'列表扩容'self._arr = self._arr+[0]*self._capacity * (self._extend_ratio-1)self._capacity = len(self._arr)def to_array(self)->list[int]:'返回有效长度的列表'return self._arr[:self._size]#切片操作,默认为零,相当于return self._arr[0:self._size]

在 Python 中,每个对象都有一个唯一的标识符(ID),可以通过内置函数 id() 来获取。这个标识符是一个整数,用于唯一标识对象在内存中的位置。

在 Python 中,每个对象都有一个唯一的标识符(ID),可以通过内置函数 id() 来获取。这个标识符是一个整数,用于唯一标识对象在内存中的位置。

对于字符串中的每个字符,虽然它们是不可变的,但在某些情况下,Python 会对相同的字符进行缓存,以节省内存。这意味着对于相同的字符,它们的标识符可能是相同的。但是,对于不同的字符,它们的标识符是不同的。

例如:

pythonCopy codes1 = 'a'
s2 = 'a'
print(id(s1))  # 输出第一个字符 'a' 的标识符
print(id(s2))  # 输出第二个字符 'a' 的标识符,与第一个相同

在上面的示例中,由于 Python 对相同的字符进行了缓存,因此 s1s2 共享相同的标识符。

#初始化栈
#python没有内置的栈,可以把list当作栈来使用
stack:list[int] = []stack.append(1)
stack.append(2)
stack.append(3)
stack.append(4)
stack.append(5)#访问栈顶
peek:int = stack[-1]
#元素出栈
pop:int = stack.pop()
size:int = len(stack)
is_empty:bool = len(stack) == 0

基于链表实现


class ListNode:'链表节点类'def __init__(self,val:int):self.val:int = valself.next:ListNode|None = Noneclass LinkedListStack:'基于链表实现栈'def __init__(self):'构造方法'self._peek:ListNode|None = None#始终是指向栈顶self._size:int = 0def size(self)->int:'获取栈的长度'return self._sizedef is_empty(self)->bool:'判断是否为空'return not self._peekdef push(self,val:int):'入栈'node = ListNode(val)node.next = self._peek #这里要理解原先里面假设有元素,这句话在于将新建的元素与开始的元素连接起来self._peek = node #上一句连接完成之后,头指针还指向栈顶self._size += 1def pop(self)->int:'出栈'num = self.peek()self._peek = self._peek.nextself._size -= 1return numdef peek(self)->int:'访问栈顶'if self.is_empty():raise IndexError("栈为空")return self._peek.valdef to_list(self)->list[int]:'转化为列表用于打印'arr = []node = self._peekwhile node:arr.append(node.val)node = node.nextarr.reverse()return arrif __name__ == "__main__":#初始化栈stack = LinkedListStack()#元素入栈stack.push(1)stack.push(2)stack.push(3)print("栈 stack = ",stack.to_list())peek = stack.peek()print("栈顶元素:peek = ",peek)

基于数组实现

class ArrayStack:'基于数组实现栈'def __init__(self):'构造方法'self._stack:list[int] = []def size(self)->int:'获取长度'return len(self._stack)def is_empty(self)->bool:'判断空'return self._stack == []def push(self,item:int):'入栈'self._stack.append(item)def pop(self)->int:'出栈'if self.is_empty():raise IndexError("栈为空")return  self._stack.pop()def peek(self)->int:'访问栈顶'if self.is_empty():raise  IndexError("栈为空")return  self._stack[-1]def to_list(self)->list[int]:'返回列表'return self._stackif __name__ =="__main__":stack = ArrayStack()

队列

from collections import deque
#在python中,我们将双向队列deque当作队列使用
if __name__ == "__main__":#初始化que : deque[int] = deque()#元素入队que.append(1)que.append(3)que.append(4)#访问队首元素front:int = que[0]print(front)#元素出队pop:int = que.popleft()size:int = len(que)is_empty:bool = len(que)==0print(pop,size,is_empty)

基于链表实现

class ListNode:"""链表"""def __init__(self,val:int):self.val:int = valself.next:ListNode|None = Noneclass LinkedListQueue:"""基于链表实现的队列"""def __init__(self):"""构造方法"""self._front:ListNode|None = None #头节点self._rear:ListNode|None = None #尾节点self._size:int = 0def size(self)->int:"""获取队列的长度"""return self._sizedef is_empty(self)->bool:"""判断队列是否为空"""return not self._frontdef push(self,num:int):"""入队"""#难点在于不断实时更新头尾节点#在尾节点之后添加node = ListNode(num)#如果队列为空,则令头尾节点都指向该节点if self._front is None:self._front = nodeself._rear = node#如果不为空,节点添加尾节点之后else:self._rear.next = nodeself._rear = nodeself._size += 1def pop(self)->int:"""出队"""#入队出队都要进行头尾节点的更新num = self.peek()self._front = self._front.nextself._size -= 1return numdef peek(self)->int:"""访问队首元素"""#访问时都要考虑是否为空if self.is_empty():raise IndexError("队列为空")return self._front.valdef to_list(self)->list[int]:"""转化为列表用于打印"""queue = []temp = self._frontwhile temp:queue.append(temp.val)temp = temp.nextreturn queueif __name__ == "__main__":#初始化que = LinkedListQueue()#元素入队que.push(1)que.push(3)que.push(4)#访问队首元素front:int = que.peek()print(front)#元素出队pop:int = que.pop()size:int = que.size()is_empty:bool = que.is_empty()print(pop,size,is_empty)

基于数组实现(环形数组),注意出对入队都是O(1)

class ArrayQueue:"""基于数组实现的队列"""def __init__(self,size:int):"""构造方法"""self._nums:list[int] = [0]*sizeself._front:int = 0self._size:int = 0def capacity(self)->int:"""获取队列的容量"""return len(self._nums)def size(self)->int:"""获取队列的长度"""return self._sizedef is_empty(self)->bool:"""判断空"""return self._size == 0def push(self,num:int):"""入队"""if self._size == self.capacity():raise IndexError("队列已满")#计算队尾指针,指向队尾索引+1#通过取余操作实现rear 越过数组尾部回到头部rear:int = (self._front+self.size())%self.capacity()self._nums[rear] = numself._size += 1def pop(self)->int:"""出队"""num:int = self.peek()#队首指针向后移动一位,若越过尾部,则返回到数组头部#这样就形成了一个循环队列,没必要进行扩容,下面这句话非常牛逼self._front = (self._front+1)%self.capacity()self._size -= 1return numdef peek(self)->int:"""访问队首元素"""if self.is_empty():raise IndexError("队列为空")return self._nums[self._front]def to_list(self)->list[int]:"""返回列表用于打印"""res = [0]*self._sizej:int = self._frontfor i in range(self._size):res[i] = self._nums[j%self.capacity()]j += 1return resif __name__ == "__main__":#初始化que = ArrayQueue(10)#元素入队que.push(1)que.push(3)que.push(4)#访问队首元素front:int = que.peek()print(front)#元素出队pop:int = que.pop()size:int = que.size()is_empty:bool = que.is_empty()print(pop,size,is_empty)

双端队列

from collections import deque
#初始化
deque= deque()#元素入队
deque.append(1)  #默认队尾
deque.append(2)
deque.append(3)
#默认队首
deque.appendleft(5)
deque.appendleft(4)
print(deque)
#访问队首队尾
front:int = deque[0]
rear:int = deque[-1]
#元素出队
pop_front:int = deque.popleft()
pop_rear:int = deque.pop()
#获取长度
size:int = len(deque)
is_empty:bool = len(deque)==0
print(front)
print(rear)
print(pop_front)
print(pop_rear)
print(size)
print(is_empty)

基于双向链表实现

class ListNode:"""双向链表节点"""def __init__(self,val:int):"""构造方法"""self.val:int = valself.next:ListNode|None = Noneself.prev:ListNode|None = Noneclass LinkedListDeque:"""基于双向链表实现的双向队列"""def __init__(self):"""构造方法"""self._front:ListNode|None = Noneself._rear:ListNode|None = Noneself._size:int = 0def size(self)->int:""""长度"""return self._sizedef is_empty(self)->bool:"""空"""return self._size == 0def push(self,num:int,is_front:bool):"""入队"""node = ListNode(num)#考虑空,头节点和尾节点都指向nodeif self.is_empty():self._front = self._rear = node#判断是队首还是队尾入队操作elif is_front:#队首self._front.prev = nodenode.next = self._front#用来链接结点self._front = node#更新头节点else:self._rear.next = nodenode.prev = self._rearself._rear = nodeself._size += 1def push_first(self,num:int):""""队首"""self.push(num,True)def push_last(self,num:int):"""队尾"""self.push(num,False)def pop(self,is_front:bool)->int:"""出队"""if self.is_empty():raise IndexError("双向队列为空")#队首#断开链接(包括两个向前和向后),更新头节点if is_front:val:int = self._front.valfnext:ListNode|None = self._front.nextif fnext!=None:fnext.prev = Noneself._front.next =Noneself._front = fnext#队尾else:val:int = self._rear.valrprev:ListNode|None = self._rear.previf rprev!=None:rprev.next = Noneself._rear.prev = Noneself._size-=1return valdef pop_first(self)->int:"""队首"""return self.pop(True)def pop_last(self)->int:"""队尾"""return self.pop(False)def peek_first(self)->int:"""队首"""if self.is_empty():raise  IndexError("双向队列为空")return self._front.valdef peek_last(self)->int:"""队尾"""if self.is_empty():raise IndexError("双向队列为空")return self._rear.valdef to_array(self)->list[int]:"""返回数组"""node = self._frontres = [0]*self.size()for i in range(self.size()):res[i] = node.valnode = node.nextreturn res

基于数组实现(环形数组)

注意:计算环形数组队首和队尾的时候,都是该在的那个位置取余,同时要注意取余的情况

class ArrayDeque:"""基于数组的双向队列"""def __init__(self,capacity:int):"""构造方法"""self._nums:list[int] = [0]*capacityself._front:int = 0self._size:int = 0def capacity(self)->int:"""容量"""return len(self._nums)def size(self)->int:"""长度"""return self._sizedef is_empty(self)->bool:""""空"""return self._size==0def index(self,i:int)->int:"""计算环形数组索引"""#通过取余操作实现数组首尾相连#当i越过尾部返回头部反之亦然#这里面加不加self.capacity都一样,因为要求余数return (i+self.capacity())%self.capacity()def push_first(self,num:int):"""队首"""if self._size ==self.capacity():print("双向队列已满")return#队首指针向左移动#通过取余实现环形self._front = self.index(self._front-1)self._nums[self._front] = numself._size += 1def push_last(self,num:int):"""队尾"""if self._size ==self.capacity():print("双向队列已满")returnrear = self.index(self._front+self._size)self._nums[rear] = numself._size += 1def pop_first(self)->int:"""队首出队"""num = self.peek_first()self._front = self.index(self._front+1)self._size -= 1return numdef pop_last(self)->int:"""队尾出队"""num = self.peek_last()self._size -= 1return numdef peek_first(self)->int:"""访问队首"""if self.is_empty():raise IndexError("双向队列为空")return self._nums[self._front]def peek_last(self)->int:"""访问队尾"""if self.is_empty():raise IndexError("双向队列为空")#计算尾元素索引last = self.index(self._front+self._size-1)return self._nums[last]def to_array(self)->list[int]:"""返回数组"""#在最后一个操作中不要试图进行修改元素res = []for i in range(self._size):res.append(self._nums[self._front+i])return res

哈希表

if __name__ == "__main__":#初始化哈希表hmap:dict = {}#加键值对hmap[123] = "你哈"hmap[124] = "加"hmap[125] = "键"print(hmap)#查询name = hmap[125]print(name)#删除hmap.pop(123)print(hmap)
#哈希表的遍历
if __name__ =="__main__":hmap: dict = {}hmap[12836] = "小哈"hmap[15937] = "小啰"hmap[16750] = "小算"hmap[13276] = "小法"hmap[10583] = "小鸭"for key,value in hmap.items():print(key,"->",value)for key in hmap.keys():print(key)for value in hmap.values():print(value)
class Pair:"""键值对"""def __init__(self,key:int,val:str):self.key = keyself.val = valclass ArrayHashMap:"""基于数组实现的哈希表"""def __init__(self):"""构造方法"""#初始化数组,包含100个桶self.buckets:list[Pair|None] = [None]*100def hash_func(self,key:int)->int:"""哈希函数,返回索引"""index = key%100return indexdef get(self,key:int)->str:"""查询"""index:int = self.hash_func(key)pair:Pair = self.buckets[index]if pair is None:return Nonereturn pair.valdef put(self,key:int,val:str):"""添加操作"""pair = Pair(key,val)index :int = self.hash_func(key)self.buckets[index] = pairdef remove(self,key:int):"""删除"""index:int = self.hash_func(key)#置为None,代表删除self.buckets[index] = Nonedef entry_set(self)->int:"""获取所有键值对"""result:list[pair] = []for pair in self.buckets:if pair is not None:result.append(pair)return resultdef key_set(self)->list[str]:"""获取所有键"""result :list[int] = []for pair in self.buckets:if pair is not None:result.append(pair.key)return resultdef value_set(self) -> list[str]:"""获取所有值"""result: list[str] = []for pair in self.buckets:if pair is not None:result.append(pair.val)return result\def print(self):"""打印哈希表"""for pair in self.buckets:if pair is not None:print(pair.key,"->",pair.val)

,包含100个桶
self.buckets:list[Pair|None] = [None]*100

def hash_func(self,key:int)->int:"""哈希函数,返回索引"""index = key%100return indexdef get(self,key:int)->str:"""查询"""index:int = self.hash_func(key)pair:Pair = self.buckets[index]if pair is None:return Nonereturn pair.valdef put(self,key:int,val:str):"""添加操作"""pair = Pair(key,val)index :int = self.hash_func(key)self.buckets[index] = pairdef remove(self,key:int):"""删除"""index:int = self.hash_func(key)#置为None,代表删除self.buckets[index] = Nonedef entry_set(self)->int:"""获取所有键值对"""result:list[pair] = []for pair in self.buckets:if pair is not None:result.append(pair)return resultdef key_set(self)->list[str]:"""获取所有键"""result :list[int] = []for pair in self.buckets:if pair is not None:result.append(pair.key)return resultdef value_set(self) -> list[str]:"""获取所有值"""result: list[str] = []for pair in self.buckets:if pair is not None:result.append(pair.val)return result\def print(self):"""打印哈希表"""for pair in self.buckets:if pair is not None:print(pair.key,"->",pair.val)

相关文章:

数据结构和算法--仅仅用于理解里面的术语,入门级别

数据结构和算法 预先知识&#xff1a;java 黑马前29节 cmd命令&#xff1a; 文件夹路径不区分大小写 E: dir:查看所有文件 cd 目录 :进入 cd… 返回上一级 cd 目录1\目录2 cd\ 回到根目录 cls 清屏 exit 退出 打开文件夹必须用cd 查找&#xff0c;但是文件不用&am…...

this.$nextTick() 作用及实现原理

1、原理和作用 2、更新任务推送到微任务队列后&#xff0c;vue是如何知道所有的更新任务执行完成了&#xff1f; vue将更新任务推送给微任务队列&#xff1b;当更新任务执行的时候&#xff0c;将回调队列任务推给微任务队列&#xff1b;通过微任务队列的原子性和先进先出机制&…...

C#常用的循环语句

在C#中&#xff0c;循环是一种控制结构&#xff0c;用于重复执行一组语句直到满足特定条件。C#提供了几种循环结构&#xff0c;包括for循环、while循环、do-while循环和foreach循环。每种循环都有其特定的用途和场景。下面我将逐一介绍这些循环的用法。 一、C#循环类型 1. fo…...

Android View 设置背景方式全解析

一、整体概述 在 Android 开发中&#xff0c;视图&#xff08;View&#xff09;的背景设置是构建用户界面的重要组成部分。一个合适的背景可以提升界面的美观度&#xff0c;增强用户体验。从简单的纯色背景到复杂的动态效果&#xff0c;背景设置不仅影响界面美观&#xff0c;还…...

HTTP拾技杂谈

HTTP拾技杂谈 简单聊聊HTTP中的那些东西 文章目录 HTTP拾技杂谈前言HTTP协议1.请求从客户端到服务器端的4个步骤一般客户端请求如下&#xff1a;服务端响应如下 2.Keep-AliveHTTP方法Cookie 总结 前言 超文本传输协议&#xff08;Hypertext Transfer Protocol &#xff0c;HT…...

网络安全之RSA算法

1978年就出现了这种算法&#xff0c;它是第一个既能用于数据加密也能用于数字签名的算法。它易于理解和操作&#xff0c;也很流行。算法的名字以发明者的名字&#xff08;RonRivest&#xff0c;AdiShamir和LeonardAdleman&#xff09;命名。但RSA的安全性一直未能得到理论上的证…...

神经网络为什么要用 ReLU 增加非线性?

在神经网络中使用 ReLU&#xff08;Rectified Linear Unit&#xff09; 作为激活函数的主要目的是引入非线性&#xff0c;这是神经网络能够学习复杂模式和解决非线性问题的关键。 1. 为什么需要非线性&#xff1f; 1.1 线性模型的局限性 如果神经网络只使用线性激活函数&…...

ES10(2019)、ES11(2020) 新增特性(八)

目录 ES10&#xff08;2019&#xff09; Array.flat() Array.flatMap() String.trimStart()和String.trimEnd() Symbol.prototype.description Object.fromEntries() ES11&#xff08;2020&#xff09; Nullish coalescing Operator【空值运算符】 可选链&#xff08…...

利用MQ自动取消未支付超时订单最佳实践

一、利用MQ自动取消未支付超时订单最佳实践 1、基于 RocketMQ 延迟消息 1.1&#xff1a;延迟消息 当消息写入到 Broker 后&#xff0c;不会立刻被消费者消费&#xff0c;需要等待指定的时长后才可被消费处理的消息&#xff0c;称为延时消息。 1.2&#xff1a;实现流程 &am…...

1-003:MySQL 的索引类型有哪些?

MySQL 中的索引类型主要分为以下几类&#xff0c;每种索引都有不同的适用场景和优化查询的作用&#xff1a; 1. 按存储结构分类 ① 聚簇索引&#xff08;Clustered Index&#xff09; 特点&#xff1a; InnoDB 引擎的 主键索引 就是 聚簇索引。数据与索引存储在一起&#xff…...

php虚拟站点提示No input file specified时的问题及权限处理方法

访问站点&#xff0c;提示如下 No input file specified. 可能是文件权限有问题&#xff0c;也可能是“.user.ini”文件路径没有配置对&#xff0c;最简单的办法就是直接将它删除掉&#xff0c;还有就是将它设置正确 #配置成自己服务器上正确的路径 open_basedir/mnt/qiy/te…...

Unity UGUI下实现精确点击的一种方式

比如有这样一个情况&#xff0c;UI的显示区域是个圆形&#xff0c;在点击的时候也需要精确点击到这个圆形显示区域&#xff0c;但是UI元素的RectTransform是个矩形 1. 使用脚本修改 2. 原理探究 此脚本继承了Image组件&#xff0c;但是获取了自身的Collider2D&#xff0c;目…...

元宇宙崛起:区块链与金融科技共绘数字新世界

文章目录 一、引言二、元宇宙与区块链的深度融合三、区块链在元宇宙金融中的应用四、金融科技在元宇宙中的创新应用五、面临的挑战与机遇《区块链与金融科技》亮点内容简介获取方式 一、引言 随着科技的飞速发展&#xff0c;元宇宙概念逐渐走进人们的视野&#xff0c;成为数字…...

postgresql14编译安装脚本

#!/bin/bash####################################readme################################### #先上传postgresql源码包&#xff0c;再配置yum源&#xff0c;然后执行脚本 #备份官方yum源配置文件&#xff1a; #cp /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS…...

警惕AI神话破灭:深度解析大模型缺陷与禁用场景指南

摘要 当前AI大模型虽展现强大能力&#xff0c;但其本质缺陷可能引发系统性风险。本文从认知鸿沟、数据困境、伦理雷区、技术瓶颈四大维度剖析大模型局限性&#xff0c;揭示医疗诊断、法律决策等8类禁用场景&#xff0c;提出可信AI建设框架与用户防护策略。通过理论分析与实操案…...

1分钟看懂React的那些Hook‘s

一、useEffect的五指山 1.执行时机&#xff1a;组件初始化,组件更新&#xff08;组件内state变化&#xff09; useEffect(() > {}) 2.执行时机&#xff1a;组件初始化 useEffect(() > {},[]) 3.执行时机&#xff1a;组件初始化&#xff0c;依赖的状态发生变化&#xf…...

聚焦两会:科技与发展并进,赛逸展2025成创新新舞台

在十四届全国人大三次会议和全国政协十四届三次会议期间&#xff0c;代表委员们围绕多个关键议题展开深入讨论&#xff0c;为国家未来发展谋篇布局。其中&#xff0c;技术竞争加剧与经济转型需求成为两会焦点&#xff0c;将在首都北京举办的2025第七届亚洲消费电子技术贸易展&a…...

深入C语言:指针与数组的经典笔试题剖析

1. sizeof和strlen的对比 1.1 sizeof sizeof 是C语言中的一个操作符&#xff0c;用于计算变量或数据类型所占内存空间的大小&#xff0c;单位是字节。它不关心内存中存储的具体数据内容&#xff0c;只关注内存空间的大小。 #include <stdio.h> int main() {int a 10;…...

⚡ 回声谷即时通讯系统

基于SpringBootVue3的实时通信解决方案 &#x1f31f; 核心特性 #mermaid-svg-uxEwEcjlUVI6Tjjf {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-uxEwEcjlUVI6Tjjf .error-icon{fill:#552222;}#mermaid-svg-uxEwEcjl…...

实验题目:授权及收回授权、约束、触发器

一、实验环境 实验使用普通PC机一台&#xff0c;MySQL数据库版本8.0.36&#xff0c;使用Navicat Premium 16提供图形化界面。 二、实验内容 1、数据库的账号、用户的建立、删除以及授权机制 2、数据库中数据完整性约束控制技术 3、触发器 三、具体完成情况&#xff08;提…...

Spark(8)配置Hadoop集群环境-使用脚本命令实现集群文件同步

一.hadoop的运行模式 二.scp命令————基本使用 三.scp命令———拓展使用 四.rsync远程同步 五.xsync脚本集群之间的同步 一.hadoop的运行模式 hadoop一共有如下三种运行方式&#xff1a; 1. 本地运行。数据存储在linux本地&#xff0c;测试偶尔用一下。我们上一节课使用…...

c#中使用时间戳转换器

在C#中,时间戳转换器通常用于将时间戳(通常是一个表示自某一特定时间点(如1970年1月1日UTC)以来的毫秒数的长整型值)转换为DateTime对象,或者将DateTime对象转换回时间戳。以下是几种实现这一功能的方法: 1. 使用DateTime的构造函数 将时间戳转换为DateTime long tim…...

LLM中的transformer结构学习(二 完结 Multi-Head Attention、Encoder、Decoder)

文章目录 LLM中的transformer结构学习&#xff08;二 完结 Multi-Head Attention、Encoder、Decoder&#xff09;Self-Attention &#xff08;自注意力机制&#xff09;结构多头注意力 EncoderAdd & Norm 层Feed Forward 层 EncoderDecoder的第一个Multi-Head AttentionMas…...

FreeSWITCH 之 chat

要把 FreeSWITCH 之 chat 完全研究清楚&#xff0c;似乎不容易 发送&#xff0c;路由&#xff0c;接收 跟哪些模块有关 等等 咱一边查资料&#xff0c;一边整理&#xff0c;不着急 先看看 Kamalio 怎么发 MESSAGE loadmodule "uac.so"route[uac_send_message] {…...

本地fake server,

C# 制作的系统级tcp 重定向&#xff0c;整个系统只要有访问指定url&#xff0c;返回自定义内容到访问端。不局限在浏览器单一方面。 再者请理解这个图的含金量&#xff0c;服务器down机都可以模拟。 用途那就太多了&#xff0c;当然很多用途都不正当。嘿嘿 如果你很想要源代…...

用Deepseek写一个 HTML 和 JavaScript 实现一个简单的飞机游戏

大家好&#xff01;今天我将分享如何使用 HTML 和 JavaScript 编写一个简单的飞机游戏。这个游戏的核心功能包括&#xff1a;控制飞机移动、发射子弹、敌机生成、碰撞检测和得分统计。代码简洁易懂&#xff0c;适合初学者学习和实践。 游戏功能概述 玩家控制&#xff1a;使用键…...

解析 SQL,就用 sqlparse!

文章目录 解析 SQL&#xff0c;就用 sqlparse&#xff01;一、背景&#xff1a;为什么你需要 sqlparse&#xff1f;二、什么是 sqlparse&#xff1f;三、如何安装 sqlparse&#xff1f;四、简单易用的库函数1\. parse(sql)2\. format(sql, **options)3\. split(sql)4\. get_typ…...

Flask 全栈学习指南

一、Flask 基础核心 1. 核心概念与启动流程 WSGI 与 Werkzeug Flask 基于 Werkzeug 实现 WSGI 协议&#xff0c;处理 HTTP 请求到响应的全流程。手动实现 WSGI 应用示例&#xff1a;def simple_app(environ, start_response):status 200 OKheaders [(Content-type, text/pla…...

git的使用

1、git的安装&#xff08;windows10&#xff09; 网址&#xff1a;Git - Downloading Package全部默认安装就好。在任意文件夹中右击&#xff0c;列表中出现git即为安装成功。 2、git的基本配置 右击打开git bash设置用户信息 git config --global user.name "username…...

MQTT协议下温度数据上报观测云最佳实践

MQTT 介绍 MQTT&#xff08;Message Queuing Telemetry Transport&#xff0c;消息队列遥测传输协议&#xff09;是一种轻量级的、基于发布/订阅模式的消息传输协议&#xff0c;专为低带宽、高延迟或不可靠的网络环境设计&#xff0c;广泛应用于物联网&#xff08;IoT&#xf…...

什么是Flask

Flask是Python中一个简单、灵活和易用的Web框架&#xff0c;适合初学者使用。它提供了丰富的功能和扩展性&#xff0c;可以帮助开发者快速构建功能完善的Web应用程序。 以下是Python Flask框架的一些特点和功能&#xff1a; Flask 是一个使用 Python 编写的轻量级 WSGI 微 Web…...

数字投屏叫号器-发射端python窗口定制

窗口 本系列前章介绍&#xff0c;叫号器的显示端&#xff0c;完成了视频音频的形成和传输的介绍。本章节开始定制小窗口。 最终实现&#xff0c;处于桌面最前端&#xff0c;发送指令&#xff0c;集合前篇即可完成&#xff1a; 处理本地text.txt更新&#xff0c;随之被rtsp采集…...

文本转语音-音画适时推送rtsp并播放

文本语音 rtsp适时播放叫号系统的底层逻辑 发布Linux, unix socket 和window win32做为音频源的 python10下的(ffmpeg version 7.1) 可运行版本. 这两天在弄这个&#xff0c;前2篇是通过虚拟声卡&#xff0c;达到了最简单的一个逻辑&#xff0c;播放文本就从声卡发声&#xff0…...

clickhouse修改和删除数据

标题&#xff1a;ClickHouse中修改和删除数据的简易指南 在大数据时代&#xff0c;数据库技术的发展日新月异。作为一款专为实时分析设计的列式数据库管理系统&#xff0c;ClickHouse因其高效的查询性能而受到欢迎。照这么推测的话&#xff0c;对于那些习惯于传统SQL操作&…...

2025CSP-J 冲刺训练(1):二分

2025CSP-J 冲刺训练 1 一、二分查找函数1. 头文件2. 前提条件3. 功能函数3.1 lower_bound3.2 upper_bound 二、二分答案模板1. 前提条件2. 模板 三、典型例题1. 寻找固定的和1.1 审题1.2 分析1.3 参考答案 2. Snuke Festival2.1 审题2.2 分析2.3 参考答案 四、拓展例题1. 晒衣服…...

无公网IP也能远程控制Windows:Linux rdesktop内网穿透实战

文章目录 前言1. Windows 开启远程桌面2. Linux安装rdesktop工具3. Win安装Cpolar工具4. 配置远程桌面地址5. 远程桌面连接测试6. 设置固定远程地址7. 固定地址连接测试 前言 如今远程办公已经从一种选择变成了许多企业和个人的必修课&#xff0c;而如何在Linux系统上高效地访…...

Win10 访问 Ubuntu 18 硬盘

目录 方案一&#xff1a;使用Samba共享服务Ubuntu 18 端配置Windows 10 端访问 方案二&#xff1a;使用 SSHFS&#xff08;需在 Windows 上安装 SSH 客户端&#xff09;Ubuntu 18 端配置Windows 10 端配置 方案三&#xff1a;使用 FTP 服务Ubuntu 18 端配置Windows 10 端访问 方…...

算法.习题篇

算法 — 地大复试 模拟 while循环和MOD循环计数 1.约瑟夫问题 http://bailian.openjudge.cn/practice/3254 using namespace std;bool isNoPeople(vector<bool> c)//判断当前数组是否一个小孩都没有了 {bool nopeople true;for (bool ival : c){if ( ival true)nop…...

upload-labs文件上传

第一关 上传一个1.jpg的文件&#xff0c;在里面写好一句webshell 保留一个数据包&#xff0c;将其中截获的1.jpg改为1.php后重新发送 可以看到&#xff0c;已经成功上传 第二关 写一个webshell如图&#xff0c;为2.php 第二关在过滤tpye的属性&#xff0c;在上传2.php后使用b…...

一二三应用开发平台——能力扩展:多数据源支持

背景 随着项目规模的扩大&#xff0c;单一数据源已无法满足复杂业务需求&#xff0c;多数据源应运而生。 技术选型 MyBatis-Plus 的官网提供了两种多数据源扩展插件&#xff1a;开源生态的 <font style"color:rgb(53, 56, 65);">dynamic-datasource</fon…...

【Python】整数除法不正确,少1的问题,以及有关浮点数转换的精度问题

1. 问题 今天在做leetcode 不同路径 的时候发现了个问题 对于m53 n4class Solution:def uniquePaths(self, m: int, n: int) -> int:rlt 1for i in range(0, m-1):rlt * (m n - 2 - i)for i in range(0, m-1):rlt / (i 1)return int(rlt)为什么这个结果是 26234class S…...

【贪心算法】简介

1.贪心算法 贪心策略&#xff1a;解决问题的策略&#xff0c;局部最优----》全局最优 &#xff08;1&#xff09;把解决问题的过程分成若干步 &#xff08;2&#xff09;解决每一步的时候&#xff0c;都选择当前看起来的“最优”的算法 &#xff08;3&#xff09;“希望”得…...

狮子座大数据分析(python爬虫版)

十二星座爱情性格 - 星座屋 首先找到一个星座网站&#xff0c;作为基础内容&#xff0c;来获取信息 网页爬取与信息提取 我们首先利用爬虫技术&#xff08;如 Python 中的 requests 与 BeautifulSoup 库&#xff09;获取页面内容。该页面&#xff08;xzw.com/astro/leo/&…...

【商城实战(20)】商品管理功能深化实战

【商城实战】专栏重磅来袭&#xff01;这是一份专为开发者与电商从业者打造的超详细指南。从项目基础搭建&#xff0c;运用 uniapp、Element Plus、SpringBoot 搭建商城框架&#xff0c;到用户、商品、订单等核心模块开发&#xff0c;再到性能优化、安全加固、多端适配&#xf…...

YC 孵化项目 Pinch:实时语音翻译视频会议平台;Mistral OCR:能处理多语言多模态复杂文档丨日报

开发者朋友们大家好&#xff1a; 这里是 「RTE 开发者日报」 &#xff0c;每天和大家一起看新闻、聊八卦。 我们的社区编辑团队会整理分享 RTE&#xff08;Real-Time Engagement&#xff09; 领域内「有话题的 技术 」、「有亮点的 产品 」、「有思考的 文章 」、「有态度的 …...

数据库原理6

1.数据是信息的载体 2.数据库应用程序人员的主要职责&#xff1a;编写应用系统的程序模块 3.关系规范化理论主要属于数据库理论的研究范畴 4.数据库主要有检索和修改&#xff08;包括插入&#xff0c;删除&#xff0c;更新&#xff09;两大操作 5.概念模型又称为语义模型。…...

深度学习与大模型基础-向量

大家好&#xff01;今天我们来聊聊向量&#xff08;Vector&#xff09;。别被这个词吓到&#xff0c;其实向量在我们的生活中无处不在&#xff0c;只是我们没注意罢了。 1. 向量是什么&#xff1f; 简单来说&#xff0c;向量就是有大小和方向的量。比如你从家走到学校&#x…...

OpenManus:3小时复刻 Manus(OpenManus安装指南)

项目地址&#xff1a;GitHub - mannaandpoem/OpenManus: No fortress, purely open ground. OpenManus is Coming. 安装指南 我们提供两种安装方式。推荐使用方式二&#xff08;uv&#xff09;&#xff0c;因为它能提供更快的安装速度和更好的依赖管理。 方式一&#xff1a;使…...

2025年渗透测试面试题总结-快某手-安全实习生(一面、二面)(题目+回答)

网络安全领域各种资源&#xff0c;学习文档&#xff0c;以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具&#xff0c;欢迎关注。 目录 快某手-安全实习生 一面 一、Linux操作&#xff1a;查看进程PID的5种方法 二、Elasticsearch&#x…...

【微信小程序】uniapp开发微信小程序

uniapp开发微信小程序 1、上拉加载 下拉刷新 import { onReachBottom, onPullDownRefresh } from dcloudio/uni-app;配置允许下拉刷新&#xff1a; {"path" : "pages/pet/pet","style" : {"navigationBarTitleText" : ""…...