C++ Qt开发:运用QJSON模块解析数据
Qt 是一个跨平台C++图形界面开发库,利用Qt可以快速开发跨平台窗体应用程序,在Qt中我们可以通过拖拽的方式将不同组件放到指定的位置,实现图形化开发极大的方便了开发效率,本章将重点介绍如何运用QJson
组件的实现对JSON文本的灵活解析功能。
JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,它易于人阅读和编写,也易于机器解析和生成。该格式是基于JavaScript语言的一个子集,但它是一种独立于语言的数据格式,因此可以在许多不同的编程语言中使用。
该数据是以键值对的形式组织的,其中键是字符串,值可以是字符串、数字、布尔值、数组、对象(即嵌套的键值对集合)或null,在Qt中默认提供了QJson
系列类库,使用该类库可以很方便的解析和处理JSON文档。
1.1 解析单一键值对
实现解析根中的单一键值对,例如解析config.json
配置文件中的blog,enable,status
等这些独立的字段值,在解析之前需要先通过QJsonDocument::fromJson
将内存中的字符串格式化为QJsonDocument
类型,当有着该类型之后,则我们可以使用*.object()
将其转换为对应的QJsonObject
对象,在对象中我们可以调用各种方法对内存中的JSON
数据进行处理。
以下是关于 QJsonDocument
类的一些常用方法的说明:
方法 | 说明 |
---|---|
QJsonDocument() | 构造函数,创建一个空的 JSON 文档。 |
QJsonDocument(const QJsonObject &object) | 通过给定的 JSON 对象构造 JSON 文档。 |
QJsonDocument(const QJsonArray &array) | 通过给定的 JSON 数组构造 JSON 文档。 |
QJsonDocument(const QJsonValue &value) | 通过给定的 JSON 值构造 JSON 文档。 |
QJsonDocument(const QJsonDocument &other) | 复制构造函数。 |
QJsonDocument &operator=(const QJsonDocument &other) | 赋值运算符。 |
bool isNull() const | 检查文档是否为空。 |
bool isEmpty() const | 检查文档是否为空,包括 JSON 数组或对象为空的情况。 |
QJsonObject object() const | 返回文档中的 JSON 对象。 |
QJsonArray array() const | 返回文档中的 JSON 数组。 |
QJsonValue value() const | 返回文档中的 JSON 值。 |
bool isArray() const | 检查文档是否包含 JSON 数组。 |
bool isObject() const | 检查文档是否包含 JSON 对象。 |
QByteArray toBinaryData() const | 将文档转换为二进制数据。 |
bool fromBinaryData(const QByteArray &data) | 从二进制数据恢复文档。 |
QString toJson(QJsonDocument::JsonFormat format = QJsonDocument::Compact) const | 返回 JSON 字符串表示,可以选择格式化的方式。 |
static QJsonDocument fromJson(const QString &json, QJsonParseError *error = nullptr) | 从 JSON 字符串创建文档。 |
以下是关于 QJsonObject
类的一些常用方法的说明:
方法 | 说明 |
---|---|
QJsonObject() | 构造函数,创建一个空的 JSON 对象。 |
QJsonObject(const QJsonObject &other) | 复制构造函数。 |
QJsonObject &operator=(const QJsonObject &other) | 赋值运算符。 |
bool isEmpty() const | 检查对象是否为空。 |
int size() const | 返回对象中键值对的数量。 |
bool contains(const QString &key) const | 检查对象中是否包含指定的键。 |
QStringList keys() const | 返回对象中所有键的列表。 |
QJsonValue value(const QString &key) const | 返回与指定键关联的值。 |
void insert(const QString &key, const QJsonValue &value) | 向对象中插入键值对。 |
QJsonObject &unite(const QJsonObject &other) | 将另一个对象的键值对合并到当前对象。 |
void remove(const QString &key) | 从对象中移除指定键及其关联的值。 |
QJsonValue take(const QString &key) | 移除并返回与指定键关联的值。 |
void clear() | 移除对象中的所有键值对,使其变为空对象。 |
QJsonDocument toDocument() const | 将对象转换为 JSON 文档。 |
当需要读取参数时只需要使用find()
方法查询特定字段中的key值即可,按钮on_pushButton_clicked
被点击后执行如下流程;
void MainWindow::on_pushButton_clicked()
{// 字符串格式化为JSONQJsonParseError err_rpt;QJsonDocument root_document = QJsonDocument::fromJson(config.toUtf8(), &err_rpt);if(err_rpt.error != QJsonParseError::NoError){QMessageBox::information(nullptr,"提示","JSON格式错误",QMessageBox::Ok);}// 获取到Json字符串的根节点QJsonObject root_object = root_document.object();// 解析blog字段QString blog = root_object.find("blog").value().toString();//std::cout << "字段对应的值 = > "<< blog.toStdString() << std::endl;ui->lineEdit_blog->setText(blog);// 解析enable字段bool enable = root_object.find("enable").value().toBool();//std::cout << "是否开启状态: " << enable << std::endl;ui->lineEdit_enable->setText(QString::number(enable));// 解析status字段int status = root_object.find("status").value().toInt();//std::cout << "状态数值: " << status << std::endl;ui->lineEdit_status->setText(QString::number(status));
}
运行后点击读取数据按钮,输出效果如下;
1.2 解析单数组键值
实现解析简单的单一对象与单一数组结构,如配置文件中的GetDict
与GetList
既是我们需要解析的内容,在解析时我们需要通过toVariantMap
将字符串转换为对应的Map容器,当数据被转换后则就可以通过Map[]
的方式很容易的将其提取出来。
void MainWindow::on_pushButton_2_clicked()
{// 字符串格式化为JSONQJsonParseError err_rpt;QJsonDocument root_document = QJsonDocument::fromJson(config.toUtf8(), &err_rpt);if(err_rpt.error != QJsonParseError::NoError){QMessageBox::information(nullptr,"提示","JSON格式错误",QMessageBox::Ok);}// 获取到Json字符串的根节点QJsonObject root_object = root_document.object();// 解析单一对象QJsonObject get_dict_ptr = root_object.find("GetDict").value().toObject();QVariantMap map = get_dict_ptr.toVariantMap();if(map.contains("address") && map.contains("username") && map.contains("password") && map.contains("update")){QString address = map["address"].toString();QString username = map["username"].toString();QString password = map["password"].toString();QString update = map["update"].toString();std::cout<< " 地址: " << address.toStdString()<< " 用户名: " << username.toStdString()<< " 密码: " << password.toStdString()<< " 更新日期: " << update.toStdString()<< std::endl;ui->listWidget->addItem(address);ui->listWidget->addItem(username);ui->listWidget->addItem(password);ui->listWidget->addItem(update);}// 解析单一数组QJsonArray get_list_ptr = root_object.find("GetList").value().toArray();for(int index=0; index < get_list_ptr.count(); index++){int ref_value = get_list_ptr.at(index).toInt();std::cout << "输出数组元素: " << ref_value << std::endl;ui->listWidget_2->addItem(QString::number(ref_value));}
}
运行后点击解析数据按钮,输出效果如下;
1.3 解析多数组键值
实现解析字典嵌套字典或字典嵌套数组的结构,如配置文件中的ObjectInArrayJson
则是一个字典中嵌套了另外两个字典而每个字典中的值又是一个Value
数组,而与之相对应的ArrayJson
则是在列表中嵌套了另外一个列表,这两中结构的使用读者可参照如下案例;
首先我们来看ObjectInArrayJson
是如何被解析的,我们分别准备两个ComboBox
选择框,当读者点击按钮时我们通过toVariantMap
将字典转换为一个MAP容器,并通过toJsonArray
转换内部的列表到JsonArray
容器内,其初始化部分如下所示;
void MainWindow::on_pushButton_3_clicked()
{// 字符串格式化为JSONQJsonParseError err_rpt;QJsonDocument root_document = QJsonDocument::fromJson(config.toUtf8(), &err_rpt);if(err_rpt.error != QJsonParseError::NoError){QMessageBox::information(nullptr,"提示","JSON格式错误",QMessageBox::Ok);}// 获取到Json字符串的根节点QJsonObject root_object = root_document.object();// 找到Object对象QJsonObject one_object_json = root_object.find("ObjectInArrayJson").value().toObject();// 转为MAP映射QVariantMap map = one_object_json.toVariantMap();// 寻找One键QJsonArray array_one = map["One"].toJsonArray();for(int index=0; index < array_one.count(); index++){QString value = array_one.at(index).toString();std::cout << "One => "<< value.toStdString() << std::endl;ui->comboBox->addItem(value);}// 寻找Two键QJsonArray array_two = map["Two"].toJsonArray();for(int index=0; index < array_two.count(); index++){QString value = array_two.at(index).toString();std::cout << "Two => "<< value.toStdString() << std::endl;ui->comboBox_2->addItem(value);}
}
同理,要实现解析数组中的数组也可以通过该方式实现,如配置文件中的ArrayJson
既是我们需要解析的内容,首先我们通过isArray
判断该节点是否为数组,如果是则通过toArray().at
方法以此得到不同下标元素参数,并依次循环即可,其代码如下所示;
void MainWindow::on_pushButton_4_clicked()
{// 字符串格式化为JSONQJsonParseError err_rpt;QJsonDocument root_document = QJsonDocument::fromJson(config.toUtf8(), &err_rpt);if(err_rpt.error != QJsonParseError::NoError){QMessageBox::information(nullptr,"提示","JSON格式错误",QMessageBox::Ok);}// 获取到Json字符串的根节点QJsonObject root_object = root_document.object();// 获取MyJson数组QJsonValue array_value = root_object.value("ArrayJson");// 验证节点是否为数组if(array_value.isArray()){// 得到数组个数int array_count = array_value.toArray().count();// 循环数组个数for(int index=0;index <= array_count;index++){QJsonValue parset = array_value.toArray().at((index));if(parset.isArray()){QString address = parset.toArray().at(0).toString();QString username = parset.toArray().at(1).toString();QString userport = parset.toArray().at(2).toString();std::cout<< "地址: " << address.toStdString()<< "用户名: " << username.toStdString()<< "端口号: " << userport.toStdString()<< std::endl;ui->comboBox_3->addItem(address);ui->comboBox_4->addItem(username);ui->comboBox_5->addItem(userport);}}}
}
运行后点击两个初始化按钮则可以将字典或列表中的数据依次解析到不同的ComBobox
列表框内,输出效果如下;
1.4 解析多字典键值
实现解析字典中嵌套多个参数或字典中嵌套参数中包含列表的数据集,如配置文件中的ObjectJson
则是字典中存在多个键值对,而ObjectArrayJson
则更进一步在多键值对中增加了列表的支持,解析此类内容只需要依次逐级拆分即可,我们来看下如何实现对这些键值的灵活提取;
首先我们来实现对ObjectJson
的参数解析功能,读者可自行对比与之前1.3
中的区别,可以发现这两者的差别其实不大,解析ObjectJson
完整代码如下所示;
void MainWindow::on_pushButton_5_clicked()
{// 字符串格式化为JSONQJsonParseError err_rpt;QJsonDocument root_document = QJsonDocument::fromJson(config.toUtf8(), &err_rpt);if(err_rpt.error != QJsonParseError::NoError){QMessageBox::information(nullptr,"提示","JSON格式错误",QMessageBox::Ok);}// 获取到Json字符串的根节点QJsonObject root_object = root_document.object();// 获取MyJson数组QJsonValue object_value = root_object.value("ObjectJson");// 验证是否为数组if(object_value.isArray()){// 获取对象个数int object_count = object_value.toArray().count();// 循环个数for(int index=0;index <= object_count;index++){QJsonObject obj = object_value.toArray().at(index).toObject();// 验证数组不为空if(!obj.isEmpty()){QString address = obj.value("address").toString();QString username = obj.value("username").toString();std::cout << "地址: " << address.toStdString() << " 用户: " << username.toStdString() << std::endl;ui->comboBox_6->addItem(address);ui->comboBox_7->addItem(username);}}}
}
接着我们来实现一个更为复杂的需求,解析多字典中嵌套的数组,如配置文件中的ObjectArrayJson
则是我们需要解析的内容,在之前解析字典部分保持与上述案例一致,唯一不同的是我们需要通过value("ulist").toArray()
获取到对应字典中的数组,并通过循环的方式输出。
如下案例中,当读者点击初始化按钮时我们首先让字典中的数据填充之ComboBox
列表框中,接着当读者点击第一个列表框时我们让其过滤出特定的内容并赋值到第二个列表框中,以此实现联动效果,首先初始化部分如下所示;
void MainWindow::on_pushButton_6_clicked()
{// 字符串格式化为JSONQJsonParseError err_rpt;QJsonDocument root_document = QJsonDocument::fromJson(config.toUtf8(), &err_rpt);if(err_rpt.error != QJsonParseError::NoError){QMessageBox::information(nullptr,"提示","JSON格式错误",QMessageBox::Ok);}// 获取到Json字符串的根节点QJsonObject root_object = root_document.object();// 获取MyJson数组QJsonValue object_value = root_object.value("ObjectArrayJson");// 验证是否为数组if(object_value.isArray()){// 获取对象个数int object_count = object_value.toArray().count();// 循环个数for(int index=0;index <= object_count;index++){QJsonObject obj = object_value.toArray().at(index).toObject();// 验证数组不为空if(!obj.isEmpty()){QString uname = obj.value("uname").toString();std::cout << "用户名: " << uname.toStdString() << std::endl;ui->comboBox_8->addItem(uname);// 解析该用户的数组int array_count = obj.value("ulist").toArray().count();std::cout << "数组个数: "<< array_count << std::endl;for(int index=0;index < array_count;index++){QJsonValue parset = obj.value("ulist").toArray().at(index);int val = parset.toInt();std::cout << "Value = > "<< val << std::endl;ui->comboBox_9->addItem(QString::number(val));}}}}
}
当第一个选择框被选中时我们触发currentIndexChanged
信号,在其中只需要判断uname.compare(arg1)
是否相等如果相等则addItem
追加到新的列表内,运行效果如下所示,详细实现可参考附件。
1.5 解析多字典嵌套
实现解析多个字典嵌套或多个列表嵌套的结构,如配置文件中的NestingObjectJson
则是字典中嵌套字典,而ArrayNestingArrayJson
则是列表中嵌套列表,两种的解析方式基本一致。
我们首先来实现第一种格式的解析,当按钮被点击后,我们首先查询uuid
字段并赋值到ComBobox
列表中,实现代码如下所示;
void MainWindow::on_pushButton_7_clicked()
{// 字符串格式化为JSONQJsonParseError err_rpt;QJsonDocument root_document = QJsonDocument::fromJson(config.toUtf8(), &err_rpt);if(err_rpt.error != QJsonParseError::NoError){QMessageBox::information(nullptr,"提示","JSON格式错误",QMessageBox::Ok);}// 获取到Json字符串的根节点QJsonObject root_object = root_document.object();// 获取NestingObjectJson数组QJsonValue array_value = root_object.value("NestingObjectJson");// 验证节点是否为数组if(array_value.isArray()){// 得到内部对象个数int count = array_value.toArray().count();std::cout << "对象个数: " << count << std::endl;for(int index=0; index < count; index++){// 得到数组中的index下标中的对象QJsonObject array_object = array_value.toArray().at(index).toObject();QString uuid = array_object.value("uuid").toString();// 追加数据std::cout << uuid.toStdString() << std::endl;ui->comboBox_10->addItem(uuid);// 开始解析basic中的数据QJsonObject basic = array_object.value("basic").toObject();QString lat = basic.value("lat").toString();QString lon = basic.value("lon").toString();std::cout << "解析basic中的lat字段: " << lat.toStdString() << std::endl;std::cout << "解析basic中的lon字段: " << lon.toStdString()<< std::endl;// 解析单独字段QString status = array_object.value("status").toString();std::cout << "解析字段状态: " << status.toStdString() << std::endl;}}
}
当ComBobox
组件中的currentIndexChanged
信号被触发时,则直接执行对LineEdit
编辑框的赋值操作,其代码如下所示;
void MainWindow::on_comboBox_10_currentIndexChanged(const QString &arg1)
{// 字符串格式化为JSONQJsonParseError err_rpt;QJsonDocument root_document = QJsonDocument::fromJson(config.toUtf8(), &err_rpt);if(err_rpt.error != QJsonParseError::NoError){QMessageBox::information(nullptr,"提示","JSON格式错误",QMessageBox::Ok);}// 获取到Json字符串的根节点QJsonObject root_object = root_document.object();// 获取NestingObjectJson数组QJsonValue array_value = root_object.value("NestingObjectJson");// 验证节点是否为数组if(array_value.isArray()){// 得到内部对象个数int count = array_value.toArray().count();std::cout << "对象个数: " << count << std::endl;for(int index=0; index < count; index++){// 得到数组中的index下标中的对象QJsonObject array_object = array_value.toArray().at(index).toObject();QString uuid = array_object.value("uuid").toString();// 对比是否相等if(uuid.compare(arg1) == 0){// 开始解析basic中的数据QJsonObject basic = array_object.value("basic").toObject();QString lat = basic.value("lat").toString();QString lon = basic.value("lon").toString();std::cout << "解析basic中的lat字段: " << lat.toStdString() << std::endl;std::cout << "解析basic中的lon字段: " << lon.toStdString()<< std::endl;ui->lineEdit->setText(lat);ui->lineEdit_2->setText(lon);// 解析单独字段QString status = array_object.value("status").toString();std::cout << "解析字段状态: " << status.toStdString() << std::endl;}}}
}
同理,我们也可以实现字典中嵌套列表结构,如配置文件中的ArrayNestingArrayJson
既我们需要解析的内容,解析实现方法与上述代码保持一致,首先当按钮被点击后我们直接对ComBobox
组件进行初始化,代码如下所示;
void MainWindow::on_pushButton_8_clicked()
{// 字符串格式化为JSONQJsonParseError err_rpt;QJsonDocument root_document = QJsonDocument::fromJson(config.toUtf8(), &err_rpt);if(err_rpt.error != QJsonParseError::NoError){std::cout << "json 格式错误" << std::endl;}// 获取到Json字符串的根节点QJsonObject root_object = root_document.object();// 获取NestingObjectJson数组QJsonValue array_value = root_object.value("ArrayNestingArrayJson");// 验证节点是否为数组if(array_value.isArray()){// 得到数组中的0号下标中的对象QJsonObject array_object = array_value.toArray().at(0).toObject();// 解析手机号字符串QString telephone = array_object.value("telephone").toString();std::cout << "手机号: " << telephone.toStdString() << std::endl;ui->comboBox_11->addItem(telephone);// 定位外层数组QJsonArray root_array = array_object.find("path").value().toArray();std::cout << "外层循环计数: " << root_array.count() << std::endl;for(int index=0; index < root_array.count(); index++){// 定位内层数组QJsonArray sub_array = root_array.at(index).toArray();std::cout << "内层循环计数: "<< sub_array.count() << std::endl;for(int sub_count=0; sub_count < sub_array.count(); sub_count++){// 每次取出最里层数组元素float var = sub_array.toVariantList().at(sub_count).toFloat();std::cout << "输出元素: " << var << std::endl;// std::cout << sub_array.toVariantList().at(0).toFloat() << std::endl;ui->listWidget_3->addItem(QString::number(var));}}}
}
运行效果如下图所示;
相关文章:

C++ Qt开发:运用QJSON模块解析数据
Qt 是一个跨平台C图形界面开发库,利用Qt可以快速开发跨平台窗体应用程序,在Qt中我们可以通过拖拽的方式将不同组件放到指定的位置,实现图形化开发极大的方便了开发效率,本章将重点介绍如何运用QJson组件的实现对JSON文本的灵活解析…...

MySQL数据库基础合集
MySQL数据库基础合集 目录 MySQL数据库基础合集SQL关键字DDL关键字DML关键字DQL关键字DCL关键字约束关键字 SQL基础数据类型整数类型字符类型浮点类型时间类型 数据定义语言DDL1.查看数据库2.创建库3.删除库4.切换库5.创建表6.删除表7.查看表8.查看表属性9.插入列10.修改列11.设…...

oracle19.22的patch已发布
2024年01月16日,oracle发布了19.22的patch 具体patch如下 Reserved for Database - Do not edit or delete (Doc ID 19202401.9) 文档ID规则如下 19(版本)年份(202x)(季度首月01,04,07,10).9 往期patch no信息和下…...

HTML+CSS:3D轮播卡片
效果演示 实现了一个3D翻转的卡片动画,其中每个卡片都有不同的图片和不同的旋转角度。整个动画循环播放,无限次。整个页面的背景是一个占据整个屏幕的背景图片,并且页面内容被隐藏在背景图片之下。 Code <div class"container"…...

ES 分词器
概述 分词器的主要作用将用户输入的一段文本,按照一定逻辑,分析成多个词语的一种工具 什么是分词器 顾名思义,文本分析就是把全文本转换成一系列单词(term/token)的过程,也叫分词。在 ES 中,Ana…...

从0开始搭建若依微服务项目 RuoYi-Cloud(保姆式教程完结)
文章接上一章: 从0开始搭建若依微服务项目 RuoYi-Cloud(保姆式教程 一)-CSDN博客 四. 项目配置与启动 当上面环境全部准备好之后,接下来就是项目配置。需要将项目相关配置修改成当前相关环境。 数据库配置 新建数据库ÿ…...

Linux true/false区分
bash的数值代表和其它代表相反:0表示true;非0代表false。 #!/bin/sh PIDFILE"pid"# truenginx进程运行 falsenginx进程未运行 checkRunning(){# -f true表示普通文件if [ -f "$PIDFILE" ]; then# -z 字符串长度为0trueif [ -z &qu…...

一些著名的软件都用什么语言编写?
1、操作系统 Microsoft Windows :汇编 -> C -> C 备注:曾经在智能手机的操作系统(Windows Mobile)考虑掺点C#写的程序,比如软键盘,结果因为写出来的程序太慢,实在无法和别的模块合并&…...

外卖跑腿系统开发:构建高效、安全的服务平台
在当今快节奏的生活中,外卖跑腿系统的开发已成为技术领域的一个重要课题。本文将介绍如何使用一些常见的编程语言和技术框架,构建一个高效、安全的外卖跑腿系统。 1. 技术选择 在开始开发之前,我们需要选择适合的技术栈。常用的技术包括&a…...

【MQ02】基础简单消息队列应用
基础简单消息队列应用 在上一课中,我们已经学习到了什么是消息队列,有哪些消息队列,以及我们会用到哪个消息队列。今天,就直接进入主题,学习第一种,最简单,但也是最常用,最好用的消息…...

CTF CRYPTO 密码学-7
题目名称:敲击 题目描述: 让我们回到最开始的地方 0110011001101100011000010110011101111011011000110110010100110011011001010011010100110000001100100110001100101101001101000011100001100011001110010010110100110100011001000011010100110000…...
随机森林和决策树区别
随机森林(Random Forest)和决策树(Decision Tree)是两种不同的机器学习算法,其中随机森林是基于决策树构建的一种集成学习方法。以下是它们之间的主要区别: 决策树: 单一模型: 决策树是一种单一模型&#…...

新建VM虚拟机-安装centOS7-连接finalshell调试
原文 这里有问题 首先进入/etc/sysconfig/network-scripts/目录 cd /etc/sysconfig/network-scripts/ 然后编辑文件 ifcfg-ens33 vi ifcfg-ens33...
936. 戳印序列
Problem: 936. 戳印序列 文章目录 思路解题方法复杂度Code 思路 这道题目要求我们通过使用印章来印刷目标字符串,使得目标字符串最终变成全为’?‘的字符串。我们可以使用贪心的思想来解决这个问题。 首先,我们需要找到所有可以匹配印章的位置ÿ…...

20240129收获
今天终于发现《八部金刚功》第五部我一直做的是错的,嗨。这里这个写法非常聪明,创立的数组,以及用obj[key] item[key]这样的写法,这个写法充分展示了js常规写法中只有等号右边会去参与运算,等号左边就是普通的键的写法…...

【虚拟机数据恢复】异常断电导致虚拟机无法启动的数据恢复案例
虚拟机数据恢复环境: 某品牌R710服务器MD3200存储,上层是ESXI虚拟机和虚拟机文件,虚拟机中存放有SQL Server数据库。 虚拟机故障: 机房非正常断电导致虚拟机无法启动。服务器管理员检查后发现虚拟机配置文件丢失,所幸…...

vue3 + antd 封装动态表单组件(三)
传送带: vue3 antd 封装动态表单组件(一) vue3 antd 封装动态表单组件(二) 前置条件: vue版本 v3.3.11 ant-design-vue版本 v4.1.1 我们发现ant-design-vue Input组件和FormItem组件某些属性支持slot插…...

【算法专题】贪心算法
贪心算法 贪心算法介绍1. 柠檬水找零2. 将数组和减半的最少操作次数3. 最大数4. 摆动序列(贪心思路)5. 最长递增子序列(贪心算法)6. 递增的三元子序列7. 最长连续递增序列8. 买卖股票的最佳时机9. 买卖股票的最佳时机Ⅱ(贪心算法)10. K 次取反后最大化的数组和11. 按身高排序12…...

x-cmd pkg | sqlite3 - 轻量级的嵌入式关系型数据库
目录 简介首次用户 技术特点竞品和相关产品sqlite 与 x-cmd进一步阅读 简介 sqlite3 是一个轻量级的文件数据库,体积非常小,提供简单优雅而功能强大的 sql 化的数据查询。 通常情况下,sqlite 指的是 SQLite 2.x 版本,而 sqlite3 …...

LeetCode —— 43. 字符串相乘
😶🌫️😶🌫️😶🌫️😶🌫️Take your time ! 😶🌫️😶🌫️😶🌫️😶🌫️…...

K8S认证|CKS题库+答案| 11. AppArmor
目录 11. AppArmor 免费获取并激活 CKA_v1.31_模拟系统 题目 开始操作: 1)、切换集群 2)、切换节点 3)、切换到 apparmor 的目录 4)、执行 apparmor 策略模块 5)、修改 pod 文件 6)、…...

通过Wrangler CLI在worker中创建数据库和表
官方使用文档:Getting started Cloudflare D1 docs 创建数据库 在命令行中执行完成之后,会在本地和远程创建数据库: npx wranglerlatest d1 create prod-d1-tutorial 在cf中就可以看到数据库: 现在,您的Cloudfla…...
Qt Widget类解析与代码注释
#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete ui; }//解释这串代码,写上注释 当然可以!这段代码是 Qt …...
【C++从零实现Json-Rpc框架】第六弹 —— 服务端模块划分
一、项目背景回顾 前五弹完成了Json-Rpc协议解析、请求处理、客户端调用等基础模块搭建。 本弹重点聚焦于服务端的模块划分与架构设计,提升代码结构的可维护性与扩展性。 二、服务端模块设计目标 高内聚低耦合:各模块职责清晰,便于独立开发…...
JVM暂停(Stop-The-World,STW)的原因分类及对应排查方案
JVM暂停(Stop-The-World,STW)的完整原因分类及对应排查方案,结合JVM运行机制和常见故障场景整理而成: 一、GC相关暂停 1. 安全点(Safepoint)阻塞 现象:JVM暂停但无GC日志,日志显示No GCs detected。原因:JVM等待所有线程进入安全点(如…...
.Net Framework 4/C# 关键字(非常用,持续更新...)
一、is 关键字 is 关键字用于检查对象是否于给定类型兼容,如果兼容将返回 true,如果不兼容则返回 false,在进行类型转换前,可以先使用 is 关键字判断对象是否与指定类型兼容,如果兼容才进行转换,这样的转换是安全的。 例如有:首先创建一个字符串对象,然后将字符串对象隐…...

AI病理诊断七剑下天山,医疗未来触手可及
一、病理诊断困局:刀尖上的医学艺术 1.1 金标准背后的隐痛 病理诊断被誉为"诊断的诊断",医生需通过显微镜观察组织切片,在细胞迷宫中捕捉癌变信号。某省病理质控报告显示,基层医院误诊率达12%-15%,专家会诊…...

面向无人机海岸带生态系统监测的语义分割基准数据集
描述:海岸带生态系统的监测是维护生态平衡和可持续发展的重要任务。语义分割技术在遥感影像中的应用为海岸带生态系统的精准监测提供了有效手段。然而,目前该领域仍面临一个挑战,即缺乏公开的专门面向海岸带生态系统的语义分割基准数据集。受…...

day36-多路IO复用
一、基本概念 (服务器多客户端模型) 定义:单线程或单进程同时监测若干个文件描述符是否可以执行IO操作的能力 作用:应用程序通常需要处理来自多条事件流中的事件,比如我现在用的电脑,需要同时处理键盘鼠标…...

android RelativeLayout布局
<?xml version"1.0" encoding"utf-8"?> <RelativeLayout xmlns:android"http://schemas.android.com/apk/res/android"android:layout_width"match_parent"android:layout_height"match_parent"android:gravity&…...