java-数据结构与算法-02-数据结构-05-栈
文章目录
- 1. 栈
- 1. 概述
- 2. 链表实现
- 3. 数组实现
- 4. 应用
- 2. 习题
- E01. 有效的括号-Leetcode 20
- E02. 后缀表达式求值-Leetcode 120
- E03. 中缀表达式转后缀
- E04. 双栈模拟队列-Leetcode 232
- E05. 单队列模拟栈-Leetcode 225
1. 栈
1. 概述
计算机科学中,stack 是一种线性的数据结构,只能在其一端添加数据和移除数据。习惯来说,这一端称之为栈顶,另一端不能操作数据的称之为栈底,就如同生活中的一摞书
栈是一种特殊的线性表,只能在一端进行操作
- 往栈中添加元素的操作,一般叫做 push,入栈
- 从栈中移除元素的操作,一般叫做 pop,出栈(只能移除栈顶元素,也叫做:弹出栈顶元素)
- 后进先出的原则,Last In First Out,LIFO
先提供一个栈接口
public interface Stack<E> {/*** 向栈顶压入元素* @param value 待压入值* @return 压入成功返回 true, 否则返回 false*/boolean push(E value);/*** 从栈顶弹出元素* @return 栈非空返回栈顶元素, 栈为空返回 null*/E pop();/*** 返回栈顶元素, 不弹出* @return 栈非空返回栈顶元素, 栈为空返回 null*/E peek();/*** 判断栈是否为空* @return 空返回 true, 否则返回 false*/boolean isEmpty();/*** 判断栈是否已满* @return 满返回 true, 否则返回 false*/boolean isFull();
}
栈的应用
浏览器的前进和后退
2. 链表实现
package com.itheima.datastructure.stack;import java.util.Iterator;
import java.util.StringJoiner;/*** 链表实现的栈。* 该类实现了Stack接口和Iterable接口,允许对栈中的元素进行迭代。** @param <E> 栈中元素的类型。*/
public class LinkedListStack<E> implements Stack<E>, Iterable<E> {/*** 栈的容量,默认为Integer.MAX_VALUE,表示不限制容量。*/private int capacity = Integer.MAX_VALUE;/*** 栈中元素的数量。*/private int size;/*** 链表的头节点,用于简化插入和删除操作。*/private final Node<E> head = new Node<>(null, null);/*** 默认构造函数。*/public LinkedListStack() {}/*** 带容量限制的构造函数。** @param capacity 栈的容量限制。*/public LinkedListStack(int capacity) {this.capacity = capacity;}/*** 将元素压入栈顶。** @param value 要压入栈的元素。* @return 如果栈未满,则返回true;否则返回false。*//*head -> 2 -> 1 -> null*/@Overridepublic boolean push(E value) {if (isFull()) {return false;}head.next = new Node<>(value, head.next);size++;return true;}/*** 从栈顶弹出一个元素。** @return 如果栈不为空,则返回栈顶元素;否则返回null。*//*head -> 2 -> 1 -> null*/@Overridepublic E pop() {if (isEmpty()) {return null;}Node<E> first = head.next;head.next = first.next;size--;return first.value;}/*** 查看栈顶元素。** @return 如果栈不为空,则返回栈顶元素;否则返回null。*/@Overridepublic E peek() {if (isEmpty()) {return null;}return head.next.value;}/*** 检查栈是否为空。** @return 如果栈为空,则返回true;否则返回false。*/@Overridepublic boolean isEmpty() {return size == 0;}/*** 检查栈是否已满。** @return 如果栈已满,则返回true;否则返回false。*/@Overridepublic boolean isFull() {return size == capacity;}/*** 创建一个迭代器,用于遍历栈中的元素。** @return栈的元素迭代器。*/@Overridepublic Iterator<E> iterator() {return new Iterator<E>() {Node<E> p = head.next;@Overridepublic boolean hasNext() {return p != null;}@Overridepublic E next() {E value = p.value;p = p.next;return value;}};}/*** 链表节点类,用于存储栈中的元素。** @param <E> 节点中存储的元素类型。*/static class Node<E> {E value;Node<E> next;public Node(E value, Node<E> next) {this.value = value;this.next = next;}}/*** 将栈中的元素转换为字符串表示。** @return 栈的字符串表示,元素之间用逗号分隔。*/@Overridepublic String toString() {StringJoiner sj = new StringJoiner(",");for (E e : this) {sj.add(e.toString());}return sj.toString();}
}
3. 数组实现
/*** 数组实现的栈类,支持泛型元素。* @param <E> 栈中元素的类型。*/
package com.itheima.datastructure.stack;import java.util.Iterator;public class ArrayStack<E> implements Stack<E>, Iterable<E> {/*** 存储栈元素的数组。*/private final E[] array;/*** 栈顶指针,指示当前栈的顶部元素的位置。*/private int top; // 栈顶指针/*** 构造一个指定容量的栈。* @param capacity 栈的初始容量。*/@SuppressWarnings("all")public ArrayStack(int capacity) {this.array = (E[]) new Object[capacity];}/*** 将元素压入栈顶。* @param value 要压入栈的元素。* @return 如果栈未满,则返回true;否则返回false。*/@Overridepublic boolean push(E value) {if (isFull()) {return false;}array[top++] = value;return true;}/*** 弹出栈顶元素。* @return 栈顶元素,如果栈为空,则返回null。*/@Overridepublic E pop() {if (isEmpty()) {return null;}E e = array[--top];array[top] = null; // help GCreturn e;}/*** 查看栈顶元素。* @return 栈顶元素,如果栈为空,则返回null。*/@Overridepublic E peek() {if (isEmpty()) {return null;}return array[top - 1];}/*** 检查栈是否为空。* @return 如果栈为空,则返回true;否则返回false。*/@Overridepublic boolean isEmpty() {return top == 0;}/*** 检查栈是否已满。* @return 如果栈已满,则返回true;否则返回false。*/@Overridepublic boolean isFull() {return top == array.length;}/*** 返回栈元素的迭代器,用于遍历栈。* @return栈元素的迭代器。*//*底 顶0 1 2 3a b c dp*/@Overridepublic Iterator<E> iterator() {return new Iterator<E>() {int p = top;@Overridepublic boolean hasNext() {return p > 0;}@Overridepublic E next() {return array[--p];}};}
}
4. 应用
模拟如下方法调用
public static void main(String[] args) {System.out.println("main1");System.out.println("main2");method1();method2();System.out.println("main3");
}public static void method1() {System.out.println("method1");method3();
}public static void method2() {System.out.println("method2");
}public static void method3() {System.out.println("method3");
}
模拟代码
package com.itheima.datastructure.stack;/*** CPU模拟类,使用栈来模拟方法的调用与返回。*/
public class CPU {/*** 方法帧类,用于存储方法的退出点。*/static class Frame {int exit;/*** 构造方法,初始化方法帧的退出点。* * @param exit 方法的退出点值。*/public Frame(int exit) {this.exit = exit;}}/*** 程序计数器,用于指示当前执行的指令位置。*/static int pc = 1;/*** 方法调用栈,用于模拟方法的调用与返回过程。*/static ArrayStack<Frame> stack = new ArrayStack<>(100);/*** 程序入口点。* * @param args 命令行参数。*/public static void main(String[] args) {// 初始化方法调用栈,压入一个表示main方法开始的帧stack.push(new Frame(-1));// 当栈不为空时,循环执行指令while (!stack.isEmpty()) {// 根据程序计数器的值执行相应的操作switch (pc) {case 1:// 执行main方法的第一段代码System.out.println("main1");pc++;break;case 2:// 执行main方法的第二段代码System.out.println("main2");pc++;break;case 3:// 调用method1方法stack.push(new Frame(pc + 1));pc = 100;break;case 4:// 调用method2方法stack.push(new Frame(pc + 1));pc = 200;break;case 5:// 方法返回,从栈中弹出方法帧,并跳转到退出点System.out.println("main3");pc = stack.pop().exit;break;case 100:// method1方法的代码段System.out.println("method1");stack.push(new Frame(pc + 1));pc = 300;break;case 101:// method1方法返回pc = stack.pop().exit;break;case 200:// method2方法的代码段System.out.println("method2");pc = stack.pop().exit;break;case 300:// method3方法的代码段System.out.println("method3");pc = stack.pop().exit;break;}}}
}
2. 习题
E01. 有效的括号-Leetcode 20
一个字符串中可能出现 [] () 和 {} 三种括号,判断该括号是否有效
有效的例子
()[]{}([{}])()
无效的例子
[)([)]([]
思路
- 遇到左括号, 把要配对的右括号放入栈顶
- 遇到右括号, 若此时栈为空, 返回 false,否则把它与栈顶元素对比
- 若相等, 栈顶元素弹出, 继续对比下一组
- 若不等, 无效括号直接返回 false
- 循环结束
- 若栈为空, 表示所有括号都配上对, 返回 true
- 若栈不为空, 表示右没配对的括号, 应返回 false
答案(用到了课堂案例中的 ArrayStack 类)
public boolean isValid(String s) {ArrayStack<Character> stack = new ArrayStack<>(s.length() / 2 + 1);for (int i = 0; i < s.length(); i++) {char c = s.charAt(i);if (c == '(') {stack.push(')');} else if (c == '[') {stack.push(']');} else if (c == '{') {stack.push('}');} else {if (!stack.isEmpty() && stack.peek() == c) {stack.pop();} else {return false;}}}return stack.isEmpty();
}
E02. 后缀表达式求值-Leetcode 120
后缀表达式也称为逆波兰表达式,即运算符写在后面
- 从左向右进行计算
- 不必考虑运算符优先级,即不用包含括号
示例
输入:tokens = ["2","1","+","3","*"]
输出:9
即:(2 + 1) * 3输入:tokens = ["4","13","5","/","+"]
输出:6
即:4 + (13 / 5)
题目假设
- 数字都视为整数
- 数字和运算符个数给定正确,不会有除零发生
代码
public int evalRPN(String[] tokens) {LinkedList<Integer> numbers = new LinkedList<>();for (String t : tokens) {switch (t) {case "+" -> {Integer b = numbers.pop();Integer a = numbers.pop();numbers.push(a + b);}case "-" -> {Integer b = numbers.pop();Integer a = numbers.pop();numbers.push(a - b);}case "*" -> {Integer b = numbers.pop();Integer a = numbers.pop();numbers.push(a * b);}case "/" -> {Integer b = numbers.pop();Integer a = numbers.pop();numbers.push(a / b);}default -> numbers.push(Integer.parseInt(t));}}return numbers.pop();
}
E03. 中缀表达式转后缀
public class E03InfixToSuffix {/*思路1. 遇到数字, 拼串2. 遇到 + - * /- 优先级高于栈顶运算符 入栈- 否则将栈中高级或平级运算符出栈拼串, 本运算符入栈3. 遍历完成, 栈中剩余运算符出栈拼串- 先出栈,意味着优先运算4. 带 ()- 左括号直接入栈- 右括号要将栈中直至左括号为止的运算符出栈拼串| || || |_____a+ba+b-ca+b*ca*b+c(a+b)*c*/public static void main(String[] args) {System.out.println(infixToSuffix("a+b"));System.out.println(infixToSuffix("a+b-c"));System.out.println(infixToSuffix("a+b*c"));System.out.println(infixToSuffix("a*b-c"));System.out.println(infixToSuffix("(a+b)*c"));System.out.println(infixToSuffix("a+b*c+(d*e+f)*g"));}/*** 将中缀表达式转换为后缀表达式。* 后缀表达式也称为逆波兰表达式,它使用栈的操作来实现运算符的优先级处理,有效地简化了计算过程。* * @param exp 中缀表达式字符串,包含数字、运算符和括号。* @return 后缀表达式字符串。*/static String infixToSuffix(String exp) {// 使用链表作为栈来存储运算符LinkedList<Character> stack = new LinkedList<>();// 使用StringBuilder来构建后缀表达式StringBuilder sb = new StringBuilder(exp.length());// 遍历中缀表达式的每个字符for (int i = 0; i < exp.length(); i++) {char c = exp.charAt(i);// 根据字符的不同类型进行处理switch (c) {case '*', '/', '+', '-' -> {// 处理运算符if (stack.isEmpty()) {stack.push(c);} else {if (priority(c) > priority(stack.peek())) {stack.push(c);} else {// 当当前运算符的优先级不高于栈顶运算符时,将栈顶运算符弹出到后缀表达式中while (!stack.isEmpty() && priority(stack.peek()) >= priority(c)) {sb.append(stack.pop());}stack.push(c);}}}case '(' -> {// 遇到左括号直接入栈stack.push(c);}case ')' -> {// 遇到右括号,将栈中的运算符依次弹出到后缀表达式中,直到遇到左括号while (!stack.isEmpty() && stack.peek() != '(') {sb.append(stack.pop());}// 弹出左括号,不加入到后缀表达式中stack.pop();}default -> {// 遇到数字直接加入到后缀表达式中sb.append(c);}}}// 将栈中剩余的运算符依次弹出到后缀表达式中while (!stack.isEmpty()) {sb.append(stack.pop());}// 返回构建好的后缀表达式return sb.toString();}/*** 计算运算符的优先级。* * @param c 运算符* @return 运算符的优先级* @throws IllegalArgumentException 如果运算符不合法,则抛出此异常*/
static int priority(char c) {// 使用switch表达式来根据运算符的类型返回对应的优先级return switch (c) {case '*' -> 2; // 乘法和除法具有相同的优先级case '/' -> 2;case '+' -> 1; // 加法和减法具有相同的优先级case '-' -> 1;case '(' -> 0; // 左括号具有最低优先级default -> throw new IllegalArgumentException("不合法的运算符:" + c);};
}}
返回结果
ab+c*
abc*+d-e*
abc+*
E04. 双栈模拟队列-Leetcode 232
给力扣题目用的自实现栈,可以定义为静态内部类
class ArrayStack<E> {private E[] array;private int top; // 栈顶指针@SuppressWarnings("all")public ArrayStack(int capacity) {this.array = (E[]) new Object[capacity];}public boolean push(E value) {if (isFull()) {return false;}array[top++] = value;return true;}public E pop() {if (isEmpty()) {return null;}return array[--top];}public E peek() {if (isEmpty()) {return null;}return array[top - 1];}public boolean isEmpty() {return top == 0;}public boolean isFull() {return top == array.length;}
}
参考解答,注意:题目已说明
- 调用 push、pop 等方法的次数最多 100
package com.itheima.datastructure.stack;/*** 双栈模拟队列** <ul>* <li>调用 push、pop 等方法的次数最多 100</li>* </ul>*/
public class E04Leetcode232 {/*队列头 队列尾b顶 底 底 顶s1 s2队列尾添加s2.push(a)s2.push(b)队列头移除先把 s2 的所有元素移动到 s1s1.pop()*/ArrayStack<Integer> s1 = new ArrayStack<>(100);ArrayStack<Integer> s2 = new ArrayStack<>(100);public void push(int x) { //向队列尾添加s2.push(x);}public int pop() { // 从对列头移除if (s1.isEmpty()) {while (!s2.isEmpty()) {s1.push(s2.pop());}}return s1.pop();}public int peek() { // 从对列头获取if (s1.isEmpty()) {while (!s2.isEmpty()) {s1.push(s2.pop());}}return s1.peek();}public boolean empty() {return s1.isEmpty() && s2.isEmpty();}}
E05. 单队列模拟栈-Leetcode 225
给力扣题目用的自实现队列,可以定义为静态内部类
public class ArrayQueue3<E> {private final E[] array;int head = 0;int tail = 0;@SuppressWarnings("all")public ArrayQueue3(int c) {c -= 1;c |= c >> 1;c |= c >> 2;c |= c >> 4;c |= c >> 8;c |= c >> 16;c += 1;array = (E[]) new Object[c];}public boolean offer(E value) {if (isFull()) {return false;} array[tail & (array.length - 1)] = value;tail++;return true;}public E poll() {if (isEmpty()) {return null;}E value = array[head & (array.length - 1)];head++;return value;}public E peek() {if (isEmpty()) {return null;}return array[head & (array.length - 1)];}public boolean isEmpty() {return head == tail;}public boolean isFull() {return tail - head == array.length;}
}
参考解答,注意:题目已说明
- 调用 push、pop 等方法的次数最多 100
- 每次调用 pop 和 top 都能保证栈不为空
public class E05Leetcode225 {/*队列头 队列尾cba顶 底queue.offer(a)queue.offer(b)queue.offer(c)*/ArrayQueue3<Integer> queue = new ArrayQueue3<>(100);int size = 0;public void push(int x) {queue.offer(x);for (int i = 0; i < size; i++) {queue.offer(queue.poll());}size++;}public int pop() {size--;return queue.poll();}public int top() {return queue.peek();}public boolean empty() {return queue.isEmpty();}
}
相关文章:

java-数据结构与算法-02-数据结构-05-栈
文章目录 1. 栈1. 概述2. 链表实现3. 数组实现4. 应用 2. 习题E01. 有效的括号-Leetcode 20E02. 后缀表达式求值-Leetcode 120E03. 中缀表达式转后缀E04. 双栈模拟队列-Leetcode 232E05. 单队列模拟栈-Leetcode 225 1. 栈 1. 概述 计算机科学中,stack 是一种线性的…...
Python 管理依赖包(pip, virtualenv)
在Python编程中,管理依赖包是开发工作的重要组成部分。正确管理依赖包可以确保代码在不同环境中的一致性和可移植性,避免版本冲突和依赖地狱等问题。Python中常用的依赖包管理工具包括pip和virtualenv。 一、pip pip是Python官方推荐的包管理工具&…...
Bigdecimal 导出为excel时显示未0E-10,不是0,怎么解决
在使用 BigDecimal 导出到 Excel 时,如果遇到显示为 0E-10 而不是 0 的问题,这通常是因为 BigDecimal 对象的精度问题。0E-10 表示的是 0 乘以 10 的 -10 次方,这在数学上等同于…...

springboot项目从jdk8升级为jdk17过程记录
背景:公司有升级项目jdk的规划,计划从jdk8升级到jdk11 开始 首先配置本地的java_home 参考文档:Mac环境下切换JDK版本及不同的maven-CSDN博客 将pom.xml中jdk1.8相关的版本全部改为jdk17,主要是maven编译插件之类的,…...

list、tuple、set和dict传参机制
1、list、tuple、set和dict传参机制 # -------------list------------- def f1(my_list):print(f"②f1()my_list:{my_list} 地址是:{id(my_list)}") # ["tom","mary","hsp"] 0x1122my_list[0]"jack"print(f&quo…...

Redis快速入门基础
Redis入门 Redis是一个基于内存的 key-value 结构数据库。mysql是二维表的接口数据库 优点: 基于内存存储,读写性能高 适合存储热点数据(热点商品、资讯、新闻) 企业应用广泛 官网:https://redis.io 中文网:https://www.redis.net.cn/ Redis下载与…...
python基础介绍
这次的专题是关于python的知识点,加油! 文章目录 1 什么是计算机(1.1 哪些可以称为计算机?(以下)(1.2 计算机可以完成的工作有哪些?(1.3 一台计算机由什么构成? 2. 什么是编程(2.1 编…...

SSRF中伪协议学习
SSRF常用的伪协议 file:// 从文件系统中获取文件内容,如file:///etc/passwd dict:// 字典服务协议,访问字典资源,如 dict:///ip:6739/info: ftp:// 可用于网络端口扫描 sftp:// SSH文件传输协议或安全文件传输协议 ldap://轻量级目录访问协议 tftp:// 简单文件传输协议 gopher…...

Java | Leetcode Java题解之第284题窥视迭代器
题目: 题解: class PeekingIterator<E> implements Iterator<E> {private Iterator<E> iterator;private E nextElement;public PeekingIterator(Iterator<E> iterator) {this.iterator iterator;nextElement iterator.next(…...
哈尔滨等保定级的常见问题
一、哈尔滨等保测评定级标准理解问题 哈尔滨等保测评如何确定信息系统的安全保护等级? 信息系统的安全保护等级应根据其在国家安全、经济建设、社会生活中的重要程度,以及一旦遭到破坏后对国家安全、社会秩序、公共利益以及公民、法人和其他组织的合法权…...

springAOP理解及事务
AOP: springAOP是什么: AOP:Aspect Oriented Programming(面向切面编程、面向方面编程),其实就是面向特定方法编程。 使用场景: 比如你想统计业务中每个方法的执行耗时,那我们最…...

Optional类的使用 java8(附代码)
🍰 个人主页:_小白不加班__ 🍞文章有不合理的地方请各位大佬指正。 🍉文章不定期持续更新,如果我的文章对你有帮助➡️ 关注🙏🏻 点赞👍 收藏⭐️ 文章目录 一、什么是Optional?二、…...

企业利用AI智能名片S2B2C商城小程序参与社区团购的风险与机遇分析
摘要 在新零售浪潮的推动下,社区团购以其独特的商业模式迅速崛起,成为连接消费者与供应商的重要桥梁。企业纷纷探索如何有效利用这一新兴渠道,以扩大市场份额、提升品牌影响力。AI智能名片S2B2C商城小程序的引入,为企业参与社区团…...

全链路追踪 性能监控,GO 应用可观测全面升级
作者:古琦 01 介绍 随着 Kubernetes 和容器化技术的普及,Go 语言不仅在云原生基础组件领域广泛应用,也在各类业务场景中占据了重要地位。如今,越来越多的新兴业务选择 Golang 作为首选编程语言。得益于丰富的 RPC 框架ÿ…...
深入探索CSS3的Media Query:打造响应式网页设计的利器
在今天的互联网世界中,随着设备种类和屏幕尺寸的多样化,响应式网页设计(Responsive Web Design, RWD)已成为不可或缺的一部分。CSS3中的Media Query正是这一设计理念的实现利器,它允许开发者根据用户的设备特性和屏幕尺…...
DDD(Domain-Driven Design)领域驱动设计
在软件开发中,DDD(Domain-Driven Design,领域驱动设计)是一种方法论,它强调在开发过程中将业务领域的知识和规则作为核心。DDD的目标是通过理解和建模业务领域来创建更好的软件系统。本文将详细讲解DDD的基本概念、原则…...

基于k8s快速搭建docker镜像服务的demo
基于k8s快速搭建docker镜像服务的demo 一、环境准备 如标题,你需要环境中有和2个平台,并且服务器上也已经安装好docker服务 接下来我来构建一个docker镜像,然后使用harbork8s来快速部署服务demo 二、部署概述 使用docker构建镜像&#x…...

“论大数据处理架构及其应用”写作框架,软考高级论文,系统架构设计师论文
论文真题 大数据处理架构是专门用于处理和分析巨量复杂数据集的软件架构。它通常包括数据收集、存储、处理、分析和可视化等多个层面,旨在从海量、多样化的数据中提取有价值的信息。Lambda架构是大数据平台里最成熟、最稳定的架构,它是一种将批处理和流…...

tarojs项目启动篇
TaroJS 是一个开放式跨端开发解决方案,使用 React 语法规范来开发多端应用(包括小程序、H5、React Native 等)。它可以帮助开发者高效地构建出在不同端上运行一致的应用。以下是启动 TaroJS 项目(本来就有的旧项目)的步…...
Maven打包时将本地 jar 加入 classpath
在使用 maven 编译项目时,我们有时候会需要引入本地的 jar 包作为依赖(不部署到本地仓库),一般会使用 scope 为 system 的标签来引入,如下所示: <dependency><groupId>com.example</groupI…...

Python:操作 Excel 折叠
💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 Python 操作 Excel 系列 读取单元格数据按行写入设置行高和列宽自动调整行高和列宽水平…...

YSYX学习记录(八)
C语言,练习0: 先创建一个文件夹,我用的是物理机: 安装build-essential 练习1: 我注释掉了 #include <stdio.h> 出现下面错误 在你的文本编辑器中打开ex1文件,随机修改或删除一部分,之后…...

前端导出带有合并单元格的列表
// 导出async function exportExcel(fileName "共识调整.xlsx") {// 所有数据const exportData await getAllMainData();// 表头内容let fitstTitleList [];const secondTitleList [];allColumns.value.forEach(column > {if (!column.children) {fitstTitleL…...
vue3 字体颜色设置的多种方式
在Vue 3中设置字体颜色可以通过多种方式实现,这取决于你是想在组件内部直接设置,还是在CSS/SCSS/LESS等样式文件中定义。以下是几种常见的方法: 1. 内联样式 你可以直接在模板中使用style绑定来设置字体颜色。 <template><div :s…...

(转)什么是DockerCompose?它有什么作用?
一、什么是DockerCompose? DockerCompose可以基于Compose文件帮我们快速的部署分布式应用,而无需手动一个个创建和运行容器。 Compose文件是一个文本文件,通过指令定义集群中的每个容器如何运行。 DockerCompose就是把DockerFile转换成指令去运行。 …...

保姆级教程:在无网络无显卡的Windows电脑的vscode本地部署deepseek
文章目录 1 前言2 部署流程2.1 准备工作2.2 Ollama2.2.1 使用有网络的电脑下载Ollama2.2.2 安装Ollama(有网络的电脑)2.2.3 安装Ollama(无网络的电脑)2.2.4 安装验证2.2.5 修改大模型安装位置2.2.6 下载Deepseek模型 2.3 将deepse…...

Golang——9、反射和文件操作
反射和文件操作 1、反射1.1、reflect.TypeOf()获取任意值的类型对象1.2、reflect.ValueOf()1.3、结构体反射 2、文件操作2.1、os.Open()打开文件2.2、方式一:使用Read()读取文件2.3、方式二:bufio读取文件2.4、方式三:os.ReadFile读取2.5、写…...

MacOS下Homebrew国内镜像加速指南(2025最新国内镜像加速)
macos brew国内镜像加速方法 brew install 加速formula.jws.json下载慢加速 🍺 最新版brew安装慢到怀疑人生?别怕,教你轻松起飞! 最近Homebrew更新至最新版,每次执行 brew 命令时都会自动从官方地址 https://formulae.…...

通过MicroSip配置自己的freeswitch服务器进行调试记录
之前用docker安装的freeswitch的,启动是正常的, 但用下面的Microsip连接不上 主要原因有可能一下几个 1、通过下面命令可以看 [rootlocalhost default]# docker exec -it freeswitch fs_cli -x "sofia status profile internal"Name …...

保姆级【快数学会Android端“动画“】+ 实现补间动画和逐帧动画!!!
目录 补间动画 1.创建资源文件夹 2.设置文件夹类型 3.创建.xml文件 4.样式设计 5.动画设置 6.动画的实现 内容拓展 7.在原基础上继续添加.xml文件 8.xml代码编写 (1)rotate_anim (2)scale_anim (3)translate_anim 9.MainActivity.java代码汇总 10.效果展示 逐帧…...