尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
C++常见通用自写算法集合
目录1.字符串大小写转换2.容器内容去重3.求文件的sha值3.1.在vcpkg中安装openssl和asio库3.2.同步读取文件求sha值3.3.优化:用内存映射方式求sha值3.4.优化:异步读取文件求sha值3.5.几种方法性能比较4.求容器的最大最小值5.求容器内元素的平均值1.字符串大小写转换CommFunc.h#pragma once #include string namespace util { std::string to_upper(std::string_view src); std::string to_upper(const std::string src); std::string to_upper(std::string src); std::string to_lower(std::string_view src); std::string to_lower(const std::string src); std::string to_lower(std::string src); } // namespace utilCommFunc.cpp#include CommFunc.h #include algorithm #include cctype #include iterator namespace util { templatetypename Container, typename Func int(int) std::string _transform(Container src, Func func) { std::string dst; dst.reserve(src.size()); std::transform(src.cbegin(), src.cend(), std::back_inserter(dst), [toUpper std::move(func)](unsigned char c) - char { return static_castchar(toUpper(static_castint(c))); }); return dst; } std::string to_upper(std::string_view src) { #if 0 std::string dst; dst.reserve(src.size()); std::transform(src.cbegin(), src.cend(), std::back_inserter(dst), [](unsigned char c) - char { return static_castchar(std::toupper(static_castint(c))); }); return dst; #else return _transform(src, std::toupper); #endif } std::string to_upper(const std::string src) { #if 0 std::string dst; dst.reserve(src.size()); std::transform(src.cbegin(), src.cend(), std::back_inserter(dst), [](unsigned char c) - char { return static_castchar(std::toupper(static_castint(c))); }); return dst; #else return _transform(src, std::toupper); #endif } std::string to_upper(std::string src) { std::transform(src.begin(), src.end(), src.begin(), [](unsigned char c) - char { return static_castchar(std::toupper(static_castint(c))); }); return src; } std::string to_lower(std::string_view src) { #if 0 std::string dst; dst.reserve(src.size()); std::transform(src.cbegin(), src.cend(), std::back_inserter(dst), [](unsigned char c) - char { return static_castchar(std::tolower(static_castint(c))); }); return dst; #else return _transform(src, std::tolower); #endif } std::string to_lower(const std::string src) { #if 0 std::string dst; dst.reserve(src.size()); std::transform(src.cbegin(), src.cend(), std::back_inserter(dst), [](unsigned char c) - char { return static_castchar(std::tolower(static_castint(c))); }); return dst; #else return _transform(src, std::tolower); #endif } std::string to_lower(std::string src) { std::transform(src.begin(), src.end(), src.begin(), [](unsigned char c) - char { return static_castchar(std::tolower(static_castint(c))); }); return src; } } // namespace util优点不需要手动 resize不会因为大小不匹配出现内存 bug推荐。如果还是报错改用全局 ::tolower部分旧编译器 / 库的坑std::transform(src.cbegin(), src.cend(), std::back_inserter(dst), [](unsigned char c) - char { return static_castchar(::tolower(static_castint(c))); });区别std::tolower是 C 版本::tolower是 C 标准库全局符号有些平台头文件混乱会找不到std::tolower。2.容器内容去重C反射之检测struct或class是否实现指定函数//容器内容去重 templatetypename Container, typename Compare std::less void deduplicateContainer(Container container, Compare comp Compare());详细实现#pragma once #include algorithm #include iterator #include type_traits namespace util { #define HAS_NON_STATIC_AND_NON_CONST_MEMBER_EX1(R, member) \ templatetypename T struct has_non_static_member_ex1_##member{ \ private:\ templatetypename Y, Y y \ class Helper; \ templatetypename U T \ constexpr static bool has##member(...) {\ return false;\ }\ templatetypename U T\ constexpr static bool has##member(HelperR (U::*)(), U::member*) {\ return true;\ }\ public:\ static const bool value has##memberT(nullptr);\ }; HAS_NON_STATIC_AND_NON_CONST_MEMBER_EX1(void, sort) // 判断容器是否可以使用 std::sort templatetypename Container constexpr bool can_use_std_sort std::is_base_of_v std::random_access_iterator_tag, typename std::iterator_traitstypename Container::iterator::iterator_category ; //容器内容去重 templatetypename Container, typename Compare void deduplicateContainer(Container container, Compare comp) { if constexpr (can_use_std_sortContainer) { std::sort(container.begin(), container.end(), comp); auto it std::unique(container.begin(), container.end()); container.erase(it, container.end()); } else if constexpr (has_non_static_member_ex1_sortContainer::value){ container.sort(comp); auto it std::unique(container.begin(), container.end()); container.erase(it, container.end()); } else { static_assert(false, Container not support sort!!!); } } } // namespace util3.求文件的sha值3.1.在vcpkg中安装openssl和asio库//安装asio和openssl vcpkg install asio openssl:x64-windows //在cmake引用 cmake_minimum_required(VERSION 3.16) project(file_hash) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) find_package(asio CONFIG REQUIRED) find_package(OpenSSL REQUIRED) add_executable(file_hash main.cpp) target_link_libraries(file_hash PRIVATE asio::asio OpenSSL::Crypto)3.2.同步读取文件求sha值std::string calc_sha256_sync(const std::string path) { std::ifstream f(path, std::ios::binary); if (!f) return ; SHA256_CTX ctx; SHA256_Init(ctx); const size_t BUF_SIZE 2*1024 * 1024; std::vectorchar buf(BUF_SIZE); while (true) { f.read(buf.data(), buf.size()); auto read_len f.gcount(); if (read_len 0) { SHA256_Update(ctx, buf.data(), read_len); } if (!f) break; } unsigned char h[SHA256_DIGEST_LENGTH]; SHA256_Final(h, ctx); char hexbuf[SHA256_DIGEST_LENGTH * 2 1]{}; for (int i 0;i SHA256_DIGEST_LENGTH;i) sprintf(hexbuf i * 2, %02x, h[i]); return std::string(hexbuf); }3.3.优化:用内存映射方式求sha值#pragma once #include windows.h #include openssl/evp.h #include string #include iostream namespace { constexpr char hex_lut2[] 0123456789abcdef; } // Windows原生内存映射计算SHA256 std::string calc_sha256_mmap_win(const std::string file_path) { HANDLE hFile CreateFileA( file_path.c_str(), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, // 顺序访问提示内核预读优化 nullptr ); if (hFile INVALID_HANDLE_VALUE) { std::cerr CreateFile failed\n; return {}; } LARGE_INTEGER file_size{}; if (!GetFileSizeEx(hFile, file_size)) { CloseHandle(hFile); return {}; } HANDLE hMap CreateFileMappingA(hFile, nullptr, PAGE_READONLY, 0, 0, nullptr); if (hMap nullptr) { CloseHandle(hFile); return {}; } // 映射整个文件到内存 const char* p_data static_castconst char*(MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 0)); if (p_data nullptr) { CloseHandle(hMap); CloseHandle(hFile); return {}; } // 哈希计算 EVP_MD_CTX* md_ctx EVP_MD_CTX_new(); EVP_DigestInit_ex(md_ctx, EVP_sha256(), nullptr); EVP_DigestUpdate(md_ctx, p_data, static_castsize_t(file_size.QuadPart)); unsigned char hash_bin[EVP_MAX_MD_SIZE]; unsigned int hash_len 0; EVP_DigestFinal_ex(md_ctx, hash_bin, hash_len); EVP_MD_CTX_free(md_ctx); // 转hex字符串 std::string hash_str; hash_str.resize(hash_len * 2); for (unsigned int i 0; i hash_len; i) { hash_str[i * 2] hex_lut[hash_bin[i] 4]; hash_str[i * 2 1] hex_lut[hash_bin[i] 0x0F]; } // 资源释放必须成对 UnmapViewOfFile(p_data); CloseHandle(hMap); CloseHandle(hFile); return hash_str; }3.4.优化:异步读取文件求sha值#include asio.hpp #include iostream #include vector #include functional #include fstream #include openssl/sha.h namespace { // 编译期十六进制查表比 sprintf 快 3~5 倍 constexpr char hex_lut[] 0123456789abcdef; // 缓冲区大小2MB 大缓冲减少系统调用次数可按场景调整为 256KB/1MB constexpr size_t BUF_SIZE 2 * 1024 * 1024; } std::string asyn_read_file_optimized(const std::string path) { try { asio::io_context io_context; // 优化1改用 stream_file 顺序流读取 // 比 random_access_file 更适合连续读取系统自动预读、无需维护偏移、调度开销更低 asio::stream_file file(io_context, path, asio::stream_file::read_only); SHA256_CTX sha_ctx; SHA256_Init(sha_ctx); std::string hash_result; // 优化2双缓冲流水线核心性能优化 // 重叠「磁盘IO」和「哈希计算」总耗时 max(IO耗时, 计算耗时)而非两者相加 std::vectorchar buf_a(BUF_SIZE); std::vectorchar buf_b(BUF_SIZE); bool use_buf_a true; // 标记当前用于IO的缓冲区 std::functionvoid() read_loop; read_loop []() { // 选择当前IO缓冲区 char* io_buf use_buf_a ? buf_a.data() : buf_b.data(); size_t io_buf_len use_buf_a ? buf_a.size() : buf_b.size(); file.async_read_some(asio::buffer(io_buf, io_buf_len), [, read_loop, io_buf](const asio::error_code ec, size_t bytes_read) { if (ec) { if (ec asio::error::eof) { // 读取结束生成最终哈希 unsigned char hash_bin[SHA256_DIGEST_LENGTH]; SHA256_Final(hash_bin, sha_ctx); //优化4查表法十六进制转换零格式解析开销 hash_result.resize(SHA256_DIGEST_LENGTH * 2); for (int i 0; i SHA256_DIGEST_LENGTH; i) { hash_result[i * 2] hex_lut[hash_bin[i] 4]; hash_result[i * 2 1] hex_lut[hash_bin[i] 0x0F]; } } else { std::cerr read error: ec.message() \n; } return; } // 流水线核心先切换缓冲区、发起下一次IO让磁盘先跑 use_buf_a !use_buf_a; read_loop(); // 异步发起下一块读取内核后台执行立即返回 // 同时计算当前块哈希与「下一块的IO」完全并行 if (bytes_read 0) { SHA256_Update(sha_ctx, io_buf, bytes_read); } }); }; read_loop(); io_context.run(); return hash_result; } catch (const std::exception e) { std::cerr exception: e.what() \n; return {}; } }双缓冲流水线大缓冲区2MB减少系统调用次数降低内核态切换开销。原理原代码是串行流程发起IO → 等待完成 → 计算哈希 → 发起下一次IOIO 和计算完全串行。优化后当前块读完后立刻发起下一块的异步读再回头计算当前块的哈希。磁盘 IO 和 CPU 计算完全重叠总耗时从「IO 总时间 计算总时间」缩短为max(IO总时间, 计算总时间)。收益大文件场景下SSD 环境提升 30%~50%高速存储环境下最高提升近 1 倍。3.5.几种方法性能比较文件 Hash 计算工具Windows用来校验你前面 C 代码的 SHA256 结果Windows 系统自带无需安装优先用和你的 C 代码做比对certutilCMD / PowerShell 都支持# SHA256和你代码一致推荐 certutil -hashfile D:\test.dat SHA256 # MD5 certutil -hashfile D:\test.dat MD5 # SHA1 certutil -hashfile D:\test.dat SHA1支持MD2 MD4 MD5 SHA1 SHA256 SHA384 SHA512测试结果4.求容器的最大最小值/// 通用求容器最大值 templatetypename Container auto container_max(const Container c) { if (c.empty()) throw std::runtime_error(container is empty!); return *std::max_element(c.cbegin(), c.cend()); } /// 通用求容器最小值 templatetypename Container auto container_min(const Container c) { if (c.empty()) throw std::runtime_error(container is empty!); return *std::min_element(c.cbegin(), c.cend()); }5.求容器内元素的平均值// 通用模板支持任意可迭代序列 算术类型元素约束 templatetypename Container auto average(Container cont) - std::enable_if_t std::is_arithmetic_v typename std::iterator_traitsdecltype(std::begin(cont))::value_type, double { // 提取元素真实类型 using ValueType typename std::iterator_traitsdecltype(std::begin(cont))::value_type; // 空容器安全处理避免除以0 const auto size std::size(cont); if (size 0) { return 0.0; } // 累加所有元素的绝对值初始值0.0保证浮点精度 double sumAbs std::accumulate( std::cbegin(cont), std::cend(cont), 0.0, [](double accum, ValueType val) { return accum val; } ); return sumAbs / static_castdouble(size); } // 新增重载专门支持花括号初始化列表 {a,b,c,...} templatetypename T std::enable_if_tstd::is_arithmetic_vT, double average(std::initializer_listT list) { // 直接复用通用版本的计算逻辑代码不重复 return average(list); }调用示例std::vectorint vecInts {1, 2, 100, 333, 444, -1}; auto sumOfInt average(vecInts); std::vectordouble vecDoubles { 1, 2, 100, 333, 444, 2}; auto sumOfDouble average(vecDoubles); int a[] {11, 33,23333, 435, 2211212, 3333, 5555,6666,432,111,233,3,3,33,34 }; auto sumOfInt1 average(a); // 3. std::array 固定数组 std::arrayint, 4 arrayValue { -10, 20, -30, 40 }; std::cout array均值: average(arrayValue) \n; auto sumOfInt2 average({11,22,33,44,56,777,88,99});后续待完。。。
RELATED

相关推荐

【化学实验室|17】HarmonyOS ArkTS 亮暗色与视觉令牌实战:集中颜色、间距和交互状态避免页面割裂

【化学实验室|17】HarmonyOS ArkTS 亮暗色与视觉令牌实战:集中颜色、间距和交互状态避免页面割裂

一个项目拥有 Theme.ets,不等于它已经拥有完整主题系统。真正可维护的主题,需要回答四个问题:颜色表达的是业务语义还是某个十六进制值;浅色与深色是否使用同一组资源名称;系统状态栏、普通 ArkUI 组件和 Canvas 是否能…

📅 2026/10/22 12:46:14
springboot网络安全工具库信息管理系统15898-计算机课程设计/毕业设计

springboot网络安全工具库信息管理系统15898-计算机课程设计/毕业设计

前言 📌博主介绍:一线全栈工程师,毕设实战引路人。技术栈覆盖Java、Python、C#、PHP、Node.js及UniApp跨端开发,擅长多语言项目落地与架构设计。持续分享毕设源码、开题报告、技术选型心得与职场踩坑经验。用工程化思维写代码&am…

📅 2026/10/22 12:46:14
Deep-Live-Cam 实时换脸快速上手:如何三步换出换脸直播与批量换脸视频

Deep-Live-Cam 实时换脸快速上手:如何三步换出换脸直播与批量换脸视频

Deep-Live-Cam 实时换脸快速上手:如何三步换出换脸直播与批量换脸视频 【免费下载链接】Deep-Live-Cam real time face swap and one-click video deepfake with only a single image 项目地址: https://gitcode.com/GitHub_Trending/de/Deep-Live-Cam 视频通…

📅 2026/10/22 12:46:14
MORE NEWS

更多资讯

📰

open-spaces 核心原语精讲:Choice、Score、Noul 三大武器如何搞定 99% 的 AI 判断场景

【免费下载链接】open-spaces Free, open-source alternative to ChatGPT Spaces: a self-hostable AI workspace for shared pages and conversations. 项目地址: https://gitcode.com/gh_mirrors/aw/open-spaces 点击查看 免费下载 open-spaces 是一个围绕 Jev&a…

📰

Qwen3-Next-80B-A3B-Instruct重磅发布:下一代混合架构大模型完全指南

【免费下载链接】Qwen3-Next-80B-A3B-Instruct 项目地址: https://ai.gitcode.com/hf_mirrors/Qwen/Qwen3-Next-80B-A3B-Instruct 点击查看 免费下载 Qwen3-Next-80B-A3B-Instruct 是 Qwen3-Next 系列首发的下一代混合架构大模型:总参数 800 亿&#xf…

📰

Poznote 快速上手:从首次登录到第一篇笔记的新手完整指南

【免费下载链接】poznote Powerful note-taking without the hassle. 项目地址: https://gitcode.com/gh_mirrors/po/poznote 点击查看 免费下载 Poznote 是一款免费、自托管的开源笔记软件,可以看作 Notion、Obsidian、Evernote 的替代品:数…

📰

AIBash:用自然语言生成命令行,提升终端操作效率

1. 命令行效率困境与AIBash的切入点如果你每天有超过两个小时泡在终端里,大概率经历过这样的场景:想批量重命名一批文件,脑子里知道大概要用rename或者for循环,但具体参数顺序、正则写法、边界条件处理,总要愣上几秒甚…

📰

SystemVerilog类与对象核心解析:句柄、继承、多态及工程实践

SV学到现在,类这一块算是真正的分水岭。前面11篇笔记从数据类型、接口、约束随机化一路写过来,到了第12篇,我决定把类与对象这个主题单独拎出来写透。原因很现实:八成的仿真报错,报得莫名其妙,查到最后都跟…

📰

SSM图书管理系统源码实战:从Spring MVC到MyBatis完整整合教程

简介:这套基于SSM(Spring MVC Spring MyBatis)的图书信息管理系统项目包,面向正在学习Java Web框架整合、需要完成课程设计或毕业设计的开发者。项目围绕图书信息管理实现了控制层、业务层和持久层代码,可在MyEclips…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬