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

Let’s Make C++ Great Again——set与vector

文章目录

  • set
    • 常用的set方法:
    • set实现去重的例子:
    • 自定义比较函数的例子,按照字符串长度从小到大排序:
    • 使用set容器求两个集合的交集的例子:
  • vector
    • 创建vector对象
    • 插入和删除元素
    • 获取vector的大小和容量
    • 检查vector是否为空
    • 访问vector的首尾元素
    • 修改vector的大小
    • 清空vector
    • 交换vector
    • vector的迭代器
    • vector的性能
    • 自定义vector元素类型
    • 使用emplace_back()方法
    • 使用reserve()方法
    • 使用std::move()函数
    • vector在算法模拟题中
      • 存储动态数组
      • 模拟栈操作
      • 实现动态规划

set

在C++中,set是一个标准的关联容器,它使用红黑树数据结构来存储元素,并保证元素按照一定的顺序排列。set中的元素是唯一的,不能重复。

set容器提供了一系列方法,包括插入元素、删除元素、查找元素、遍历元素等,可以方便地实现对元素的操作。

常用的set方法:

  • insert(val):将元素val插入到set中。
  • erase(val):从set中删除值为val的元素。
  • find(val):在set中查找值为val的元素,并返回指向该元素的迭代器。
  • size():返回set中元素的个数。
  • begin():返回指向set中第一个元素的迭代器。
  • end():返回指向set中最后一个元素之后位置的迭代器,通常用于遍历set中的元素。
  • empty():判断set是否为空,如果为空则返回true,否则返回false。
  • clear():清空set中的所有元素。
  • count(val):返回set中值为val的元素的个数,因为set中元素不重复,所以返回值只能是0或1。
  • lower_bound(val):返回一个指向第一个不小于val的元素的迭代器。
  • upper_bound(val):返回一个指向第一个大于val的元素的迭代器。
  • equal_range(val):返回一个迭代器对,其中第一个迭代器指向set中第一个等于val的元素,第二个迭代器指向set中第一个大于val的元素。

set实现去重的例子:

#include <iostream>
#include <set>using namespace std;int main() {set<int> myset;myset.insert(10);myset.insert(20);myset.insert(30);myset.insert(20);myset.insert(40);cout << "Set contains " << myset.size() << " elements: ";for (auto it = myset.begin(); it != myset.end(); it++) {cout << *it << " ";}cout << endl;return 0;
}
Set contains 4 elements: 10 20 30 40

set还支持自定义比较函数,可以根据不同的需求来定义元素之间的比较方式,例如按照字符串长度进行排序等。

自定义比较函数的例子,按照字符串长度从小到大排序:

#include <iostream>
#include <set>
#include <string>using namespace std;struct cmp {bool operator() (const string& a, const string& b) const {return a.length() < b.length();}
};int main() {set<string, cmp> myset;myset.insert("apple");myset.insert("banana");myset.insert("pear");myset.insert("orange");cout << "Set contains " << myset.size() << " elements: ";for (auto it = myset.begin(); it != myset.end(); it++) {cout << *it << " ";}cout << endl;return 0;
}
Set contains 4 elements: pear apple banana orange

可以看到,程序根据字符串长度从小到大排序了元素。

总之,set是一个非常有用的容器,可以方便地实现对元素的操作,并且保证元素无重复。在实际的编程中,我们可以根据不同的需求来灵活地使用set容器。

在算法模拟题中,set容器通常用于实现集合的概念,即存储一些元素,同时保证元素无重复。在模拟一些实际场景时,例如计算两个集合的交集、并集等操作时,set容器可以很方便地实现这些操作。

使用set容器求两个集合的交集的例子:

#include <iostream>
#include <set>using namespace std;int main() {set<int> A = {1, 2, 3, 4, 5};set<int> B = {2, 4, 6, 8};set<int> C;for (auto it = A.begin(); it != A.end(); it++) {if (B.count(*it)) {C.insert(*it);}}cout << "A: ";for (auto it = A.begin(); it != A.end(); it++) {cout << *it << " ";}cout << endl;cout << "B: ";for (auto it = B.begin(); it != B.end(); it++) {cout << *it << " ";}cout << endl;cout << "C: ";for (auto it = C.begin(); it != C.end(); it++) {cout << *it << " ";}cout << endl;return 0;
}
A: 1 2 3 4 5 
B: 2 4 6 8 
C: 2 4

可以看到,程序使用set容器实现了对两个集合求交集的操作。

除了求交集、并集等操作外,set容器还可以用于对元素进行排序、去重等操作。在进行算法模拟题时,我们可以根据实际需要灵活地使用set容器,以实现对元素的操作和处理。

vector

vector是C++标准库中的一个容器类,用于存储元素的动态数组,可以实现自动扩容、快速随机访问等功能。下面介绍一些vector的基本用法。

创建vector对象

可以通过以下方式来创建一个vector对象:

#include <vector>using namespace std;vector<int> v;  // 创建一个空的vector对象

可以在创建时指定初始大小和初始值:

vector<int> v1(10);         // 创建一个大小为10的vector对象,每个元素的值为0
vector<int> v2(10, 1);      // 创建一个大小为10的vector对象,每个元素的值为1
vector<int> v3{1, 2, 3};    // 创建一个包含3个元素的vector对象,值分别为1、2、3
vector<int> v4 = {4, 5, 6}; // 与v3等价

插入和删除元素

可以使用push_back()方法在vector的末尾插入一个元素:

vector<int> v;
v.push_back(1);
v.push_back(2);
v.push_back(3);

也可以使用insert()方法在指定位置插入一个元素:

vector<int> v{1, 2, 3};
v.insert(v.begin() + 1, 4);  // 在下标为1的位置插入元素4

可以使用pop_back()方法删除vector末尾的一个元素:

vector<int> v{1, 2, 3};
v.pop_back();

也可以使用erase()方法删除指定位置的一个或多个元素:

vector<int> v{1, 2, 3};
v.erase(v.begin() + 1);     // 删除下标为1的元素
v.erase(v.begin() + 1, v.end() - 1);  // 删除下标为1到末尾前一个位置的元素
访问元素

可以使用下标运算符[]或at()方法来访问vector中的元素,下标从0开始:

vector<int> v{1, 2, 3};
int x = v[0];      // x的值为1
int y = v.at(1);   // y的值为2

也可以使用迭代器来访问vector中的元素:

vector<int> v{1, 2, 3};
for (auto it = v.begin(); it != v.end(); it++) {cout << *it << " ";  // 输出1 2 3
}

获取vector的大小和容量

可以使用size()方法获取vector中元素的个数:

vector<int> v{1, 2, 3};
int n = v.size();  // n的值为3

可以使用capacity()方法获取vector中能够容纳的元素个数:

vector<int> v{1, 2, 3};
int m = v.capacity();  // m的值为3

需要注意的是,vector的实际大小和容量可能不一致,因为vector会动态调整大小和容量以适应元素的增减。

检查vector是否为空

可以使用empty()方法检查vector是否为空:

vector<int> v{1, 2, 3};
if (v.empty()) {cout << "vector is empty" << endl;
} else {cout << "vector is not empty" << endl;
}

访问vector的首尾元素

可以使用front()方法和back()方法分别访问vector的第一个和最后一个元素:

vector<int> v{1, 2, 3};
int x = v.front();  // x的值为1
int y = v.back();   // y的值为3

修改vector的大小

可以使用resize()方法修改vector的大小,如果新的大小比原来的大小小,则会删除多余的元素,如果新的大小比原来的大小大,则会添加默认值的元素:

vector<int> v{1, 2, 3};
v.resize(5);  // v的大小变为5,多余的元素的值为0
v.resize(2);  // v的大小变为2,多余的元素被删除

清空vector

可以使用clear()方法清空vector中的所有元素:

vector<int> v{1, 2, 3};
v.clear();  // v中的元素被清空

交换vector

可以使用swap()方法交换两个vector对象:

vector<int> v1{1, 2, 3};
vector<int> v2{4, 5, 6};
v1.swap(v2);  // v1和v2中的元素被交换

需要注意的是,使用swap()方法可以在不需要额外的内存空间的情况下交换两个vector对象,因此可以有效避免内存泄漏的问题。

vector的迭代器

vector的迭代器可以用来遍历vector中的元素,可以使用begin()方法和end()方法分别获取指向第一个元素和最后一个元素之后位置的迭代器:

vector<int> v{1, 2, 3};
for (auto it = v.begin(); it != v.end(); it++) {cout << *it << " ";  // 输出1 2 3
}

需要注意的是,vector的迭代器不是指针类型,但是可以通过解引用*运算符来访问迭代器指向的元素。

vector的性能

vector的性能在大多数情况下都非常好,可以达到常数时间复杂度。但是,由于vector的动态扩容需要重新分配内存并复制元素,因此在频繁增加元素的情况下,可能会导致性能下降。此外,vector的内存分配可能不是连续的,这也可能会影响性能。

自定义vector元素类型

vector可以存储任何类型的元素,包括内置类型、自定义类型、指针等。如果要存储自定义类型的元素,需要定义一个适当的构造函数和析构函数。

例如,假设我们有一个自定义类型Person,其中包含姓名和年龄两个字段:

#include <string>using namespace std;class Person {
public:Person(const string& name, int age) : name_(name), age_(age) {}string name() const { return name_; }int age() const { return age_; }
private:string name_;int age_;
};

然后可以定义一个vector来存储Person类型的元素:

vector<Person> v;
v.push_back(Person("Alice", 20));
v.push_back(Person("Bob", 30));

需要注意的是,如果Person类中包含指针等动态分配内存的成员变量,需要自定义拷贝构造函数和赋值运算符,以确保正确地复制和释放内存。

使用emplace_back()方法

emplace_back()方法可以在vector的末尾直接构造新的元素,而不是先创建一个临时对象再复制到vector中,从而可以避免不必要的拷贝操作,提高性能。

例如,假设我们有一个vector来存储Person类型的元素,可以使用emplace_back()方法来添加新的元素:

vector<Person> v;
v.emplace_back("Alice", 20);
v.emplace_back("Bob", 30);

需要注意的是,emplace_back()方法的参数应该与元素类型的构造函数所需的参数匹配。

使用reserve()方法

reserve()方法可以预先分配一定数量的内存空间,以避免在添加大量元素时反复进行动态内存分配和复制操作,从而提高性能。

例如,假设我们需要存储一百万个int类型的元素,可以使用reserve()方法预先分配内存空间:

vector<int> v;
v.reserve(1000000);
for (int i = 0; i < 1000000; i++) {v.push_back(i);
}

需要注意的是,reserve()方法只会预先分配内存空间,而不会改变vector的大小,因此需要在添加元素之前使用reserve()方法。

使用std::move()函数

std::move()函数可以将一个对象的所有权转移给另一个对象,从而避免不必要的拷贝操作,提高性能。

例如,假设我们有一个vector,需要将其中的元素移动到另一个vector中:

vector<Person> v1;
vector<Person> v2;
// 添加元素到v1中
v2.reserve(v1.size());
for (auto& p : v1) {v2.push_back(std::move(p));
}
v1.clear();  // 清空v1

需要注意的是,使用std::move()函数需要确保被移动的对象不再使用,否则可能会出现未定义的行为。

总之,vector是一个非常实用的容器类,在处理动态数组的问题时非常方便。需要注意的是,在使用vector时需要了解其高级特性,并结合具体的应用场景进行优化,以提高性能和减少内存开销。

vector在算法模拟题中

在算法模拟题中,vector是一个非常实用的容器类,可以方便地处理动态数组的问题。以下是一些常见的算法模拟题中使用vector的场景:

存储动态数组

在模拟数组操作时,可以使用vector来存储动态数组。例如,假设需要实现一个队列,可以使用vector来存储队列中的元素:

vector<int> q;  // 定义一个vector来存储队列中的元素
q.push_back(1);  // 添加元素到队列末尾
q.push_back(2);
q.push_back(3);
int x = q.front();  // 获取队列头部元素
q.erase(q.begin());  // 删除队列头部元素

模拟栈操作

在模拟栈操作时,也可以使用vector来存储栈中的元素。例如,假设需要实现一个栈,可以使用vector来存储栈中的元素:

vector<int> s;  // 定义一个vector来存储栈中的元素
s.push_back(1);  // 添加元素到栈顶
s.push_back(2);
s.push_back(3);
int x = s.back();  // 获取栈顶元素
s.pop_back();  // 删除栈顶元素

实现动态规划

在动态规划问题中,通常需要定义一个二维数组来存储状态。可以使用vector来实现这个二维数组,并使用resize()方法来动态调整数组大小。例如,假设需要实现一个最长公共子序列问题的动态规划算法,可以使用vector来存储状态:

string s1 = "ABCBDAB";
string s2 = "BDCABA";
vector<vector<int>> dp(s1.size() + 1, vector<int>(s2.size() + 1));
for (int i = 1; i <= s1.size(); i++) {for (int j = 1; j <= s2.size(); j++) {if (s1[i - 1] == s2[j - 1]) {dp[i][j] = dp[i - 1][j - 1] + 1;} else {dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);}}
}
int ans = dp[s1.size()][s2.size()];  // 最长公共子序列的长度

需要注意的是,使用vector来实现二维数组时,应该将数组定义为vector<vector>类型,并使用resize()方法来动态调整数组大小。

总之,在算法模拟题中,vector是一个非常实用的容器类,可以方便地处理动态数组的问题,并且可以根据具体的应用场景进行优化,以提高性能和减少内存开销。

相关文章:

Let’s Make C++ Great Again——set与vector

文章目录 set常用的set方法&#xff1a;set实现去重的例子&#xff1a;自定义比较函数的例子&#xff0c;按照字符串长度从小到大排序&#xff1a;使用set容器求两个集合的交集的例子&#xff1a; vector创建vector对象插入和删除元素获取vector的大小和容量检查vector是否为空…...

Nginx+Tomcat负载均衡、动静分离

一.Nginx负载均衡实现原理 Nginx实现负载均衡是通过反向代理实现 1、 反向代理原理 2、反向代理的概念 反向代理&#xff08;Reverse Proxy&#xff09;方式是指以代理服务器来接受internet上的连接请求&#xff0c;然后将请求转发给内部网络上的服务器&#xff0c;并将从服…...

SpringCloud入门实战(七)-Hystrix服务熔断

&#x1f4dd; 学技术、更要掌握学习的方法&#xff0c;一起学习&#xff0c;让进步发生 &#x1f469;&#x1f3fb; 作者&#xff1a;一只IT攻城狮 。 &#x1f490;学习建议&#xff1a;1、养成习惯&#xff0c;学习java的任何一个技术&#xff0c;都可以先去官网先看看&…...

百度平地起“雷”,突然爆出的QPS数据意味着什么?

鲁迅先生1923年在北师大发表了著名的演讲《娜拉走后怎样》&#xff0c;其中的提问与思考方式振聋发聩&#xff0c;直到今天也依旧有效。面对很多产业现象、技术趋势&#xff0c;我们也不妨多问几个“之后怎样”。 比如说&#xff0c;自ChatGPT爆火之后&#xff0c;中国各个互联…...

电子模块|外控集成 LED 光源 WS2812模块---硬件介绍和stm32驱动

电子模块|外控集成 LED 光源 WS2812模块 模块简介模块特点机械尺寸单线归零码通讯方式24bit 数据结构 stm32 驱动 模块简介 WS2812是一个集控制电路与发光电路于一体的智能外控LED光源。其外型与一个5050LED灯珠相同&#xff0c;每个元件即为一个像素点。像素点内部包含了智能…...

Jenkins+Python自动化测试持续集成详细教程(全网独家)

目录 一、前言 二、环境准备 三、创建Jenkins Job 四、编写Python自动化测试脚本 五、测试报告生成与展示 六、持续集成流程优化 七、实战演练 八、常见问题及解决方案 九、结论 一、前言 Jenkins是目前最为流行的CI/CD工具之一&#xff0c;它可以支持多种语言和技术…...

运维监控工具PIGOSS BSM扩展指标介绍

PIGOSS BSM运维监控工具&#xff0c;除系统自带指标外&#xff0c;还支持添加SNMP扩展指标、脚本扩展指标、JMX扩展指标、自定义JDBC指标等&#xff0c;今天本文将介绍如何添加SNMP扩展指标和脚本扩展指标。 添加SNMP扩展指标 前提&#xff1a;需要知道指标的oid 例子&#xff…...

一些前端问题2

1.业务场景中需要嵌入公司其他行业线的页面&#xff0c;这种不使用 iframe 该怎么办&#xff1f; 答&#xff1a;理论上应该让他们给你做个组件出来&#xff0c;但是如果实在没别的办法&#xff0c;就使用 iframe 吧。 2.jquery ajax 同步请求的原理是? 目前用 axios 库&…...

Moviepy模块之视频添加图片水印

文章目录 前言视频添加图片水印1.引入库2.加载视频文件3.加载水印图片4.缩放水印图片大小5.设置水印的位置5.1 相对于视频的左上角5.2 相对于视频的左下角5.3 相对于视频的右上角5.4 相对于视频的右下角5.5 相对于视频的左中位置5.6 相对于视频的正中位置5.7 相对于视频的右中位…...

day35—编程题

文章目录 1.第一题1.1题目1.2思路1.3解题 2.第二题2.1题目2.2思路2.3解题 1.第一题 1.1题目 描述&#xff1a; 今年公司年会的奖品特别给力&#xff0c;但获奖的规矩却很奇葩&#xff1a; 首先&#xff0c;所有人员都将一张写有自己名字的字条放入抽奖箱中&#xff1b;待所有…...

Linux安装Nginx

前言 提示&#xff1a;这里可以添加本文要记录的大概内容&#xff1a; Linux安装Nginx的详细步骤。 一、安装Nginx的相关依赖 1、安装gcc,PCRE pcre-devel,zlib,OpenSSL, 提示&#xff1a;安装 nginx 需要先将官网下载的源码进行编译&#xff0c;编译依赖 gcc 环境。 PCRE(…...

Qt 项目Mingw编译器转换为VS编译器时的错误及解决办法

错误 在mingw生成的项目&#xff0c;转换为VS编译器时通常会报些以下错误&#xff08;C4819警告&#xff0c;C2001错误&#xff0c;C2143错误&#xff09; 原因及解决方式 这一般是由于字符编码引起的&#xff0c;在源代码文件中包含了中文字符导致的。Qt Creator 生成的代码文…...

大学生用什么蓝牙耳机好?2023好用的蓝牙耳机推荐

近几年&#xff0c;蓝牙耳机市场不断扩大&#xff0c;逐渐取代有线耳机成为最受人欢迎的数码产品之一。作为蓝牙耳机主要受众群的大学生&#xff0c;用什么蓝牙耳机比较好呢&#xff1f;下面&#xff0c;我来给大家推荐几款便宜好用的蓝牙耳机&#xff0c;一起来看看吧。 一、…...

【好题】好题分享

1001-四舍五入_牛客竞赛语法入门班数组模拟、枚举、贪心习题 (nowcoder.com) 题目描述 四舍五入是个好东西。比如你只考了45分&#xff0c;四舍五入后你是50分再四舍五入你就是满分啦&#xff01;qdgg刚考完拓扑。成绩十分不理想。但老师觉得他每天都很认真的听课很不容易。于是…...

three.js 怎么在自动缩放的时候添加动画效果

要在自动缩放的时候添加动画效果可以使用three.js中的Tween.js库。Tween.js提供了一种简单的方式来创建和管理动画&#xff0c;它可以让开发者通过简单的API来控制对象的属性变化&#xff0c;从而实现动画效果。 以下是一个使用Tween.js实现模型缩放动画的示例&#xff1a; 加…...

考虑梯水电站群的水火电节能调度(Python代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…...

CF914G Sum the Fibonacci

CF914G Sum the Fibonacci 洛谷Sum the Fibonacci 题目大意 给你一个长度为 n n n的数组 s s s&#xff0c;定义五元组 ( a , b , c , d , e ) (a,b,c,d,e) (a,b,c,d,e)是合法的当且仅当&#xff1a; 1 ≤ a , b , c , d , e ≤ n 1\leq a,b,c,d,e\leq n 1≤a,b,c,d,e≤n ( …...

Shell基础入门实战

写在前面 好久没在项目内做自动化了&#xff0c;主要是现阶段在项目内做自动化收益不大&#xff0c;最近开发做batch run的正好缺人&#xff0c;我看了一下代码&#xff0c;就是通过代码读取jar包和远程服务器连接&#xff0c;然后通过shell脚本&#xff0c;向数据库插入数据&a…...

如何进行微服务的技术选型?

本文首发自「慕课网」&#xff0c;想了解更多IT干货内容&#xff0c;程序员圈内热闻&#xff0c;欢迎关注"慕课网"&#xff01; 作者&#xff1a;陈于吉吉|慕课网讲师 随着这几年微服务的火爆&#xff0c;在平时的工作或者技术交流中&#xff0c;我们总能听到哪家公…...

Vue电商项目--应用开发详解

vue-cli脚手架初始化项目 首先&#xff0c;页面上新建一个文件夹。然后打开命令端口 vue create app 选择Default ([Vue 2] babel, eslint) 然后把项目拖拽到vscode中。项目目录看一下 脚手架项目的目录 node_modules:放置项目依赖的地方 public:一般放置一些共用的静态资源&a…...

Docker 运行 Kafka 带 SASL 认证教程

Docker 运行 Kafka 带 SASL 认证教程 Docker 运行 Kafka 带 SASL 认证教程一、说明二、环境准备三、编写 Docker Compose 和 jaas文件docker-compose.yml代码说明&#xff1a;server_jaas.conf 四、启动服务五、验证服务六、连接kafka服务七、总结 Docker 运行 Kafka 带 SASL 认…...

线程与协程

1. 线程与协程 1.1. “函数调用级别”的切换、上下文切换 1. 函数调用级别的切换 “函数调用级别的切换”是指&#xff1a;像函数调用/返回一样轻量地完成任务切换。 举例说明&#xff1a; 当你在程序中写一个函数调用&#xff1a; funcA() 然后 funcA 执行完后返回&…...

今日科技热点速览

&#x1f525; 今日科技热点速览 &#x1f3ae; 任天堂Switch 2 正式发售 任天堂新一代游戏主机 Switch 2 今日正式上线发售&#xff0c;主打更强图形性能与沉浸式体验&#xff0c;支持多模态交互&#xff0c;受到全球玩家热捧 。 &#x1f916; 人工智能持续突破 DeepSeek-R1&…...

用docker来安装部署freeswitch记录

今天刚才测试一个callcenter的项目&#xff0c;所以尝试安装freeswitch 1、使用轩辕镜像 - 中国开发者首选的专业 Docker 镜像加速服务平台 编辑下面/etc/docker/daemon.json文件为 {"registry-mirrors": ["https://docker.xuanyuan.me"] }同时可以进入轩…...

select、poll、epoll 与 Reactor 模式

在高并发网络编程领域&#xff0c;高效处理大量连接和 I/O 事件是系统性能的关键。select、poll、epoll 作为 I/O 多路复用技术的代表&#xff0c;以及基于它们实现的 Reactor 模式&#xff0c;为开发者提供了强大的工具。本文将深入探讨这些技术的底层原理、优缺点。​ 一、I…...

网络编程(UDP编程)

思维导图 UDP基础编程&#xff08;单播&#xff09; 1.流程图 服务器&#xff1a;短信的接收方 创建套接字 (socket)-----------------------------------------》有手机指定网络信息-----------------------------------------------》有号码绑定套接字 (bind)--------------…...

Spring是如何解决Bean的循环依赖:三级缓存机制

1、什么是 Bean 的循环依赖 在 Spring框架中,Bean 的循环依赖是指多个 Bean 之间‌互相持有对方引用‌,形成闭环依赖关系的现象。 多个 Bean 的依赖关系构成环形链路,例如: 双向依赖:Bean A 依赖 Bean B,同时 Bean B 也依赖 Bean A(A↔B)。链条循环: Bean A → Bean…...

Python+ZeroMQ实战:智能车辆状态监控与模拟模式自动切换

目录 关键点 技术实现1 技术实现2 摘要&#xff1a; 本文将介绍如何利用Python和ZeroMQ消息队列构建一个智能车辆状态监控系统。系统能够根据时间策略自动切换驾驶模式&#xff08;自动驾驶、人工驾驶、远程驾驶、主动安全&#xff09;&#xff0c;并通过实时消息推送更新车…...

脑机新手指南(七):OpenBCI_GUI:从环境搭建到数据可视化(上)

一、OpenBCI_GUI 项目概述 &#xff08;一&#xff09;项目背景与目标 OpenBCI 是一个开源的脑电信号采集硬件平台&#xff0c;其配套的 OpenBCI_GUI 则是专为该硬件设计的图形化界面工具。对于研究人员、开发者和学生而言&#xff0c;首次接触 OpenBCI 设备时&#xff0c;往…...

uniapp 小程序 学习(一)

利用Hbuilder 创建项目 运行到内置浏览器看效果 下载微信小程序 安装到Hbuilder 下载地址 &#xff1a;开发者工具默认安装 设置服务端口号 在Hbuilder中设置微信小程序 配置 找到运行设置&#xff0c;将微信开发者工具放入到Hbuilder中&#xff0c; 打开后出现 如下 bug 解…...