如何在Qt使用uchardet库
如何在 Qt 中使用 uchardet 库
文章目录
- 如何在 Qt 中使用 uchardet 库
- 一、简介
- 二、uchardet库的下载
- 三、在Qt中直接调用
- 四、编译成库文件后调用
- 4.1 编译工具下载
- 4.2 uchardet源码编译
- 4.3 测试编译文件
- 4.4 Qt中使用
- 五、一些小问题
- 5.1 测试文件存在的问题
- 5.2 uchardet库相关
- 六、写在最后
一、简介
相信对编程熟悉的朋友有时候都会碰到这样一个问题——乱码。
大家应该都知道,这是由于文件编码格式不正确导致的相关问题,即在文件编写和阅读的时候采取的编码格式不同,于是造成了我们阅读上的困难。
对于众多编译器,都有转文件编码与识别文件编码的相关功能,因此我们经常看到他们的身影。
如上图所示分别为 windows记事本、Notepad++、VsCode
所提供的文件编码格式识别。
而在网上搜索到的绝大多数方式是使用 python
中的 chardet
模块进行文件编码格式的判断。其实该库就是我们本次使用的 uchardet
库,其只是被开发者适配成了 python
版本。由于有关该库的 C++
使用示例太少,所以就有了这篇文章,希望能给各位大佬提供思路!!!
那么我在这里简单介绍一下 uchardet
库。
uchardet(Universal Charset Detector)
是一个强大的开源项目,它可以帮助我们自动识别文本的字符集编码。
uchardet
基于Mozilla
的CharDet
算法,该算法经过大量实际数据训练,具有高度的准确性。其核心功能是通过分析字节序列的统计特性,判断出最可能的字符编码类型,支持如UTF-8、GBK、ISO-8859-1
等多种常见的字符集。项目采用
C++
编写,易于跨平台集成,并且拥有简洁的API
接口,使得开发者可以轻松地将uchardet
整合到他们的应用中。此外,项目还提供了Python
绑定,方便Python
开发者使用。项目地址(下载方式后续过程中我会进行阐述,因此不用着急下载!!!):
BYVoid/uchardet: An encoding detector library ported from Mozilla (github.com)
uchardet / uchardet · GitLab
项目网站主页:
- uchardet (www.freedesktop.org)
以上信息来源为以下文章,感谢作者分享!!
- 探索高效字符检测:深入理解
uchardet
-CSDN博客
由此,我们对 uchardet
有了初步的认识,那么如何将其应用到项目工程中,是本文的重点。这里我将使用 Qt
对该库进行操作,同理使用 C++
亦可实现。
在项目开始之前,简单介绍一下我所使用的配置环境:
开发平台:
- Window 10
- Qt 5.12.3
编译环境
- MinGW 64-bit
二、uchardet库的下载
由于网上资料实在是太少,所以说下载也是一件难事,不过本文推荐以下下载方式:
Index of /software/uchardet/releases (www.freedesktop.org)
- 如无法点击跳转可自行复制网址:https://www.freedesktop.org/software/uchardet/releases/
打开以后得到如下页面:
截至本文章撰写时间 2024/6/27,其版本更新到
0.0.8
而我们需要下载的是 uchardet-0.0.8.tar.xz
,这是稳定的发行版,可以正常使用。这里对新手朋友说一句,不要直接从 Github
上下载,而要去里面的 Release
下载,否则,你下载的文件大概率无法运行。因为没有 Release
的项目,大概率正在开发,其中不免存在或多或少的问题,盲目尝试不会让我们事半功倍!!!
回归正题,对上述下载的文件解压以后得到如下图所示的文件结构。
那么到这里该库的源码下载完成!!!后续我们将对其进行使用。
三、在Qt中直接调用
这种方法可以实现功能,但不推荐。因为直接使用其源码文件导入到 Qt
中,会增加很多文件,对我们的阅读体验不是很好,但这里也做介绍,感兴趣的朋友可以阅读。
-
新建
Qt
项目,将uchardet
源码中的src
文件夹复制到Qt
项目文件中: -
然后在
Qt
中按照如下步骤添加库文件:如图所示,在项目文件夹上 右键,点击
Add Existing Directory
。如图所示,对
uchardet.cpp
文件取消勾选。对项目中已有的文件取消勾选!!!然后点击
OK
,此时我的项目结构为: -
我在
UI
文件中创建了一个按钮,用来测试该库是否可行,如下所示: -
对按钮使用转到槽,实现其
released
槽函数。-
在
widget.h
文件中进行如下更改:#ifndef WIDGET_H #define WIDGET_H#include <QWidget>#include <QFileDialog> #include <QDebug>/* 增加 uchardet 库头文件 */ #include "src/uchardet.h"namespace Ui { class Widget; }class Widget : public QWidget {Q_OBJECTpublic:explicit Widget(QWidget *parent = nullptr);~Widget();private slots:void on_pushButton_released();private:Ui::Widget *ui; };#endif // WIDGET_H
-
对
widget.cpp
文件中对按钮的槽函数进行实现/*! * @File : widget.cpp* @Brief : 按钮槽函数* @Details : 详细说明* @Param : 参数* @Return : 返回值* @Author : Liu Jiahao* @Date : 2024-06-27 16:42:05* @Version : v1.1* @Copyright : Copyright By Liu Jiahao, All Rights Reserved* */ void Widget::on_pushButton_released() {QString filePath = QFileDialog::getOpenFileName(nullptr, "选择文件", "../", "所有文件 (*.*)");if (filePath.isEmpty()) {return;}QFile file(filePath);// 文件打开成功if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {QByteArray buff = file.readAll();uchardet_t ud = uchardet_new();uchardet_handle_data(ud, buff.constData(), buff.size());uchardet_data_end(ud);const char* encoding = uchardet_get_charset(ud);QString result = QString::fromLatin1(encoding);uchardet_delete(ud);qDebug() << "该文件的编码格式为:" << result;}file.close(); }
-
由此,完成了对该库的调用,这种方法较为简单,缺点就是会导入大量的源代码。
当我们运行程序点击按钮打开一个文件后,将会打印出该文件的编码格式,其运行结果如下图所示:
这里我做了一个简单的动图用于演示实现效果,如下所示:
四、编译成库文件后调用
在 Qt
中最常用的一般都是将所需库编译后调用,而 uchardet
也是可以进行这样的操作的,只不过实现起来有一点繁琐,需要我们自己进行编译。
4.1 编译工具下载
我们编译需要使用 MinGW-w64
进行编译,因此需要对该文件进行下载。
Releases · niXman/mingw-builds-binaries (github.com)
- 如无法点击跳转可自行复制网址:https://github.com/niXman/mingw-builds-binaries/releases
截至本文章撰写时间 2024/6/27,其版本更新到
13.2.0
我们可以看到下图所示的内容:
各个版本有何区别,感兴趣的朋友可以自行搜索,这里将不再赘述!!!本文着重讲解如何使用 uchardet
,望谅解!!!
这里我电脑是 64 位的,故我下载 x86_64-13.2.0-release-win32-seh-ucrt-rt_v11-rev0.7z
,下载后解压得到以下文件信息:
任意一个盘都可以,我这里直接解压在了 C 盘,大家不要学我!!!
- 尽量解压到一个自己好找的地方,后续需要使用这个地址!!!
然后打开 设置->系统->系统信息->高级系统设置->环境变量
,按照图中所示步骤进行点击:
我这里电脑没有装中文,但界面几乎一致。
我之前将其解压到 C:/mingw64/
目录下,因此这里我需要向环境变量中加入其 bin
文件,如下所示:
此时我们打开控制台(快捷键 win + R
后输入 cmd
最后回车),在其中输入 gcc -v
得到以下信息:
即证明安装完成,但还有一步需要操作。
打开 MinGW-w64
的安装目录,进入其 bin
文件,找到 mingw32-make.exe
文件将其复制一份重命名为 make.exe
,如下所示:
这样做是为了我们后续使用命令时,能够方便的使用
make
命令,而不是mingw32-make
此时再次使用控制台,输入 make -v
或者 mingw32-make -v
都能输出以下内容:
至此,结束安装编译工具的工作。接下来需要编译 uchardet
源码。
4.2 uchardet源码编译
同样打开控制台,这里我们需要提前将源码文件复制一份,这样方便我们出错后有回转的余地,而不是每次都要重新下载源码。我这里将复制的源码文件夹命名为 uchardet-copy
,然后输入命令行,去到复制源码的文件夹,命令如下:
cd <复制后源码文件夹的路径>
运行结果如图所示:
此后依次输入以下命令:
mkdir build
cd build
cmake .. -G "MinGW Makefiles"
make
不出意外的话将会在 uchardet-copy/build/
目录中生成类似的文件结构:
4.3 测试编译文件
后续一切操作都是基于我复制源码的文件夹,即 uchardet-copy
文件夹下的!!!
-
首先,需要我们进入
uchardet-copy/build/src
目录下找到libuchardet.dll
文件,将其复制到uchardet-copy/build/test
中: -
打开控制台,进入
uchardet-copy/build/test
目录中,同样使用cd
命令:cd <写入自己文件路径>
-
然后在
uchardet-copy/build/test
目录中新建一个文件,我这里新建的a.txt
文件,默认采用的是UTF-8
编码格式,此时命令窗口中输入你想检测的文件,我使用以下命令行:uchardet-tests.exe a.txt
得到以下内容:
可以看到其编码格式为
UTF-8
,检测结果正确!
由此可以看到我们编译结果成功!!!其他编码格式相关的测试大家可以自行验证,这里不再赘述!!!
4.4 Qt中使用
通过上一步编译后我们已经得到了相关的 .a
和 .dll
文件,其路径位于我上述所讲的 uchardet-copy/build/src
文件夹,将 .a
以及 .dll
复制到我们新建的 Qt
项目文件中。
这里需要注意的是,由于我电脑是64位的,我下载的 MinGW 也是64位版本,因此编译出的 dll 文件也是用于64位操作系统的。所以,建立 Qt 项目时,注意所需 Qt 编译环境,应当是 MinGw 64-bit!!!
除此之外,还需要添加 .h
文件,其路径位于 uchardet-copy/src
文件夹内,同样需要将其复制到我们自己的 Qt
项目文件夹中,我这里新建了文件夹 uchardet
并将相关文件复制在该文件中,如下所示:
然后我们需要在工程文件中导入该动态库(具体操作不予细说,这里只介绍重要部分)。
-
导入动态库:
具体在
.pro
文件中添加的东西为:win32: LIBS += -L$$PWD/uchardet/ -luchardetINCLUDEPATH += $$PWD/uchardet DEPENDPATH += $$PWD/uchardet
-
与本文第三小节类似,在
UI
文件中添加一个按钮: -
具体代码也与第三小节类似,这里简单赘述:
在
widget.h
中有以下代码:#ifndef WIDGET_H #define WIDGET_H#include <QWidget>#include <QDebug> #include <QFileDialog>#include <uchardet/uchardet.h>namespace Ui { class Widget; }class Widget : public QWidget {Q_OBJECTpublic:explicit Widget(QWidget *parent = nullptr);~Widget();private slots:void on_pushButton_released();private:Ui::Widget *ui; };#endif // WIDGET_H
在
widget.c
文件中实现其槽函数:/*!* @File : widget.cpp* @Brief : 打开文件槽函数* @Details : 详细说明* @Param : 参数* @Return : 返回值* @Author : Liu Jiahao* @Date : 2024-06-28 14:43:15* @Version : v1.1* @Copyright : Copyright By Liu Jiahao, All Rights Reserved**/ void Widget::on_pushButton_released() {QString filePath = QFileDialog::getOpenFileName(nullptr, "选择文件", "../", "所有文件 (*.*)");if (filePath.isEmpty()) {return;}QFile file(filePath);// 文件打开成功if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {QByteArray buff = file.readAll();uchardet_t ud = uchardet_new();uchardet_handle_data(ud, buff.constData(), buff.size());uchardet_data_end(ud);const char* encoding = uchardet_get_charset(ud);QString result = QString::fromLatin1(encoding);uchardet_delete(ud);qDebug() << "该文件的编码格式为:" << result;}file.close(); }
-
其运行结果也与第三小节类似,只是采用了不同的调库方式,这里就不再进行赘述。
值得注意的是,该库并不能确保百分百检测出的文件类型正确,同时,文件中如果没有文本信息,也是无法检测出来的。
五、一些小问题
在对该库的使用过程,也发现一些或多或少的小问题,在这一小节将进行阐述。
5.1 测试文件存在的问题
细心的朋友可能会注意到,在 uchardet/test
中有很多文件夹,如下所示:
其中均为不同语言的不同编码格式文件,例如 en
为英语,其中包含文件 ascii.txt
,也就意味着该文件编码格式为 ascii
,但是我们将此文件复制到 uchardet-copy/build/test
中进行测试的时候,发现其并不能输出任何东西,如下所示:
通过对 uchardet-copy/test
中 uchardet-tests.c
文件的阅读,其中包含以下代码:
/* In a unit test, 0 means success, other returned values mean failure. */
success = (strcmp(charset, expected_charset) != 0);
if (success) {fprintf(stderr, "success: %d, Got %s, expected %s\n", success, charset, expected_charset);
}
通过对这代码的分析可以知道,charset
为检测出的文件编码格式类型,而 expected_charset
为期望的文件编码格式类型。再往上看,有以下代码:
expected_charset = strrchr(filename, '/');
if (expected_charset == NULL)
{expected_charset = filename;
}
else
{expected_charset++;
}
expected_charset = strtok(expected_charset, ".");
我们通过阅读这段代码,可以知道,其进行的操作是把你输入的文件名去后缀并保存起来,使其成为 expected_charset
变量。
那么上述问题迎刃而解,例如,我们输入的文件名是 ascii.txt
,经过其检测后得出其编码格式为 ascii
,那么对于 success = (strcmp(charset, expected_charset) != 0);
这一句代码而言,得到的结果 success
必定为 0
,故没有输出。
可以看的出来,作者这样做的目的是,当文件编码格式和文件名相同时,判定为真,则不进行输出。当文件编码格式和文件名不相同时,判定为假,输出错误信息。
其实这对我们开发而言,并没有多大关系,也不影响我们使用这个库进行编码识别的操作,只是我在开发过程中遇到这个问题的一些感想。希望能对本文读者有所帮助!!!
5.2 uchardet库相关
由于编码格式众多且繁杂,且该库长时间没有进行更新,难免会有一些小问题,导致识别文件编码格式不准确。但这都是在我们可以承受的范围之内。
另外肯定有人好奇,我怎么知道这个库为什么这么用。实际上,我在网上找了大量资料,对于该库的描述实在是太少,偶然间看到一位大佬写的文章:C++ 自动检测编码_uchardet c++±CSDN博客
顿时恍然大悟,于是我也去查看了 Notepad++
的源码文件:
并且,notepad++
为了解决该库无法识别出 UTF-8 BOM、UTF-16BE BOM、UTF-16LE BOM
的问题,专门对这几个类型进行了单独的判断:
那么综合来讲,该库的性能以及使用体验还是不错的,大家感兴趣可以自行尝试。
六、写在最后
本文介绍了 如何在Qt中使用uchardet库,同时该库也可适用于C++。以及使用过程中存在的一些小问题。
本文中的代码后续会逐步开源,欢迎关注,敬请期待!!!
欢迎广大读者提出问题以及修改意见,本人看到后会给予回应,欢迎留言,后续会逐步进行开源!!!
另外,由于文章是作者手打的文字,有些地方可能文字会出错,望谅解,也可私信联系我,我对其进行更改。
-
个人CSDN账号:刘梓谦_-CSDN博客
-
Gitee:刘佳豪 (liu-jiahaohappy) - Gitee.com
-
GitHub:Jiahao-Liu29 (github.com)
相关文章:

如何在Qt使用uchardet库
如何在 Qt 中使用 uchardet 库 文章目录 如何在 Qt 中使用 uchardet 库一、简介二、uchardet库的下载三、在Qt中直接调用四、编译成库文件后调用4.1 编译工具下载4.2 uchardet源码编译4.3 测试编译文件4.4 Qt中使用 五、一些小问题5.1 测试文件存在的问题5.2 uchardet库相关 六…...

G9 - ACGAN理论与实战
🍨 本文为🔗365天深度学习训练营 中的学习记录博客🍖 原作者:K同学啊 目录 环境步骤环境设置数据准备工具方法模型设计模型训练模型效果展示 总结与心得体会 上周已经简单的了解了ACGAN的原理,并且不经实践的编写了部分…...

合合信息大模型“加速器”亮相2024世界人工智能大会,助力大模型学好“专业课”
7月4日至7日,2024世界人工智能大会在上海拉开帷幕。现阶段,“百模大战”现象背后的中国大模型发展前景与堵点仍然是各界关注的焦点。如何帮助大模型在信息的海洋中快速找准航向,在数据的荒漠中找到高质量的“水源”?合合信息在本次…...

bond网络配置文件中 interface-name 与 id 的区别
在bond网络配置文件中,interface-name和id是两个不同的参数,它们有如下区别: interface-name:该参数用于指定bond设备所使用的物理网卡接口的名称。可以设置一个或多个接口名称,多个接口名称之间使用逗号分隔。例如&am…...

Linux权限概述
一、权限概述 1.权限的基本概念 2.为什么要设置权限 3.linux用户的身份类别 4.user文件的拥有者 5.group文件所属组内用户 6.other其他用户 7.特殊用户root 二、普通权限管理 1.ls -l查看文件权限 2.文件类型以及权限解析 3.文件或文件夹的权限设置 4.通过数字给文件…...

谷粒商城学习-09-配置Docker阿里云镜像加速及各种docker问题记录
文章目录 一,配置Docker阿里云镜像加速二,Docker安装过程中的几个问题1,安装报错:Could not resolve host: mirrorlist.centos.org; Unknown error1.1 检测虚拟机网络1.2 重设yum源 2,报错:Could not fetch…...

基于GWO灰狼优化的多目标优化算法matlab仿真
目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.本算法原理 4.1灰狼优化算法原理 4.2 多目标优化问题(MOP)的帕累托最优解 4.3 基于GWO的多目标优化算法 5.完整程序 1.程序功能描述 基于GWO灰狼优化的多目标优化算法matlab仿真,目标函数…...

排序算法-java版本
冒泡排序 原理:相邻的数据两两比较,小的放前面,大的放后面 int[] arr{3,5,2,1,4} for(int i0;i<arr.length-1;i){for(int j0;j<arr.length-1-i;j){if(arr[j]>arr[j1]){int temparr[j];arr[j]arr[j1];arr[j1]temp;}}}选择排序 升序…...

Java+前后端分离架构+ MySQL8.0.36产科信息管理系统 产科电子病历系统源码
Java前后端分离架构 MySQL8.0.36产科信息管理系统 产科电子病历系统源码 产科信息管理系统—住院管理 数字化产科住院管理是现代医院管理中的重要组成部分,它利用数字化技术优化住院流程,提升医疗服务质量和效率。以下是对数字化产科住院管理的详细阐述…...

js使用websocket,vue使用websocket,copy即用
新建一个文件 websocket.js // 定义websocket 地址 let socketurlDev "ws://192.000.0.0:8085/websocket/admin/"; //开发环境 let socketurlProd "wss://123456789.cn/prod-api/websocket/admin/"; //正式环境// 重连锁, 防止过多重连 let reconnectLo…...

【鸿蒙学习笔记】Stage模型工程目录
官方文档:应用配置文件概述(Stage模型) 目录标题 FA模型和Stage模型工程级目录模块级目录app.json5module.json5程序执行流程程序基本结构开发调试与发布流程 FA模型和Stage模型 工程级目录 模块级目录 app.json5 官方文档:app.j…...

算法基础-----【动态规划】
动态规划(待完善) 动规五部曲分别为: 确定dp数组(dp table)以及下标的含义确定递推公式(状态转移公式)dp数组如何初始化确定遍历顺序举例推导dp数组、 动态规划的核心就是递归剪枝(存储键值,…...

Java中的响应式编程与Reactor框架
Java中的响应式编程与Reactor框架 大家好,我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编,也是冬天不穿秋裤,天冷也要风度的程序猿! 响应式编程(Reactive Programming)是一种面向数据流…...

政安晨【零基础玩转各类开源AI项目】基于Ubuntu系统部署ComfyUI:功能最强大、模块化程度最高的Stable Diffusion图形用户界面和后台
目录 ComfyUI的特性介绍 开始安装 做点准备工作 在Conda虚拟环境中进行 依赖项的安装 运行 政安晨的个人主页:政安晨 欢迎 👍点赞✍评论⭐收藏 收录专栏: 零基础玩转各类开源AI项目 希望政安晨的博客能够对您有所裨益,如有不足之处&…...

匿名内部类
下面代码中,Person24 是一个抽象类,这意味着它不能被直接实例化,只能通过继承它的子类来实现其抽象方法。代码片段中展示了如何使用匿名内部类来实现一个抽象类的实例。 package chapter04;public class Java24_Object_匿名内部类 {public s…...

react_web自定义组件_多类型Modal_搜索栏Search
目录 一、带输入框的Modal 二、提示框Modal 三、搜索栏Search 在做项目时引入一些现成的UI组件,但是如果和设计图冲突太大,更改时很麻烦,如果自己写一个通用组件其实也就几十分钟或者几个小时,而且更具UI设计更改也比较好更改&…...

Apache Flink架构介绍
目录 一、Apache Flink架构组件栈 1.1 概述 1.2 架构图 1.3 架构分层组件说明 1.3.1 物理部署层 1.3.2 Runtime 核心层 1.3.3 API & Libraries层 二、Flink运行时架构 2.1 概述 2.2 架构图 2.3 架构角色和组件 2.3.1 Flink Clients客户端 2.3.2 JobManager 2.…...

华为HCIP Datacom H12-821 卷28
1.单选题 下面是一台路由器的部分配置,关于该部分配置描述正确的是,[HUAWEI]ip ip-prefx pl permit 10.0.192.0 8greater-equal17 less-equal 18 A、10.0.192.0/8网段内,掩码长度为18的路由会匹配到该前缀列表,匹配规则为允许 B、10.0.192.0/8网段内掩码长度为21的路…...

安装Nginx以及简单使用 —— windows系统
一、背景 Nginx是一个很强大的高性能Web和反向代理服务,也是一种轻量级的Web服务器,可以作为独立的服务器部署网站,应用非常广泛,特别是现在前后端分离的情况下。而在开发过程中,我们常常需要在window系统下使用Nginx作…...

【UE5.3】笔记8 添加碰撞,检测碰撞
添加碰撞 打开BP_Food,添加Box Collision组件,与unity类似: 调整Box Collision的大小到刚好包裹物体,通过调整缩放和盒体范围来控制大小,一般先调整缩放找个大概大小,然后调整盒体范围进行微调。 碰撞检测 添加好碰撞…...

丝滑流畅!使用kimi快速完成论文仿写
学境思源,一键生成论文初稿: AcademicIdeas - 学境思源AI论文写作 今天的分享,我们将带大家探索一种新的学术写作技巧——使用Kimi进行论文仿写。本文将深入解析如何利用Kimi的智能辅助功能,提高论文写作的效率和质量,…...

【C++】认识使用string类
【C】STL中的string类 C语言中的字符串标准库中的string类string类成员变量string类的常用接口说明成员函数string(constructor构造函数)~string(destructor析构函数)默认赋值运算符重载函数 遍历string下标[ ]迭代器范围for反向迭代器 capacitysizelengthmax_sizeresizecapaci…...

如何在 Odoo 16 中对 Many2Many 字段使用 Group by
Many2many 字段与 Many2one 字段类似,因为它们在模型之间建立了新的关系。在Odoo 16中,您无法按 many2many 字段分组,因为可以使用 many2many 记录选择任何记录。当您使用 many2many 字段给出 group by 过滤器时,您将遇到断言错误。 介绍如何在 Odoo 16 中使用 Many2Many…...

PCL从理解到应用【03】KDTree 原理分析 | 案例分析 | 代码实现
前言 本文分析KDTree的原理,集合案例深入理解,同时提供源代码。 三个案例:K近邻搜索、半径内近邻搜索、近似最近邻搜索。方法对比,如下表所示: 特性K近邻搜索半径内近邻搜索近似最近邻搜索描述查找K个最近邻点查找指…...

Windows 11内置一键系统备份与还原 轻松替代Ghost
面对系统崩溃、恶意软件侵袭或其他不可预见因素导致的启动失败,Windows 7~Windows 11内置的系统映像功能能够迅速将您的系统恢复至健康状态,确保工作的连续性和数据的完整性。 Windows内置3种备份策略 U盘备份:便携且安全 打开“创建一个恢…...

leetCode-hot100-动态规划专题
动态规划 动态规划定义动态规划的核心思想动态规划的基本特征动态规划的基本思路例题322.零钱兑换53.最大子数组和72.编辑距离139.单词拆分62.不同路径63.不同路径Ⅱ64.最小路径和70.爬楼梯121.买卖股票的最佳时机152.乘积最大子数组 动态规划定义 动态规划(Dynami…...

【算法笔记自学】入门篇(2)——算法初步
4.1排序 自己写的题解 #include <stdio.h> #include <stdlib.h>void selectSort(int A[], int n) {for(int i 0; i < n - 1; i) { // 修正索引范围int k i;for(int j i 1; j < n; j) { // 修正索引范围if(A[j] < A[k]) {k j;}}if (k ! i) { // 仅在…...

Redis基础教程(六):redis 哈希(Hash)
💝💝💝首先,欢迎各位来到我的博客,很高兴能够在这里和您见面!希望您在这里不仅可以有所收获,同时也能感受到一份轻松欢乐的氛围,祝你生活愉快! 💝Ὁ…...

鸿蒙开发设备管理:【@ohos.account.appAccount (应用帐号管理)】
应用帐号管理 说明: 本模块首批接口从API version 7开始支持。后续版本的新增接口,采用上角标单独标记接口的起始版本。开发前请熟悉鸿蒙开发指导文档:gitee.com/li-shizhen-skin/harmony-os/blob/master/README.md点击或者复制转到。 导入模…...

java项目自定义打印日志,打印请求方式,参数用时等
1.相关依赖 <!-- 私人工具包 --><dependency><groupId>cn.changeforyou</groupId><artifactId>location</artifactId><version>1.13-SNAPSHOT</version></dependency><!-- hutool工具依赖 --><dependency>…...