【数据结构】6栈
0
章节
3.1到3.3小节。
认知与理解栈结构;
列举栈的操作特点。
理解并列举栈的应用案例。
重点
栈的特点与实现;
难点
栈的灵活实现与应用
作业或思考题
完成学习测试2,?
内容达成以下标准(考核点):
正确实现栈基本操作;
分析总结栈与队列实现算法;
作业4:栈和队列基本操作
一、题目及分析
1.1题目
有两组型数:A(99,98,89,88,78,78,69,68)和B(89,88,87,86,85,84,83,82,81),
(1)分别建立顺序栈和链栈,来存放A和B,实现数据入栈和出栈操作,输出一种数据元素入栈和对应出栈列表;
(2)分别建立顺序队列和链队列,来存放A和B,实现数据入队和出队操作,输出数据元素入队和出队顺序 ;
1.2分析问题与实现工程类结构图
题目要求使用顺序栈、链栈、顺序队列和链队列来存放两组数据A和B,并实现相应的入栈、出栈、入队和出队操作。需要分析每种数据结构的特点和操作过程,然后根据题目要求编写相应的代码。
1. 顺序栈(数组):顺序栈是一种使用数组实现的栈,具有先进后出(LIFO)的特点。入栈操作即将数据元素依次添加到栈顶,出栈操作即将栈顶元素移除并返回。入栈操作时,需要判断栈是否已满,若未满则将元素添加到栈顶;出栈操作时,需要判断栈是否为空,若不为空则将栈顶元素移除并返回。由于顺序栈的栈顶位置在数组的末尾,所以入栈、出栈操作的时间复杂度均为O(1)。
2. 链栈:链栈是一种使用链表实现的栈,同样具有先进后出的特点。内存动态分配,无固定大小限制。入栈操作即将数据元素添加到链表的头部,出栈操作即将链表头部元素移除并返回。入栈操作时,需要新建一个节点并将其添加到链表头部;出栈操作时,需要判断链表是否为空,若不为空则将链表头部节点移除并返回。由于链栈的栈顶位置在链表的头部,所以入栈、出栈操作的时间复杂度均为O(1)。
3. 顺序队列(数组):顺序队列是一种使用数组实现的队列,具有先进先出(FIFO)的特点。入队操作即将数据元素添加到队尾,出队操作即将队头元素移除并返回。入队操作时,需要判断队列是否已满,若未满则将元素添加到队尾;出队操作时,需要判断队列是否为空,若不为空则将队头元素移除并返回。由于顺序队列的队头和队尾位置在数组的两端,所以队列的元素位置可能会发生变动,需要使用循环队列来解决这个问题。循环队列可以通过“头尾相接”来实现,入队、出队操作的时间复杂度均为O(1)。
4. 链队列:链队列是一种使用链表实现的队列,同样具有先进先出的特点。入队操作即将数据元素添加到链表的尾部,出队操作即将链表头部元素移除并返回。入队操作时,需要新建一个节点并将其添加到链表尾部;出队操作时,需要判断链表是否为空,若不为空则将链表头部节点移除并返回。由于链队列的队头和队尾位置分别在链表的头部和尾部,所以入队、出队操作的时间复杂度均为O(1)。
对于每种数据结构,我们需要编写入栈、出栈、入队、出队的代码,并输出数据元素入栈和对应出栈列表,以及数据元素入队和出队的顺序。
1.3工程类结构图
二、类的实现
2.1 SeqStck类代码
package homework4;//1,顺序栈
public class SeqStack<T> {private int maxSize; // 栈的最大容量private Object[] stackArray; // 存储栈元素的数组private int top; // 栈顶指针,指向栈顶元素的下标// 构造方法,初始化栈public SeqStack(int size) {maxSize = size;stackArray = new Object[maxSize];top = -1;}// 判断栈是否为空public boolean isEmpty() {return top == -1;}// 判断栈是否已满public boolean isFull() {return top == maxSize - 1;}// 入栈操作public void push(T data) {if (isFull()) {System.out.println("栈已满,无法入栈");return;}stackArray[++top] = data;}// 出栈操作public T pop() {if (isEmpty()) {System.out.println("栈为空,无法出栈");return null;}return (T) stackArray[top--];}}
2.2 LinkedStack类代码
package homework4;//2,链栈
public class LinkedStack<T> {private Node<T> top; // 栈顶节点// 构造方法,初始化链栈public LinkedStack() {top = null;}// 判断链栈是否为空public boolean isEmpty() {return top == null;}// 入栈操作public void push(T data) {Node<T> newNode = new Node<>(data);newNode.next = top;top = newNode;}// 出栈操作public T pop() {if (isEmpty()) {System.out.println("链栈为空,无法出栈");return null;}T data = top.data;top = top.next;return data;}// 链栈节点的定义private class Node<T> {private T data;private Node<T> next;public Node(T data) {this.data = data;}}
}
2.3 SeqQueue类代码
package homework4;//3,顺序队列
public class SeqQueue<T> {private int maxSize; // 队列的最大容量private Object[] queueArray; // 存储队列元素的数组private int front; // 队头指针,指向队头元素的下标private int rear; // 队尾指针,指向队尾元素的下标的后一个位置// 构造方法,初始化队列public SeqQueue(int size) {maxSize = size;queueArray = new Object[maxSize];front = rear = 0;}// 判断队列是否为空public boolean isEmpty() {return front == rear;}// 判断队列是否已满public boolean isFull() {return (rear + 1) % maxSize == front;}// 入队操作public void enqueue(T data) {if (isFull()) {System.out.println("队列已满,无法入队");return;}queueArray[rear] = data;rear = (rear + 1) % maxSize;}// 出队操作public T dequeue() {if (isEmpty()) {System.out.println("队列为空,无法出队");return null;}T data = (T) queueArray[front];front = (front + 1) % maxSize;return data;}
}
2.4 LinkedQueue类代码
package homework4;//4,链队列
public class LinkedQueue<T> {private Node<T> front; // 队头节点private Node<T> rear; // 队尾节点// 构造方法,初始化链队列public LinkedQueue() {front = rear = null;}// 判断链队列是否为空public boolean isEmpty() {return front == null;}// 入队操作public void enqueue(T data) {Node<T> newNode = new Node<>(data);if (isEmpty()) {front = rear = newNode;} else {rear.next = newNode;rear = newNode;}}// 出队操作public T dequeue() {if (isEmpty()) {System.out.println("链队列为空,无法出队");return null;}T data = front.data;front = front.next;if (front == null) {rear = null;}return data;}// 链队列节点的定义private class Node<T> {private T data;private Node<T> next;public Node(T data) {this.data = data;}}
}
2.5 Main类代码
package homework4;public class Main {public static void main(String[] args) {// 分别建立顺序栈和链栈来存放ASeqStack<Integer> seqStackA = new SeqStack<>(8);LinkedStack<Integer> linkedStackA = new LinkedStack<>();int[] stackDataA = {99, 98, 89, 88, 78, 78, 69, 68};for (int j : stackDataA) {seqStackA.push(j);linkedStackA.push(j);}System.out.println("顺序栈A出栈顺序:");while (!seqStackA.isEmpty()) {System.out.print(seqStackA.pop() + " ");}System.out.println();System.out.println("链栈A出栈顺序:");while (!linkedStackA.isEmpty()) {System.out.print(linkedStackA.pop() + " ");}System.out.println();// 分别建立顺序队列和链队列来存放BSeqQueue<Integer> seqQueueB = new SeqQueue<>(10);LinkedQueue<Integer> linkedQueueB = new LinkedQueue<>();int[] queueDataB = {89, 88, 87, 86, 85, 84, 83, 82, 81};for (int j : queueDataB) {seqQueueB.enqueue(j);linkedQueueB.enqueue(j);}System.out.println("顺序队列B出队顺序:");while (!seqQueueB.isEmpty()) {System.out.print(seqQueueB.dequeue() + " ");}System.out.println();System.out.println("链队列B出队顺序:");while (!linkedQueueB.isEmpty()) {System.out.print(linkedQueueB.dequeue() + " ");}System.out.println();}
}
三、结果与总结
3.1程序运行结果
3.2总结
SeqStack类、LinkedStack类、SeqQueue类和LinkedQueue类分别实现了顺序栈、链栈、顺序队列和链队列数据结构。它们的优点和缺点如下:
SeqStack类的优点:
1. 使用数组实现,插入和删除元素的时间复杂度为O(1),具有较高的效率。
2. 对于固定大小的栈,空间利用率较高。
SeqStack类的缺点:
1. 需要预先指定栈的最大容量,如果栈的元素个数超过了容量,会导致栈溢出。
2. 在插入或删除元素时,需要移动其他元素的位置,效率较低。
LinkedStack类的优点:
1. 使用链表实现,插入和删除元素的时间复杂度为O(1),具有较高的效率。
2. 不需要预先指定栈的最大容量,可以根据实际需求动态调整。
LinkedStack类的缺点:
1. 需要额外的内存空间存储链表节点的指针,占用较多的内存。
2. 对于频繁插入或删除元素的操作,可能会导致频繁的内存分配和释放,影响性能。
SeqQueue类的优点:
1. 使用数组实现,循环队列的方式解决了队列满时无法插入元素的问题。
2. 插入和删除元素的时间复杂度为O(1),具有较高的效率。
SeqQueue类的缺点:
1. 需要预先指定队列的最大容量,如果队列的元素个数超过了容量,会导致队列溢出。
2. 在删除元素时,需要移动其他元素的位置,效率较低。
LinkedQueue类的优点:
1. 使用链表实现,插入和删除元素的时间复杂度为O(1),具有较高的效率。
2. 不需要预先指定队列的最大容量,可以根据实际需求动态调整。
LinkedQueue类的缺点:
1. 需要额外的内存空间存储链表节点的指针,占用较多的内存。
2. 对于频繁插入或删除元素的操作,可能会导致频繁的内存分配和释放,影响性能。
3. 在获取队列长度时,需要遍历整个链表,效率较低。
综上所述,不同的数据结构适用于不同的场景。如果需要固定大小的栈或队列,并且对空间利用率有要求,可以选择SeqStack类和SeqQueue类;如果需要动态调整大小的栈或队列,并且对内存占用有要求,可以选择LinkedStack类和LinkedQueue类。
实验2:栈和队列的应用
一、题目一
1.1题目
编程实现将一个M进制整数转换成N进制数,程序运行时M和N由键盘输入(M和N为正整数),并将一个具体M进制数转成N进制数输出。
1.2问题的分析
根据题目要求,我们需要将一个M进制整数转换为N进制数。具体而言,需要完成以下几个步骤:
1. 从键盘读取输入的M和N(M和N为正整数)。
2. 从键盘读取输入的M进制整数。
3. 将M进制整数转换为十进制数(使用栈来存储每一位的值,计算时需要按权展开累加)。
4. 将十进制数转换为N进制数(使用队列来存储每一位的值,求余数并入队,再不断整除进队)。
5. 输出转换后的N进制数。
在上述步骤中,我们可以使用栈来实现将M进制整数转换为十进制数,因为栈具有后进先出的特性,适合处理从右到左的操作。而将十进制数转换为N进制数,我们可以使用队列来实现,因为队列具有先进先出的特性,适合处理从左到右的操作。
1.3 工程中类结构图
类BaseConversion,该类包含以下成员变量:
- num:待转换的M进制整数;
- M:原进制;
- N:目标进制;
- decimalNum:转换为十进制的数字;
- convertedNum:转换为N进制的结果。
该类可以包含以下方法:
- 构造函数:接收M进制整数、原进制和目标进制,将M进制整数转换为十进制数,并将十进制数转换为目标进制数;
- convertToDecimal方法:接收M进制整数和原进制,将M进制整数转换为十进制数,并使用栈来辅助计算;
- convertFromDecimal方法:接收十进制数和目标进制,将十进制数转换为目标进制数,并使用队列来辅助计算;
- charToInt方法:将一个字符转换为对应的整数;
- intToChar方法:将一个整数转换为对应的字符;
- printResult方法:输出转换后的N进制数。
类Test1
在主函数中,可以从键盘读取输入的M和N值以及M进制数,然后创建一个BaseConversion对象进行转换,最后输出转换后的N进制数。
1.4各个类的实现
通过BaseConversion类中的convertToDecimal和convertFromDecimal函数将M进制数转换为十进制数,再将十进制数转换为N进制数。在main函数中,先读取输入的M和N值以及M进制数,然后创建一个BaseConversion对象进行转换,最后输出转换后的N进制数。
首先定义了BaseConversion类,该类包含了num(待转换的M进制整数)、M(原进制)、N(目标进制)、decimalNum(转换为十进制的数字)和convertedNum(转换为N进制的结果)等成员变量。
在构造函数中,将输入的M进制整数转换为十进制数,并将十进制数转换为N进制数。
convertToDecimal方法使用了栈来辅助计算,从num的最后一位开始,通过charToInt将字符转换为对应的数字,并根据M的幂次进行累加得到十进制数。
convertFromDecimal方法使用了队列来辅助计算,通过不断将十进制数除以N,得到余数并入队列,直到十进制数变为0。然后依次出队列,通过intToChar将数字转换为对应的字符,构建出N进制数的字符串表示。
接着是定义了charToInt方法和intToChar方法,用于字符和数字的相互转换。
在printResult方法中,输出转换后的N进制数。
最后,在Test1类的main函数中,从键盘读取输入的M和N,并输入待转换的M进制整数。然后创建一个BaseConversion对象,并传入参数进行转换。最后调用printResult方法输出转换后的结果。
1.4.1 BaseConversion类代码
package experience2;import java.util.Stack;
import java.util.Queue;
import java.util.LinkedList;public class BaseConversion {private String num;private int M;private int N;private int decimalNum;private String convertedNum;public BaseConversion(String num, int M, int N) {this.num = num;this.M = M;this.N = N;// 将输入的M进制整数转换为十进制数decimalNum = this.convertToDecimal(num, M);// 将十进制数转换为N进制数convertedNum = this.convertFromDecimal(decimalNum, N);}// 将一个M进制整数转换为十进制数public static int convertToDecimal(String num, int M) {int decimalNum = 0;int power = 1;Stack<Integer> stack = new Stack<>();for (int i = num.length() - 1; i >= 0; i--) {int digit = charToInt(num.charAt(i));decimalNum += digit * power;power *= M;}return decimalNum;}// 将一个十进制数转换为N进制数public static String convertFromDecimal(int decimalNum, int N) {Queue<Integer> queue = new LinkedList<>();while (decimalNum > 0) {int remainder = decimalNum % N;queue.offer(remainder);decimalNum /= N;}StringBuilder sb = new StringBuilder();while (!queue.isEmpty()) {sb.append(intToChar(queue.poll()));}return sb.toString();}// 将一个字符转换为对应的整数private static int charToInt(char ch) {if (ch >= '0' && ch <= '9') {return ch - '0';} else {return ch - 'A' + 10;}}// 将一个整数转换为对应的字符private static char intToChar(int num) {if (num >= 0 && num <= 9) {return (char) ('0' + num);} else {return (char) ('A' + num - 10);}}public void printResult () {// 输出转换后的N进制数System.out.println(num + "的" + N + "进制表示为:" + convertedNum);}
}
1.4.2 Test1类代码
package experience2;import java.util.Scanner;public class Test1 {public static void main(String[] args) {// 从键盘读取输入的M和NScanner scanner = new Scanner(System.in);System.out.println(">=======将一个M进制整数转换成N进制数========<");System.out.print("请输入M的值:");int M = scanner.nextInt();System.out.print("请输入N的值:");int N = scanner.nextInt();// 从键盘读取输入的M进制整数System.out.print("请输入一个M进制整数:");String num = scanner.next();// 创建一个BaseConversion对象,并传入参数
// BaseConversion bc = new BaseConversion("123", 8, 2);BaseConversion bc = new BaseConversion(num, M, N);//输出结果, 输出转换后的N进制数bc.printResult();}
}
1.5程序运行结果
二、题目二
2.1题目
数据结构是一门较难的课程,同学们学习时问题较多,请你编写一个课程答疑程序,对多个同学的问题进行一一解答。
2.2问题的分析
这个程序的主要目标是模拟一个课堂答疑环境。在这个环境中,学生可以提出问题,问题被放入一个队列中,然后老师从队列中取出问题并回答。
这个程序的设计涉及到几个主要的问题:
1. 如何表示学生和问题?
创建了一个学生类和一个问题类来解决这个问题。学生类包含学生的姓名、编号和他们提出的问题列表。问题类包含提问者和问题内容。
2. 如何存储问题?
使用一个循环队列来存储问题。循环队列是一种特殊的队列,当队列满时,新的元素会被添加到队列的开头。这种数据结构非常适合模拟这个问题,因为它可以保证问题按照先进先出的顺序被回答。
3. 如何处理问题?
创建学生对象和问题对象,然后将问题添加到循环队列中。然后,使用一个循环,从队列中取出问题并回答,直到队列为空。
需求:
1. 需要定义一个学生类(Student),包含学生的姓名、学号和问题列表。
2. 需要定义一个问题类(Question),包含提问者(学生对象)和问题内容。
3. 需要定义一个循环队列类(CircularQueue),实现队列接口(QueueInterface),用于存储学生的问题。
4. 主类(Main)中,创建循环队列对象和多个学生对象,并将学生的问题加入队列中。
5. 使用循环队列模拟老师回答问题的过程,从队列中取出问题并进行回答。
2.3工程中类结构图
程序包括以下几个部分:
1. 接口QueueInterface:定义了队列的基本操作,包括入队、出队、获取队头元素和判断队列是否为空。
2. 类CircularQueue:实现了QueueInterface接口,代表一个循环队列。它使用数组实现队列,并记录了队列的大小、队头和队尾指针。具体的功能包括入队、出队、获取队头元素和判断队列是否为空。
3. 类Question:代表一个问题,包含提问者和问题内容。它提供了输出问题信息的方法。
4. 类Student:代表一个学生,包含学号、姓名和问题列表。它提供了添加问题和输出学生信息的方法。
5. 主类Main:在main方法中创建了一个CircularQueue对象和两个Student对象,并将学生的问题加入队列中。然后通过循环从队列中取出问题并回答。
程序的运行逻辑如下:
1. 创建循环队列对象queue。
2. 创建两个Student对象s1和s2,并为每个学生添加问题。
3. 将学生的问题加入队列中。
4. 循环从队列中取出问题,回答问题,并输出回答内容。
2.4各个类的实现
2.4.1 CircularQueue类代码
package experience2.t2;// 定义循环队列,实现接口
public class CircularQueue<T> implements Queue<T> {private T[] queue;private int size;int front, rear;public CircularQueue() {front = rear = 0;size = 5;queue = (T[]) (new Object[size]);}void setSize(int n) {this.size = n;}public void enterQueue(T element) {if ((rear + 1) % size == front) {System.out.print("队列满");return;}queue[rear] = element;rear = (rear + 1) % size;System.out.println(" front=" + front + ",rear=" + rear);}public T delQueue() {if (isEmpty()) {System.out.print("队空");return null;}T queueHead = queue[front];front = (front + 1) % size;System.out.println(" front=" + front + ",rear=" + rear);return queueHead;}public T getHead() {if (isEmpty()) {System.out.print("队空");return null;}T queueHead = queue[front + 1];System.out.println(" front=" + front + ",rear=" + rear);return queueHead;}public boolean isEmpty() {return rear == front;}
}
2.4.2 Question类代码
package experience2.t2;public class Question {Student asker;String content;public Question(Student asker, String content) {this.asker = asker;this.content = content;}public void outInformation() {System.out.println("来自 " + asker.name + " 的问题: " + content);}
}
2.4.3 Queue接口代码
package experience2.t2;// 定义接口规范队列完成功能
public interface Queue<T> {void enterQueue(T element);T delQueue();T getHead();boolean isEmpty();
}
2.4.4 Student类代码
package experience2.t2;import java.util.ArrayList;
import java.util.List;public class Student {String num;String name;List<Question> questions;public Student(String name, String num) {this.num = num;this.name = name;this.questions = new ArrayList<>();}public void addQuestion(Question question) {this.questions.add(question);}public void outInformation() {System.out.println(name + "," + num);}
}
2.4.5 Test2类代码
package experience2.t2;public class Test2 {public static void main(String[] args) {CircularQueue<Question> queue = new CircularQueue<>();Student s1 = new Student("LiMing", "123456789");s1.addQuestion(new Question(s1, "数据结构是什么?"));s1.addQuestion(new Question(s1, "队列是如何工作的?"));Student s2 = new Student("YiMing", "2323345");s2.addQuestion(new Question(s2, "什么是栈?"));s2.addQuestion(new Question(s2, "二叉树是如何工作的?"));// 学生提问for (Question question : s1.questions) {queue.enterQueue(question);}for (Question question : s2.questions) {queue.enterQueue(question);}// 老师回答问题while (!queue.isEmpty()) {Question question = queue.delQueue();System.out.println("回答问题: ");question.outInformation();System.out.println("回答: 这是一个好问题。");}}
}
2.5程序运行结果
三 实验总结
3.1对于问题一
1:如何将M进制数转换为十进制数?
解决方案:使用栈来辅助计算。从M进制数的最后一位开始,通过charToInt方法将字符转换为对应的数字,并根据M的幂次进行累加得到十进制数。
2:如何将十进制数转换为N进制数?
解决方案:使用队列来辅助计算。通过不断将十进制数除以N,得到余数并入队列,直到十进制数变为0。然后依次出队列,通过intToChar方法将数字转换为对应的字符,构建出N进制数的字符串表示。
3:如何将字符转换为对应的整数?
解决方案:使用charToInt方法将字符转换为对应的整数。如果字符是数字,则将其减去字符'0'的ASCII码值;如果字符是字母,则将其减去字符'A'的ASCII码值再加上10。
4:如何将整数转换为对应的字符?
解决方案:使用intToChar方法将整数转换为对应的字符。如果整数在0到9之间,则将其加上字符'0'的ASCII码值;如果整数在10到35之间,则将其加上字符'A'的ASCII码值再减去10。
在程序实现过程中,采用了面向对象的编程思想,将转换的逻辑封装在BaseConversion类中,并且通过构造函数进行初始化。这样做的好处是可以重复使用该类,并且提高代码的可读性和可维护性。
程序的优点:
1. 可以实现将任意M进制整数转换为N进制数,具有一定的通用性。
2. 使用栈和队列来辅助计算,遵循了栈先进后出和队列先进先出的特点,使得转换过程更加简洁明了。
3. 代码结构清晰,函数划分合理,易于理解和维护。
程序的缺点:
1. 没有对用户输入的数据进行验证和异常处理,如果输入的M和N不是正整数或M进制数中包含非法字符,程序可能会出现错误。
2. 对于大数字的计算可能存在效率问题,因为使用了栈和队列来存储每一位的值,当数字很大时,可能会占用较多的内存空间。
3. 在实际使用中,需要注意对输入数据的验证和异常处理,以及对大数字的计算效率优化。
3.2对于问题二
在这个实验中,我们实现了一个循环队列和学生提问的模拟。通过这个实验,我遇到了一些问题并找到了解决方法。
问题1:为什么要使用循环队列?
解决方法:循环队列可以有效地利用存储空间,通过循环利用数组空间来实现队列的功能。当队列满时,可以将队尾指针重新指向队首,实现循环利用。
问题2:如何判断队列是否为空?
解决方法:我们可以通过判断队首指针和队尾指针是否相等来判断队列是否为空。如果相等,则表示队列为空。
问题3:为什么需要定义Question类和Student类?
解决方法:Question类表示学生的问题,包含提问者和问题内容两个属性。Student类表示学生,包含姓名、学号和问题列表三个属性。通过定义这两个类,我们可以将学生的问题与学生进行关联,并方便地管理学生的问题。
程序优点:
1. 实现了循环队列的基本功能,包括入队、出队、获取队首元素和判断队列是否为空。
2. 分别定义了Question类和Student类,使得代码结构清晰,易于理解和扩展。
3. 使用了泛型,可以适应不同类型的队列元素。
程序缺点:
1. 循环队列的大小是固定的,无法动态扩容。如果队列已满,再添加元素会导致队列溢出。
2. 没有提供删除指定元素的功能,只能删除队首元素。
3. 在CircularQueue类中,没有提供获取队尾元素的方法,只能通过出队操作来获取队尾元素。
4. 没有对输入进行严格的校验,比如在enterQueue()方法中,没有判断element是否为null。
通过这个实验,我学习了循环队列的实现原理和相关操作。在今后的编程实践中,我会更加注重程序的可扩展性和灵活性,同时注意处理边界情况和异常情况,提高程序的健壮性。
相关文章:
【数据结构】6栈
0 章节 3.1到3.3小节。 认知与理解栈结构; 列举栈的操作特点。 理解并列举栈的应用案例。 重点 栈的特点与实现; 难点 栈的灵活实现与应用 作业或思考题 完成学习测试2,? 内容达成以下标准(考核…...
【C++】每日一练(有效的括号)
本篇博客给大家带来的是用C语言来解答有效的括号! 🐟🐟文章专栏:每日一练 🚀🚀若有问题评论区下讨论,我会及时回答 ❤❤欢迎大家点赞、收藏、分享! 今日思想:不服输的少年…...
数字化新零售与 AI 大模型,如何重塑大健康赛道?
在数字化浪潮中,大健康赛道正经历深刻变革。数字化新零售营销模式的兴起,与 AI 大模型的强大能力相结合,为大健康领域带来了全新的发展机遇。 数字化新零售营销模式融合线上线下,运用大数据、云计算分析消费者行为,实…...
Android实现Socket通信
问题: 我在Android端对接后端Socket服务实现消息模块的时候,使用WebSocketClient 库,手动构造了订阅和发送消息的 STOMP 帧,,Socket连接成功建立,但是当用户发送消息的时候,对方无法接受到。 …...
✅ Vue 3 响应式写法小抄表(Composition API 实战模板)
📦 引入核心响应式工具 import { ref, reactive, computed, watch, toRefs } from vue1️⃣ 基本类型(string / number / boolean) → 推荐使用 ref() const username ref() const count ref(0) const isLoading ref(false)2️⃣ 对象/表…...
Python数据分析之数据可视化
Python 数据分析重点知识点 本系列不同其他的知识点讲解,力求通过例子让新同学学习用法,帮助老同学快速回忆知识点 可视化系列: Python基础数据分析工具数据处理与分析数据可视化机器学习基础 四、数据可视化 图表类型与选择 根据数据特…...
TCP协议支持全双工原因TCP发送接收数据是生产者消费者模型
一、TCP支持全双工的原因 TCP协议支持全双工,即使用TCP协议进行通信时,服务端和客户端可以同时进行数据的发送和接收,互不干扰,实现同时双向传输数据。 这是因为使用TCP协议通信时,读写套接字的文件描述符既用来发送…...
【ODHead】BEVDet的 CenterHead的推理和拓展到蒸馏损失的算法细节
文章目录 背景常识1、BEVDet的CenterHead整体方案2、蒸馏部分3、输出 preds_dicts 部分3.1、headmap3.2、bbox3.3、Mask掩膜3.4、损失 背景常识 在BEVDet和BEVFormer里,使用了不同的3D detection head(BEVDet用了centerhead,BEVFormer用了de…...
在 CentOS 7 上安装 PHP 7.3
在 CentOS 7 上安装 PHP 7.3 可以按照以下步骤进行操作: 1. 安装必要的依赖和 EPEL 仓库 EPEL(Extra Packages for Enterprise Linux)是为企业级 Linux 提供额外软件包的仓库,yum-utils 用于管理 yum 仓库。 sudo yum install -…...
vue+dhtmlx-gantt 实现甘特图-快速入门【甘特图】
文章目录 一、前言二、使用说明2.1 引入依赖2.2 引入组件2.3 引入dhtmlx-gantt2.4 甘特图数据配置2.5 初始化配置 三、代码示例3.1 Vue2完整示例3.2 Vue3 完整示例 四、效果图 一、前言 dhtmlxGantt 是一款功能强大的甘特图组件,支持 Vue 3 集成。它提供了丰富的功…...
关于ModbusTCP/RTU协议对接Ethernet/IP(CIP)协议的方案
IGT-DSER智能网关模块支持西门子、倍福(BECKHOFF)、罗克韦尔AB,以及三菱、欧姆龙等各种品牌的PLC之间通讯,支持Ethernet/IP(CIP)、Profinet(S7),以及FINS、MC等工业自动化常用协议,同时也支持PLC与Modbus协议的工业机器人、智能仪…...
python-leetcode 49.二叉树中的最大路径和
题目: 二叉树中的路径被定义为一条节点序列,序列中每对相邻节点之间都存在一条边,同一个节点在一条路径序列中至多出现一次,该路径至少包含一个节点,且不一定经过根节点。 路径和是路径中各节点值得总和,…...
C语言基础知识04
指针 指针概念 指针保存地址,地址是字节的编号 指针类型和保存的地址类型要一直 使用时注意,把地址转换为&变量的格式来看 int a[3]; a转为&a[0] 指针的大小 64bit 固定8字节, 32bit 固定4字节 指针…...
使用 Golang 操作 MySQL
在Go语言中,操作SQL数据库,通常会用到一些第三方库来简化数据库的连接、查询和操作过程。其中原生的 database/sql go-sql-driver/mysql 库更符合sql语句使用习惯。 安装 go get github.com/go-sql-driver/mysql 直接上代码来演示基本的创建ÿ…...
前端面试:cookie 可以实现不同域共享吗?
在前端开发中,Cookie 不能直接实现不同域之间的共享。Cookie 的作用域受到域的限制,浏览器不会允许一个域下的 Cookie 被另一个域访问。这是为了保护用户隐私及安全,防止跨站请求伪造(CSRF)等安全问题。 Cookie 的基本…...
MyBatis-Plus接入和简单使用
如何接入 https://baomidou.com/getting-started/ 简单使用方法 使用 MyBatis-Plus 时,大多数场景下不需要编写 XML 和 SQL,因为它提供了强大的通用 CRUD 操作和条件构造器。但以下情况可能需要手动编写 SQL: 1. 不需要写 XML/SQL 的场景 …...
【Go万字洗髓经】Golang内存模型与内存分配管理
本文目录 1. 操作系统中的虚拟内存分页与进程管理虚拟内存与内存隔离 2. Golang中的内存模型内存分配流程内存单元mspan线程缓存mcache中心缓存mcentral全局堆缓存mheapheapArena空闲页索引pageAlloc 3. Go对象分配mallocgc函数tiny对象分配内存 4.结合GMP模型来看内存模型tiny…...
mov格式视频如何转换mp4?
mov格式视频如何转换mp4?在日常的视频处理中,经常需要将MOV格式的视频转换为MP4格式,以兼容更多的播放设备和平台。下面给大家分享如何将MOV视频转换为MP4,4款视频格式转换工具分享。 一、牛学长转码大师 牛学长转码大师是一款功…...
鸿蒙OS开发ForEach循环渲染
摘要 在ForEach循环渲染过程中,如果修改列表项中的数据,但是UI页面不会刷新。在最近开发公司app时遇到了这个问题,经过查看官方文档找到了解决方式 官方地址:数据变化不刷新 一、具体解决方案 思路:通过父子组件传…...
【算法】DFS、BFS、拓扑排序
⭐️个人主页:小羊 ⭐️所属专栏:算法 很荣幸您能阅读我的文章,诚请评论指点,欢迎欢迎 ~ 目录 持续更新中...1、DFS2、BFSN 叉树的层序遍历二叉树的锯齿形层序遍历二叉树最大宽度 3、多源BFS腐烂的苹果 4、拓扑排序 持续更新中…...
【Godot4.0】贝塞尔曲线在游戏中的实际应用
概述 之前研究贝塞尔曲线绘制,完全是以绘图函数,以及实现节点连接为思考。并没有实际考虑贝塞尔曲线在游戏中的应用。今日偶然看到悦千简一年多前发的一个用贝塞尔曲线实现追踪弹或箭矢效果,还有玩物不丧志的老李杀戮尖塔系列中的卡牌动态箭…...
MongoDB 数据导出与导入实战指南(附完整命令)
1. 场景说明 在 MongoDB 运维中,数据备份与恢复是核心操作。本文使用 mongodump 和 mongorestore 工具,演示如何通过命令行导出和导入数据,解决副本集连接、路径指定等关键问题。 2. 数据导出(mongodump) 2.1 导出命…...
『Rust』Rust运行环境搭建
文章目录 rust编译工具rustupVisual Studio VS Code测试编译手动编译VSCode编译配置 参考完 rust编译工具rustup https://www.rust-lang.org/zh-CN/tools/install 换源 RUSTUP_DIST_SERVER https://rsproxy.cn RUSTUP_UPDATE_ROOT https://rsproxy.cn修改rustup和cargo的安…...
CPU+GPU结合的主板设计思路与应用探讨
在高性能计算和图形处理需求不断增长的背景下,CPUGPU结合的主板设计逐渐成为硬件架构的重要趋势。本文将探讨基于CPUGPU架构的主板设计思路、关键技术考量以及应用前景。 1. 设计思路概述 CPU(中央处理器)擅长处理复杂的逻辑运算和多任务控制…...
latex问题汇总
latex问题汇总 环境问题1 环境 texlive2024 TeXstudio 4.8.6 (git 4.8.6) 问题1 编译过程有如下错 ! Misplaced alignment tab character &. l.173 International Conference on Infrared &Millimeter Waves, 2004: 667--... I cant figure out why you would wa…...
学习springboot-Bean管理(Bean 注册,Bean 扫描)
Bean 扫描 可以浏览下面的博客链接 :spring 学习 (注解)-CSDN博客 在学习spring 注解时,我们使用 Component ,Service,Controller等 这样的注解,将目标类信息,传递给IOC容器,为其创…...
iOS开发,SQLite.swift, Missing argument label ‘value:‘ in call问题
Xcode16中,集成使用SQLite.swift,创建表的时候: let id Expression<Int64>("id"),报错Missing argument label value: in call 直接使用SQLite.Expression<Int64>("id") 或者定义一个全局typ…...
【GIT】重新初始化远程仓库
有的时候我们克隆远端仓库会出错: git clone --depth 1 git116.*.*.*:/srv/customs.git D:\dev\projects\kdy\customs11\customs Cloning into D:\dev\projects\kdy\customs11\customs... remote: Enumerating objects: 1494, done. remote: Counting objects: 100…...
Vue3中 ref 与 reactive区别
ref 用途: ref 通常用于创建一个响应式的基本类型数据(如 string、number、boolean 等),但它也可以用于对象或数组 返回值: ref 返回一个带有 .value 属性的对象,访问或修改数据需要通过 .value 进行 使用场景: …...
apollo3录音到wav播放解决方法
SDK DEMO项目:ap3bp_evb_vos_pcm_recorder_20210901 pcm_recorder.c //***************************************************************************** // // Options // //***************************************************************************** #define PRINT…...
信号处理抽取多项滤波的数学推导与仿真
昨天的《信号处理之插值、抽取与多项滤波》,已经介绍了插值抽取的多项滤率,今天详细介绍多项滤波的数学推导,并附上实战仿真代码。 一、数学变换推导 1. 多相分解的核心思想 将FIR滤波器的系数 h ( n ) h(n) h(n)按相位分组,每…...
Java网络多线程
网络相关概念: 关于访问: IP端口 因为一个主机上可能有多个服务, 一个服务监听一个端口,当你访问的时候主机通过端口号就能知道要和哪个端口发生通讯.因此一个主机上不能有两个及以上的服务监听同一个端口. 协议简单来说就是数据的组织形式 好像是两个人交流一样,要保证自己说…...
linux centos 忘记root密码拯救
在CentOS 7中,如果忘记root密码,可以通过修改系统启动参数进入单用户模式或紧急模式进行重置。以下是两种常用方法,适用于物理机或虚拟机环境: 方法一:通过rd.break参数重置密码 步骤: 重启系统并进入GRU…...
C# 事件使用详解
总目录 前言 在C#中,事件(Events)是一种基于委托的重要机制,用于实现对象之间的松耦合通信。它通过发布-订阅模式(Publisher-Subscriber Pattern),允许一个对象(发布者)…...
flink cdc同步mysql数据
一、api 添加依赖 <dependency><groupId>org.apache.flink</groupId><artifactId>flink-connector-mysql-cdc</artifactId><!-- 请使用已发布的版本依赖,snapshot 版本的依赖需要本地自行编译。 --><version>3.3-SNAP…...
tomcat负载均衡配置
这里拿Nginx和之前做的Tomcat 多实例来实现tomcat负载均衡 1.准备多实例与nginx tomcat单机多实例部署-CSDN博客 2.配置nginx做负载均衡 upstream tomcat{ server 192.168.60.11:8081; server 192.168.60.11:8082; server 192.168.60.11:8083; } ser…...
Ceph(1):分布式存储技术简介
1 分布式存储技术简介 1.1 分布式存储系统的特性 (1)可扩展 分布式存储系统可以扩展到几百台甚至几千台的集群规模,而且随着集群规模的增长,系统整体性能表现为线性增长。分布式存储的水平扩展有以下几个特性: 节点…...
16、JavaEE核心技术-EL与 JSTL
EL与 JSTL 实践 一. EL(Expression Language) EL(表达式语言)是 JSP 2.0 中引入的一种简单的脚本语言,用于在 JSP 页面中简化数据的访问和显示。它通过一种类似于 JavaScript 的语法,允许开发者在 JSP 页面…...
RabbitMQ报错:Shutdown Signal channel error; protocol method
报错信息: Shutdown Signal: channel error; protocol method: #method<channel.close>(reply-code406, reply-textPRECONDITION_FAILED - unknown delivery tag 1, class-id60, method-id80) 原因 默认情况下 RabbitMQ 是自动ACK(确认签收&…...
使用DeepSeek完成一个简单嵌入式开发
开启DeepSeek对话 请帮我使用Altium Designer设计原理图、PCB,使用keil完成代码编写;要求:使用stm32F103RCT6为主控芯片,控制3个流水灯的原理图 这里需要注意,每次DeepSeek的回答都不太一样。 DeepSeek回答 以下是使…...
NLP技术介绍
NLP技术介绍 语言分析技术分词词性标注命令实体识别句法分析语义分析文本处理技术文本分类文本聚类情感分析文本生成机器翻译对话系统与交互技术聊天机器人问答系统语音识别与合成知识图谱与语义理解技术知识图谱语义搜索语义推理深度学习与预训练模型循环神经网络(RNN)及其变…...
pycharm + anaconda + yolo11(ultralytics) 的视频流实时检测,保存推流简单实现
目录 背景pycharm安装配置代码实现创建本地视频配置 和 推流配置视频帧的处理和检测框绘制主要流程遇到的一些问题 背景 首先这个基于完整安装配置了anaconda和yolo11的环境,如果需要配置开始的话,先看下专栏里另一个文章。 这次的目的是实现拉取视频流…...
C++编译问题——1模板函数的实现必须在头文件中
今天编译数据结构时,遇见一个编译错误 假设你有一个头文件 SeqList.h 和一个源文件 SeqList.cpp。 SeqList.h #ifndef SEQLIST_H #define SEQLIST_H#include <stdexcept> #include <iostream>template<typename T> class SeqList { private:sta…...
深度学习PyTorch之数据加载DataLoader
深度学习pytorch之简单方法自定义9类卷积即插即用 文章目录 数据加载基础架构1、Dataset类详解2、DataLoader核心参数解析3、数据增强 数据加载基础架构 核心类关系图 torch.utils.data ├── Dataset (抽象基类) ├── DataLoader (数据加载器) ├── Sampler (采样策略)…...
使用Beanshell前置处理器对Jmeter的请求body进行加密
这里我们用HmacSHA256来进行加密举例: 步骤: 1.先获取请求参数并对请求参数进行处理(处理成String类型) //处理请求参数的两种方法: //方法一: //获取请求 Arguments args sampler.getArguments(); //转…...
前端面试:如何减少项目里面 if-else?
在前端开发中,大量使用 if-else 结构可能导致代码调试困难、可读性降低和冗长的逻辑。不妨考虑以下多种策略来减少项目中的 if-else 语句,提高代码的可维护性和可读性: 1. 使用对象字面量替代 用对象字面量来替代 if-else 语句,…...
05.基于 TCP 的远程计算器:从协议设计到高并发实现
📖 目录 📌 前言🔍 需求分析 🤔 我们需要解决哪些问题? 🎯 方案设计 💡 服务器架构 🚀 什么是协议?为什么要设计协议? 📌 结构化数据的传输问题 …...
Matlab:矩阵运算篇——矩阵数学运算
目录 1.矩阵的加法运算 实例——验证加法法则 实例——矩阵求和 实例——矩阵求差 2.矩阵的乘法运算 1.数乘运算 2.乘运算 3.点乘运算 实例——矩阵乘法运算 3.矩阵的除法运算 1.左除运算 实例——验证矩阵的除法 2.右除运算 实例——矩阵的除法 ヾ( ̄…...
git reset的使用,以及解决还原后如何找回
文章目录 git reset 详解命令作用常用参数1. --soft2. --mixed(默认参数,可省略)3. --hard4. 提交引用 总结 git reset --hard HEAD^ 还原代码如何找回?利用 git reflog找回 git reset 详解 git reset 是 Git 中一个功能强大且较…...
react中字段响应式
class中用法: import React, { Component } from react export default class Index extends Component<any, any> { constructor(props) { super(props) this.state { settingInfo: {}, } } async componentDidMount() { let settingInfo awa…...