突破编程_C++_STL教程( stack 的实战应用)
1 std::stack 应用于自定义数据结构
通常,std::stack 用于存储基本数据类型,如 int、float、char 等。然而,std::stack 同样可以存储自定义的数据结构,只要这些数据结构满足一定的要求。
(1)存储自定义数据结构的要求
要使自定义数据结构能够存储在 std::stack 中,该数据结构必须满足以下条件:
- 可复制性:自定义数据结构必须能够被复制。这意味着它必须有一个有效的复制构造函数和一个赋值运算符。当元素被压入栈或从栈中弹出时,会涉及到复制操作。
- 析构函数:自定义数据结构应该有一个合适的析构函数,以确保在元素从栈中删除时能够正确地释放资源。
(2)使用 std::stack 存储自定义数据结构
下面是一个简单的例子,展示了如何使用 std::stack 存储自定义的数据结构:
#include <iostream>
#include <stack> // 自定义数据结构
struct MyData { int id; std::string name; // 构造函数 MyData(int id, const std::string& name) : id(id), name(name) {} // 输出数据结构的内容 void print() const { std::cout << "ID: " << id << ", Name: " << name << std::endl; }
}; int main()
{ // 创建一个存储 MyData 类型元素的栈 std::stack<MyData> dataStack; // 创建一些 MyData 对象并将其压入栈中 dataStack.push(MyData(1, "Alice")); dataStack.push(MyData(2, "Bob")); dataStack.push(MyData(3, "Charlie")); // 遍历栈并输出每个元素的内容 while (!dataStack.empty()) { MyData topData = dataStack.top(); // 获取栈顶元素但不移除它 topData.print(); // 输出栈顶元素的内容 dataStack.pop(); // 移除栈顶元素 } return 0;
}
上面代码的输出为:
ID: 3, Name: Charlie
ID: 2, Name: Bob
ID: 1, Name: Alice
这个例子定义了一个名为 MyData 的自定义数据结构,它包含两个成员变量:id 和 name。然后,我们创建了一个 std::stack<MyData> 类型的栈,用于存储 MyData 对象。通过调用 push 方法将 MyData 对象压入栈中,并通过循环和 top、pop 方法遍历并输出栈中每个元素的内容。
(3)注意事项
- 内存管理:当自定义数据结构包含动态分配的内存(如指针、动态数组等)时,需要确保在复制和析构过程中正确地管理这些内存。
- 性能考虑:对于大型或复杂的自定义数据结构,频繁地复制元素可能会对性能产生显著影响。在这种情况下,可以考虑使用指针或智能指针(如 std::shared_ptr 或 std::unique_ptr)来存储数据结构的引用,而不是直接存储数据结构本身。
- 异常安全性:在自定义数据结构的复制构造函数和赋值运算符中,应确保操作是异常安全的,以避免在发生异常时导致资源泄漏或其他问题。
2 std::stack 的主要应用场景
下面是 std::stack 的一些主要应用场景:
(1)函数调用与递归:
在函数调用和递归实现中,局部变量和参数通常被存储在栈上。std::stack 可以模拟这种行为,帮助理解函数调用的过程。
(2)表达式求值:
在算术表达式或逻辑表达式的求值过程中,通常使用栈来存储操作数和操作符。例如,实现一个简单的四则运算器时,可以利用栈来处理运算符和操作数的优先级。
(3)深度优先搜索(DFS):
在图或树的深度优先搜索中,栈可以用来保存待访问的节点。每次从栈中弹出一个节点,并访问其相邻节点,然后将相邻节点压入栈中,直到栈为空或达到搜索目标。
(4)括号匹配:
在解析包含括号的字符串(如数学表达式、编程语言中的代码块等)时,栈可以用来跟踪未闭合的括号,以确保它们的正确匹配。
(5)撤销/重做操作:
在一些需要撤销或重做功能的应用中(如文本编辑器、绘图工具等),可以使用栈来存储历史操作。撤销操作就是弹出栈顶元素,重做操作则是将之前弹出的元素再次压入栈中。
(6)解析与编译器设计:
在编译器设计中,栈可以用来跟踪语法分析过程中的符号和状态。
(7)UI导航历史:
在一些图形用户界面(GUI)应用中,栈可以用来存储用户的导航历史,以便用户可以向前或向后导航。
(8)游戏开发:
在某些游戏中,栈可以用来管理游戏状态、事件或动作序列。
(9)算法实现:
一些算法,如汉诺塔问题、中序遍历的非递归实现等,都可以使用栈来辅助实现。
2.1 std::stack 应用于函数调用与递归
下面是一个简单的示例,演示了如何使用 std::stack 来模拟函数调用和递归的过程。在这个示例中,我们将创建一个简单的函数调用栈,并模拟执行一些基本的函数调用和返回操作。
#include <iostream>
#include <stack>
#include <string> // 模拟的函数调用记录结构
struct FunctionCall { std::string functionName; // 函数名 int returnAddress; // 返回地址(在栈中的位置) // 构造函数 FunctionCall(const std::string& name, int addr) : functionName(name), returnAddress(addr) {}
}; int main()
{ std::stack<FunctionCall> callStack; // 函数调用栈 int currentPosition = 0; // 当前执行位置 // 模拟函数A的调用 std::cout << "Entering function A" << std::endl; callStack.push(FunctionCall("A", currentPosition + 1)); // 压入函数调用记录 currentPosition++; // 移动到下一个执行位置 // 假设函数A调用了函数B std::cout << "Calling function B from A" << std::endl; callStack.push(FunctionCall("B", currentPosition + 1)); // 压入函数B的调用记录 currentPosition++; // 移动到下一个执行位置 // 执行函数B的代码(这里只是模拟) std::cout << "Executing function B" << std::endl; currentPosition++; // 假设函数B执行了一些操作,移动到下一个执行位置 // 函数B执行完毕,准备返回 std::cout << "Returning from function B" << std::endl; FunctionCall topCall = callStack.top(); // 获取栈顶函数调用记录 std::cout << "Returning to " << topCall.functionName << std::endl; callStack.pop(); // 弹出栈顶记录,表示返回 currentPosition = topCall.returnAddress; // 设置返回地址 // 继续执行函数A的剩余代码 std::cout << "Continuing execution in function A" << std::endl; currentPosition++; // 移动到下一个执行位置(如果有的话) // 函数A执行完毕,准备返回 std::cout << "Returning from function A" << std::endl; if (!callStack.empty()) { topCall = callStack.top(); // 如果有更多函数调用,则获取栈顶记录 std::cout << "Returning to " << topCall.functionName << std::endl; callStack.pop(); // 弹出栈顶记录,表示返回到上一层调用 currentPosition = topCall.returnAddress; // 设置新的返回地址 } else { std::cout << "Program execution finished" << std::endl; } return 0;
}
上面代码的输出为:
Entering function A
Calling function B from A
Executing function B
Returning from function B
Returning to B
Continuing execution in function A
Returning from function A
Returning to A
这个示例定义了一个 FunctionCall 结构体来记录每次函数调用的信息,包括函数名和返回地址(在调用栈中的位置)。示例中使用 std::stack<FunctionCall> 来模拟函数调用栈的行为。每次函数调用时,将一个新的 FunctionCall 对象压入栈中,并记录当前的执行位置。当函数返回时,从栈顶弹出记录,并根据记录的返回地址继续执行。
注意:这个示例是为了演示目的而简化的。在实际的程序中,函数调用和返回通常涉及到更多的复杂性和细节,比如局部变量、参数传递、作用域等。此外,这个示例也没有展示如何处理函数调用中的参数和返回值。在实际的编译器或解释器实现中,函数调用栈会更加复杂,并且会紧密地与程序的执行流程相结合。
2.2 std::stack 应用于表达式求值
下面是一个使用 std::stack 来实现简单四则运算表达式求值的示例。这个示例将实现一个基本的计算器,能够处理加、减、乘、除四种运算。为了实现这个计算器,需要使用两个栈:一个用于存储操作数,另一个用于存储操作符。
#include <iostream>
#include <stack>
#include <cctype>
#include <string>
#include <cmath> // 定义运算符的优先级
int getPrecedence(char op) { if (op == '+' || op == '-') return 1; if (op == '*' || op == '/') return 2; return 0;
} // 执行运算
double applyOp(double a, double b, char op) { switch(op) { case '+': return a + b; case '-': return a - b; case '*': return a * b; case '/': if (b != 0.0) return a / b; else throw std::invalid_argument("Division by zero"); default: throw std::invalid_argument("Unknown operator"); }
} // 计算表达式的值
double evaluateExpression(const std::string &expr) { std::stack<double> values; // 操作数栈 std::stack<char> ops; // 操作符栈 for (size_t i = 0; i < expr.size(); ++i) { char ch = expr[i]; // 如果是空格,则跳过 if (std::isspace(ch)) continue; // 如果是操作数,则压入操作数栈 if (std::isdigit(ch)) { double val = 0; // 处理多位数 while (i < expr.size() && std::isdigit(expr[i])) { val = val * 10 + (expr[i] - '0'); ++i; } --i; // 因为for循环还会递增i,所以这里要减回去 values.push(val); } // 如果是左括号,则压入操作符栈 else if (ch == '(') { ops.push(ch); } // 如果是右括号,则执行栈顶操作符直到遇到左括号 else if (ch == ')') { while (!ops.empty() && ops.top() != '(') { double val2 = values.top(); values.pop(); double val1 = values.top(); values.pop(); char op = ops.top(); ops.pop(); values.push(applyOp(val1, val2, op)); } if (!ops.empty()) ops.pop(); // 弹出左括号 } // 如果是操作符,则根据优先级进行处理 else if (ch == '+' || ch == '-' || ch == '*' || ch == '/') { while (!ops.empty() && getPrecedence(ops.top()) >= getPrecedence(ch)) { double val2 = values.top(); values.pop(); double val1 = values.top(); values.pop(); char op = ops.top(); ops.pop(); values.push(applyOp(val1, val2, op)); } ops.push(ch); } // 如果是非法字符,则抛出异常 else { throw std::invalid_argument("Invalid character in expression"); } } // 应用栈中剩余的操作符 while (!ops.empty()) { double val2 = values.top(); values.pop(); double val1 = values.top(); values.pop(); char op = ops.top(); ops.pop(); values.push(applyOp(val1, val2, op)); } // 表达式的结果应该在操作数栈的顶部 return values.top();
} int main()
{ std::string expression = "(1+2)*(2+6)/2-1";try { double result = evaluateExpression(expression); std::cout << "Result: " << result << std::endl; } catch (const std::exception &e) { std::cerr << "Error: " << e.what() << std::endl; } return 0;
}
上面代码的输出为:
Result: 11
程序中,首先定义了一个 getPrecedence 函数来返回运算符的优先级,然后定义了一个 applyOp 函数来执行实际的运算。在 evaluateExpression 函数中,遍历输入的表达式,并根据字符类型执行相应的操作。
当遇到数字时,将其解析为一个 double 类型的数值并压入操作数栈。当遇到左括号时,将其压入操作符栈。当遇到右括号时,弹出操作符栈顶的操作符并执行相应的运算,直到遇到左括号为止。当遇到操作符时,则根据操作符的优先级来决定是否先执行栈顶的操作符。
最后,在遍历完整个表达式后,将执行操作符栈中剩余的所有操作符,并将最终的结果存储在操作数栈的顶部。
2.3 std::stack 应用于深度优先搜索(DFS)
栈在深度优先搜索(DFS)中是一个非常有用的数据结构。以下是一个使用 std::stack 来实现深度优先搜索的简单示例。这个示例将在一个无向图中进行深度优先搜索。
#include <iostream>
#include <vector>
#include <stack>
#include <unordered_set> // 使用邻接列表表示图
class Graph {
public: Graph(int vertices) : adjList(vertices) {} // 添加边 void addEdge(int src, int dest) { adjList[src].push_back(dest); adjList[dest].push_back(src); // 对于无向图,需要添加反向边 } // 深度优先搜索 void DFS(int start) { std::stack<int> s; std::unordered_set<int> visited; s.push(start); visited.insert(start); while (!s.empty()) { int vertex = s.top(); s.pop(); std::cout << vertex << " "; // 遍历与当前节点相邻且未被访问过的节点 for (int neighbor : adjList[vertex]) { if (visited.find(neighbor) == visited.end()) { s.push(neighbor); visited.insert(neighbor); } } } } private: std::vector<std::vector<int>> adjList; // 邻接列表
}; int main()
{ Graph g(5); // 创建一个包含5个顶点的图 // 添加边 g.addEdge(0, 1); g.addEdge(0, 4); g.addEdge(1, 2); g.addEdge(1, 3); g.addEdge(1, 4); g.addEdge(2, 3); g.addEdge(3, 4); std::cout << "Depth First Traversal (starting from vertex 0): "; g.DFS(0); std::cout << std::endl; return 0;
}
上面代码的输出为:
Depth First Traversal (starting from vertex 0): 0 4 3 2 1
这个示例首先定义了一个 Graph 类,它包含一个邻接列表 adjList 来存储图的信息。addEdge 方法用于向图中添加边。
DFS 方法是深度优先搜索的实现。它使用一个栈 s 来保存待访问的节点,以及一个 visited 哈希集合来跟踪已经访问过的节点。搜索从指定的起始节点 start 开始。
在 DFS 方法中,首先将起始节点压入栈中,并标记为已访问。然后,在栈不为空的情况下,不断地从栈顶取出节点,访问它,并将其未访问过的相邻节点压入栈中。这个过程一直持续到栈为空,即所有可达的节点都已被访问。
在 main 函数中,创建了一个包含5个顶点的图,并添加了一些边。然后,从顶点0开始进行深度优先遍历,并输出遍历结果。
运行这个程序,可以看到从顶点0开始的深度优先遍历结果。由于图的结构和遍历顺序可能因实现细节和编译器行为的不同而略有差异,因此输出可能不是唯一的。
3 实现一个简单的 std::stack 容器
下面是一个简单的 MyStack 类的实现,它使用 std::vector 作为底层容器。
#include <iostream>
#include <vector> template <typename T>
class MyStack {
public:// 构造函数 MyStack() : elements() {}// 判断栈是否为空 bool empty() const {return elements.empty();}// 返回栈顶元素(不删除) T& top() {if (empty()) {throw std::out_of_range("Stack is empty");}return elements.back();}const T& top() const {if (empty()) {throw std::out_of_range("Stack is empty");}return elements.back();}// 将元素压入栈顶 void push(const T& value) {elements.push_back(value);}// 弹出栈顶元素 void pop() {if (empty()) {throw std::out_of_range("Stack is empty");}elements.pop_back();}// 返回栈的大小 size_t size() const {return elements.size();}private:std::vector<T> elements; // 底层容器
};int main()
{MyStack<int> myStack;// 压入几个元素 myStack.push(1);myStack.push(2);myStack.push(3);// 输出栈的大小 std::cout << "Size of stack: " << myStack.size() << std::endl;// 弹出栈顶元素并输出 myStack.pop();std::cout << "Top element after pop: " << myStack.top() << std::endl;// 判断栈是否为空 if (myStack.empty()) {std::cout << "Stack is empty." << std::endl;}else {std::cout << "Stack is not empty." << std::endl;}return 0;
}
上面代码的输出为:
Size of stack: 3
Top element after pop: 2
Stack is not empty.
这个简单的 MyStack 类提供了基本的栈操作,包括 push(压栈)、pop(弹栈)、top(查看栈顶元素)、empty(判断栈是否为空)和 size(获取栈的大小)。它使用 std::vector 作为底层容器来存储元素,并利用 vector 的 push_back 和 pop_back 方法来实现栈的基本操作。
相关文章:
突破编程_C++_STL教程( stack 的实战应用)
1 std::stack 应用于自定义数据结构 通常,std::stack 用于存储基本数据类型,如 int、float、char 等。然而,std::stack 同样可以存储自定义的数据结构,只要这些数据结构满足一定的要求。 (1)存储自定义数…...
Spring Data访问Elasticsearch----其他Elasticsearch操作支持
Spring Data访问Elasticsearch----其他Elasticsearch操作支持 一、索引设置二、索引映射三、Filter Builder四、为大结果集使用滚动Scroll五、排序选项六、运行时字段6.1 索引映射中的运行时字段定义6.2 在查询上设置的运行时字段定义 七、Point In Time (PIT) API八、搜索模板…...

代码随想录算法训练营第60天 | 84.柱状图中最大的矩形
单调栈章节理论基础: https://leetcode.cn/problems/daily-temperatures/ 84.柱状图中最大的矩形 题目链接:https://leetcode.cn/problems/largest-rectangle-in-histogram/description/ 思路: 本题双指针的写法整体思路和42. 接雨水是一…...
【讲解Node.js常用的命令】进阶版
Node.js常用命令 Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行时环境,它使得可以在服务器端运行 JavaScript 代码。Node.js 采用了事件驱动、非阻塞 I/O 模型,非常适用于构建高效的网络应用程序。以下是一些Node.js开发中常用的命令࿱…...

软考81-上午题-【面向对象技术3-设计模式】-行为型设计模式01
一、行为型设计模式一览 二、责任链模式 2-1、意图 使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。 1-2、结构 1-3、代码实现 1-4、适…...

【Linux进阶之路】HTTPS = HTTP + S
文章目录 一、概念铺垫1.Session ID2.明文与密文3.公钥与私钥4.HTTPS结构 二、加密方式1. 对称加密2.非对称加密3.CA证书 总结尾序 一、概念铺垫 1.Session ID Session ID,即会话ID,用于标识客户端与服务端的唯一特定会话的标识符。会话,即客…...

51-31 CVPR’24 | VastGaussian,3D高斯大型场景重建
2024 年 2 月,清华大学、华为和中科院联合发布的 VastGaussian 模型,实现了基于 3D Gaussian Splatting 进行大型场景高保真重建和实时渲染。 Abstract 现有基于NeRF大型场景重建方法,往往在视觉质量和渲染速度方面存在局限性。虽然最近 3D…...

GPT-4引领AI新纪元,Claude3、Gemini、Sora能否跟上步伐?
【最新增加Claude3、Gemini、Sora、GPTs讲解及AI领域中的集中大模型的最新技术】 2023年随着OpenAI开发者大会的召开,最重磅更新当属GPTs,多模态API,未来自定义专属的GPT。微软创始人比尔盖茨称ChatGPT的出现有着重大历史意义,不亚…...

图书馆RFID(射频识别)数据模型压缩/解压缩算法实现小工具
1. 前言 最近闲来无聊,看了一下《图书馆射频识别数据模型第1部分:数据元素的设置及应用规则》以及《图书馆射频识别数据模型第2部分:基于ISO/IEC 15962的数据元素编码方案》,决定根据上面的编码方法实现一下该算法,于…...

【Java Web基础】一些网页设计基础(三)
文章目录 1. 导航栏样式进一步调整2. 入驻企业信息展示栏2.1 Title设置2.2 具体信息添加 3. 轮播图4. 注册登录按钮及其他信息5. 一些五颜六色的、丰富视觉效果的中间件…… 1. 导航栏样式进一步调整 这种导航栏,选中的时候字体变蓝色,可能还是不够美观&…...

2 使用GPU理解并行计算
2.1 简介 本章旨在对并行程序设计的基本概念及其与GPU技术的联系做一个宽泛的介绍。本章主要面向具有串行程序设计经验,但对并行处理概念缺乏了解的读者。我们将用GPU的基本知识来讲解并行程序设计的基本概念。 2.2 传统的串行代码 绝大多数程序员是在串行程序占据…...
Android什么情况下会出现内存泄漏以及怎么解决?
1.什么情况下会出现内存泄漏? (1)单例模式下为什么会造成内存泄漏? 因为单例的生命周期和应用的生命周期是一致的,如果往单例模式里面传了一个生命周期比较短的对象,比如Activity,就会导致Activity不能释放,导致内存泄漏。我们可以传context.getAppliactionContext,而…...

kafka集群介绍及搭建
介绍 kafka是一个高性能、低延迟、分布式的消息传递系统,特点在于实时处理数据。集群由多个成员节点broker组成,每个节点都可以独立处理消息传递和存储任务。 路由策略 发布消息由key、value组成,真正的消息是value,key是标识路…...

2024/03/19(网络编程·day5)
一、思维导图 二、selec函数实现TCP并发服务器 #include<myhead.h>#define SER_PORT 8888 //服务器端口号 #define SER_IP "192.168.117.116" //服务器IP int main(int argc, const char *argv[]) {//1、创建一个套接字int sfd -1;sfd socket(AF_INET,SOC…...
LeetCode解法汇总1969. 数组元素的最小非零乘积
目录链接: 力扣编程题-解法汇总_分享记录-CSDN博客 GitHub同步刷题项目: https://github.com/September26/java-algorithms 原题链接:. - 力扣(LeetCode) 描述: 给你一个正整数 p 。你有一个下标从 1 开…...

学习vue3第九节(新加指令 v-pre/v-once/v-memo/v-cloak )
1、v-pre 作用:防止编译器解析某个特定的元素及其内容,即v-pre 会跳过当前元素以及其子元素的vue语法解析,并将其保持原样输出; 用于:vue 中一些没有指令和插值表达式的节点的元素,使用 v-pre 可以提高 Vu…...

二开飞机机器人群发,实现自动给多个频道发送消息
频道1 频道2 二开代码部分: const CChatIdListprocess.env.CHANNEL_CHAT_ID_LIST; var channelChatIdArray CChatIdList.split(,);channelChatIdArray.forEach(function(item) {console.log(item); // 这里可以替换为您需要对数组中每个值进行的操作bot.sendM…...

AI如何支持慈善组织
为各种有意义的事业提供支持,无论是努力寻找治愈疾病的方法、研发使生活更轻松的技术,还是为有需要的人提供服务,都是无比崇高的使命。提供捐款或是投入时间支持的捐助者和志愿者往往对他们选择支持的事业的目标、服务和资源分配存有诸多疑虑…...

Git如何清除账户凭证
场景:一般发生在Git用户变更的情况 1.git base 操作 Git会使用凭证助手 credential.helper来储存账户凭证,通过以下命令移除: git config --system --unset credential.helper 除了system系统级外,还有 global、local范围。 查…...

【YUNBEE云贝-PostgreSQL】FDW应用
注: 本文为云贝教育 刘峰 原创,请尊重知识产权,转发请注明出处,不接受任何抄袭、演绎和未经注明出处的转载。 前言 Wrapper(FDW)是一项关键特性,它赋予数据库用户直接通过SQL语句访问存储于外部数据源的能…...
Python爬虫实战:研究MechanicalSoup库相关技术
一、MechanicalSoup 库概述 1.1 库简介 MechanicalSoup 是一个 Python 库,专为自动化交互网站而设计。它结合了 requests 的 HTTP 请求能力和 BeautifulSoup 的 HTML 解析能力,提供了直观的 API,让我们可以像人类用户一样浏览网页、填写表单和提交请求。 1.2 主要功能特点…...

华为云AI开发平台ModelArts
华为云ModelArts:重塑AI开发流程的“智能引擎”与“创新加速器”! 在人工智能浪潮席卷全球的2025年,企业拥抱AI的意愿空前高涨,但技术门槛高、流程复杂、资源投入巨大的现实,却让许多创新构想止步于实验室。数据科学家…...
云原生核心技术 (7/12): K8s 核心概念白话解读(上):Pod 和 Deployment 究竟是什么?
大家好,欢迎来到《云原生核心技术》系列的第七篇! 在上一篇,我们成功地使用 Minikube 或 kind 在自己的电脑上搭建起了一个迷你但功能完备的 Kubernetes 集群。现在,我们就像一个拥有了一块崭新数字土地的农场主,是时…...

【JavaEE】-- HTTP
1. HTTP是什么? HTTP(全称为"超文本传输协议")是一种应用非常广泛的应用层协议,HTTP是基于TCP协议的一种应用层协议。 应用层协议:是计算机网络协议栈中最高层的协议,它定义了运行在不同主机上…...

盘古信息PCB行业解决方案:以全域场景重构,激活智造新未来
一、破局:PCB行业的时代之问 在数字经济蓬勃发展的浪潮中,PCB(印制电路板)作为 “电子产品之母”,其重要性愈发凸显。随着 5G、人工智能等新兴技术的加速渗透,PCB行业面临着前所未有的挑战与机遇。产品迭代…...

python/java环境配置
环境变量放一起 python: 1.首先下载Python Python下载地址:Download Python | Python.org downloads ---windows -- 64 2.安装Python 下面两个,然后自定义,全选 可以把前4个选上 3.环境配置 1)搜高级系统设置 2…...

YSYX学习记录(八)
C语言,练习0: 先创建一个文件夹,我用的是物理机: 安装build-essential 练习1: 我注释掉了 #include <stdio.h> 出现下面错误 在你的文本编辑器中打开ex1文件,随机修改或删除一部分,之后…...
vue3 字体颜色设置的多种方式
在Vue 3中设置字体颜色可以通过多种方式实现,这取决于你是想在组件内部直接设置,还是在CSS/SCSS/LESS等样式文件中定义。以下是几种常见的方法: 1. 内联样式 你可以直接在模板中使用style绑定来设置字体颜色。 <template><div :s…...

使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台
🎯 使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台 📌 项目背景 随着大语言模型(LLM)的广泛应用,开发者常面临多个挑战: 各大模型(OpenAI、Claude、Gemini、Ollama)接口风格不统一;缺乏一个统一平台进行模型调用与测试;本地模型 Ollama 的集成与前…...
Mobile ALOHA全身模仿学习
一、题目 Mobile ALOHA:通过低成本全身远程操作学习双手移动操作 传统模仿学习(Imitation Learning)缺点:聚焦与桌面操作,缺乏通用任务所需的移动性和灵活性 本论文优点:(1)在ALOHA…...