C/C++实现欧几里得距离:从数学原理到性能优化实战
1. 项目概述从“两点之间直线最短”到代码实现“欧几里得距离”这个名字听起来有点学术但它的核心思想简单到我们从小就知道两点之间直线最短。在编程的世界里尤其是在C/C这种追求性能与控制的领域这个看似简单的几何概念却是无数复杂系统的基石。无论是游戏开发中计算角色与目标的距离还是机器学习里KNN算法衡量样本间的相似度甚至是图形学中处理像素位置背后都离不开它的身影。很多新手朋友在接触这个概念时可能会觉得“这不就是套个公式吗”。但真正上手写代码尤其是在追求效率、处理边界情况比如浮点数精度、大数计算时才会发现里面有不少门道。今天我就结合自己这些年踩过的坑来详细拆解一下在C/C中实现欧几里得距离算法的方方面面。我们不止会写出能跑的代码更要写出高效、健壮、易于理解的代码。无论你是正在学习数据结构与算法还是准备应对C面试中的相关八股文或是需要在项目中实际应用这篇文章都能给你提供从原理到实战的完整参考。2. 算法核心原理与数学基础拆解2.1 欧几里得距离的定义与公式推导欧几里得距离也叫欧氏距离它描述的是在欧几里得空间中两点间的“普通”直线距离。这个概念源于古希腊数学家欧几里得的《几何原本》是我们在二维、三维乃至更高维空间中最直观的距离度量方式。在二维平面上给定两个点P1(x1, y1)和P2(x2, y2)它们之间的欧几里得距离d计算公式为d sqrt( (x2 - x1)^2 (y2 - y1)^2 )这个公式本质上就是勾股定理的直接应用。我们把两点在x轴方向的差值看作直角边a在y轴方向的差值看作直角边b那么斜边c即两点间的直线距离就是sqrt(a^2 b^2)。推广到三维空间对于点P1(x1, y1, z1)和P2(x2, y2, z2)公式变为d sqrt( (x2 - x1)^2 (y2 - y1)^2 (z2 - z1)^2 )这可以理解为在二维勾股定理的基础上再加上了z轴方向的维度。对于更一般的n维空间给定两个n维向量A(a1, a2, ..., an)和B(b1, b2, ..., bn)欧几里得距离的通用公式为d sqrt( Σ (ai - bi)^2 )其中求和符号Σ对 i 从 1 到 n。注意这里有一个非常重要的细节。公式中先求差值的平方再求和最后开方。这个顺序不能乱。平方操作确保了距离的非负性距离永远大于等于0并且放大了较大差值的影响求和操作综合了所有维度上的差异开方操作则将这个综合差异映射回原始的“距离”尺度上。2.2 与其他距离度量的对比与选型思考在实际项目中选择哪种距离度量方式往往取决于数据和问题的特性。欧几里得距离虽然常用但并非万能。曼哈顿距离也叫L1距离或城市街区距离。计算公式为各维度坐标差值的绝对值之和d Σ |ai - bi|。想象一下在曼哈顿街区你不能斜穿大楼只能沿着网格状的街道走走过的街区数就是曼哈顿距离。它对数据中的异常值离群点不如欧几里得距离敏感因为绝对值运算不像平方那样会放大大误差的影响。在特征维度物理意义不同或者数据稀疏、存在异常值时曼哈顿距离有时是更好的选择。切比雪夫距离定义为各维度坐标差值的绝对值的最大值d max(|ai - bi|)。它衡量的是“在任意维度上能达到的最大差异”在国际象棋中国王的移动规则可以横、竖、斜走一格所衡量的距离就是切比雪夫距离。常用于棋盘类游戏或需要关注最大差异的场景。余弦相似度它衡量的是两个向量在方向上的差异而非距离。计算公式为向量点积除以模长的乘积。它对向量的绝对大小不敏感只关注方向。在文本分析如TF-IDF向量、推荐系统中非常常用因为我们更关心用户兴趣或文档主题的“方向”是否一致而不是它们的“长度”如用户评分的高低或文档的长短。选型心得如果你的数据各个维度是同质的比如都是长度、都是像素值并且你关心的是“直线最短”这种最直观的几何距离那么欧几里得距离是自然的选择。如果你的数据维度代表不同性质的指标比如年龄、收入、点击次数通常需要先进行标准化或归一化处理再使用欧几里得距离否则量纲大的维度会主导距离的计算结果。3. C/C实现详解从基础到优化3.1 基础实现二维与三维场景我们先从最基础的场景开始。在C/C中我们通常使用double或float类型来存储坐标和距离以处理小数运算。二维距离计算函数#include math.h // 或 cmath for C double euclidean_distance_2d(double x1, double y1, double x2, double y2) { double dx x2 - x1; double dy y2 - y1; return sqrt(dx * dx dy * dy); }三维距离计算函数double euclidean_distance_3d(double x1, double y1, double z1, double x2, double y2, double z2) { double dx x2 - x1; double dy y2 - y1; double dz z2 - z1; return sqrt(dx * dx dy * dy dz * dz); }这两个函数清晰明了直接对应数学公式。这里我特意将差值计算 (dx,dy,dz) 单独提出来而不是直接写在sqrt的参数里。这样做有几个好处1) 代码更易读2) 方便调试可以单独检查每个差值的计算是否正确3) 在某些编译器优化下可能有助于生成更高效的代码。3.2 通用N维实现与数据结构设计对于N维向量我们需要更通用的数据结构。在C中常用数组在C中则可以使用std::vector或std::array。C语言版本使用数组和长度参数#include math.h #include assert.h double euclidean_distance_nd_c(const double* vec_a, const double* vec_b, int dimensions) { assert(vec_a ! NULL vec_b ! NULL); // 防御性编程检查空指针 assert(dimensions 0); // 维度必须为正 double sum_of_squares 0.0; for (int i 0; i dimensions; i) { double diff vec_a[i] - vec_b[i]; sum_of_squares diff * diff; // 累加平方差 } return sqrt(sum_of_squares); } // 使用示例 int main() { double point_a[] {1.0, 2.0, 3.0}; double point_b[] {4.0, 6.0, 8.0}; double dist euclidean_distance_nd_c(point_a, point_b, 3); // dist 应为 sqrt((4-1)^2 (6-2)^2 (8-3)^2) sqrt(91625)sqrt(50)≈7.071 return 0; }C版本使用std::vector更安全便捷#include vector #include cmath #include cassert // 或用 assert.h double euclidean_distance_nd_cpp(const std::vectordouble vec_a, const std::vectordouble vec_b) { assert(vec_a.size() vec_b.size()); // 必须维度相同 assert(!vec_a.empty()); // 避免空向量 double sum_of_squares 0.0; // 使用size_t避免有符号/无符号比较警告使用 const auto 避免拷贝 for (size_t i 0; i vec_a.size(); i) { double diff vec_a[i] - vec_b[i]; sum_of_squares diff * diff; } return std::sqrt(sum_of_squares); } // 使用示例 #include iostream int main() { std::vectordouble p1 {1.0, 2.0, 3.0, 4.0}; // 4维点 std::vectordouble p2 {5.0, 6.0, 7.0, 8.0}; double dist euclidean_distance_nd_cpp(p1, p2); std::cout Distance: dist std::endl; // 输出应为 8.0 return 0; }实操要点维度检查这是最容易出错的地方之一。在C版本中使用assert在调试阶段强制检查两个向量的维度是否一致。在生产代码中你可能需要更优雅的错误处理比如抛出异常 (std::invalid_argument)。循环效率对于性能敏感的场景确保循环是高效的。使用size_t作为索引类型可以避免一些潜在的警告和性能损耗。现代编译器通常能很好地将这种简单循环向量化。浮点数精度double比float精度更高默认推荐使用double。除非是在内存极度受限如嵌入式系统或大规模并行计算如GPU且精度要求不高的场景才考虑float。3.3 性能优化与高级技巧当需要计算海量点对之间的距离时例如在KNN算法或聚类算法中基础的循环实现可能成为瓶颈。以下是一些优化思路1. 循环展开与编译器优化对于固定的小维度如2、3、4维可以手动展开循环消除循环开销。但现代编译器如GCC、Clang、MSVC的/O2或/Ox优化级别在识别到这种简单循环模式后通常会自动进行循环展开和向量化SIMD优化。所以写出清晰、标准的循环往往比晦涩的手动展开更好除非你通过性能分析工具如perf, VTune证实了此处是热点且编译器优化不足。2. 避免不必要的开方运算在很多算法中如KNN找最近邻、聚类判断归属我们实际上只需要比较距离的大小而不需要具体的距离值。因为开方函数sqrt()是一个相对昂贵的操作。我们可以直接比较距离的平方// 比较两个点离原点的距离无需开方 bool is_point_a_closer_squared(const std::vectordouble a, const std::vectordouble b) { double sum_a 0.0, sum_b 0.0; for (size_t i 0; i a.size(); i) { sum_a a[i] * a[i]; sum_b b[i] * b[i]; } return sum_a sum_b; // 比较平方和 }这是一个非常重要的优化技巧在性能关键的代码中经常使用。3. 使用更高效的数学库对于超大规模计算可以考虑使用英特尔MKLMath Kernel Library或Eigen库中的优化线性代数例程。这些库针对特定CPU架构如AVX2, AVX-512进行了高度优化能利用SIMD指令并行计算多个距离。4. 空间换时间——预计算与查表在某些特定场景下如果坐标值是离散的、范围有限的整数比如图像像素坐标0-255的灰度值可以预先计算所有可能差值对应的平方值存储在一个查找表中从而将乘法运算替换为内存访问。这在一些古老的或资源受限的嵌入式系统中可能有用但在现代CPU上由于乘法指令非常快而缓存未命中代价高这种方法不一定总是有效需要实测。4. 浮点数精度问题与数值稳定性实战浮点数计算是欧几里得距离实现中的一个“暗礁”。直接套用公式可能会遇到精度丢失、上溢或下溢的问题。4.1 典型问题大数吃小数与精度丢失考虑两个在空间中距离很远的点它们的坐标值非常大。计算dx*dx dy*dy时dx和dy本身可能已经很大平方后可能超过double类型能精确表示的范围约1e308导致上溢结果为无穷大 (inf)。另一种情况是“大数吃小数”。当两个点非常接近时dx和dy非常小。在计算dx*dx dy*dy时如果两个平方项的数量级相差巨大较小的那个在相加时可能会因为精度限制而被“忽略”导致开方后的距离精度不足。4.2 解决方案使用更稳定的数学公式一个经典的稳定计算方法是先对坐标进行平移减去一个公共的参考点比如第一个点的坐标但这在计算两点距离时不太适用。对于欧氏距离一个更鲁棒的方法是使用hypot函数。C标准库和C的cmath提供了hypot函数用于计算直角三角形的斜边长度sqrt(x^2 y^2)它在设计时就考虑了数值稳定性会避免中间计算过程的溢出或下溢。#include cmath // 更稳定的二维距离计算 double stable_distance_2d(double x1, double y1, double x2, double y2) { return std::hypot(x2 - x1, y2 - y1); } // C17 起还有三个参数的 std::hypot用于三维 double stable_distance_3d(double x1, double y1, double z1, double x2, double y2, double z2) { return std::hypot(x2 - x1, y2 - y1, z2 - z1); }对于高维情况虽然没有直接的hypot但我们可以借鉴其思想或者使用一些数值线性代数库中的范数计算函数如Eigen::VectorXd::norm()它们内部也实现了稳定的算法。实操心得在大多数应用场景下直接使用sqrt(dx*dx dy*dy)没有问题。但是如果你在处理科学计算、图形学或金融数据坐标范围跨度极大或对精度要求极高那么从一开始就养成使用hypot或类似稳定函数的习惯是很有必要的。这属于一种“防御性编程”用微小的性能代价hypot比直接计算略慢换取代码的健壮性。5. 实际应用场景与代码集成示例理解了原理和实现我们来看看它如何融入真实的项目。这里我举两个典型的例子。5.1 场景一K-最近邻算法中的距离计算KNN算法的核心就是找距离最近的K个样本。下面是一个极度简化的KNN分类函数片段展示了距离计算如何被集成#include vector #include cmath #include algorithm struct DataPoint { std::vectordouble features; int label; }; int knn_predict(const std::vectorDataPoint training_data, const std::vectordouble query_point, int k) { // 1. 计算查询点到所有训练点的距离 std::vectorstd::pairdouble, int distances; // (距离, 训练数据索引) for (size_t i 0; i training_data.size(); i) { double dist euclidean_distance_nd_cpp(query_point, training_data[i].features); distances.emplace_back(dist, i); } // 2. 按距离排序取前K个 std::sort(distances.begin(), distances.end(), [](const auto a, const auto b) { return a.first b.first; }); // 3. 统计前K个最近邻的标签 std::unordered_mapint, int label_counts; for (int i 0; i k i distances.size(); i) { int label training_data[distances[i].second].label; label_counts[label]; } // 4. 返回出现次数最多的标签 // ... (寻找最大计数的代码) }优化提示在这个场景中我们其实不需要真实的距离值来进行排序只需要相对大小。因此可以将euclidean_distance_nd_cpp函数修改为返回距离的平方并在排序比较函数中使用平方距离进行比较从而省去所有sqrt调用这是KNN实现中一个关键的优化点。5.2 场景二游戏开发中的距离判断在2D或3D游戏中判断角色是否进入怪物攻击范围、拾取物品等都需要距离计算。// 一个简单的3D游戏实体类 class GameEntity { public: double x, y, z; // 世界坐标 double attack_range; bool is_within_attack_range(const GameEntity target) const { double dx target.x - this-x; double dy target.y - this-y; double dz target.z - this-z; // 比较距离平方与攻击范围平方避免开方 double squared_dist dx*dx dy*dy dz*dz; double squared_range attack_range * attack_range; return squared_dist squared_range; } // 更精确的距离获取例如用于UI显示 double get_distance_to(const GameEntity target) const { return std::hypot(target.x - x, target.y - y, target.z - z); } };游戏开发心得在游戏的主循环中is_within_attack_range这类函数可能每帧被调用成千上万次。因此使用平方距离进行比较是标准做法。get_distance_to这种需要真实距离的函数则用于不频繁调用的地方如更新HUD显示。同时在大型游戏世界中还会使用空间分割数据结构如四叉树、八叉树、BVH来快速剔除明显不在范围内的实体避免进行不必要的距离计算。6. 常见问题、调试技巧与代码测试6.1 常见编译与链接问题**undefined reference tosqrt‘** 这是新手最常见的问题。在C/C中sqrt等数学函数定义在数学库libm 中。编译时需要显式链接该库。GCC/Clang在编译命令末尾加上-lm。例如gcc -o program program.c -lmMSVC (Visual Studio)通常会自动链接数学库。如果遇到问题在项目属性中确保链接了legacy_stdio_definitions.lib等新版本VS通常不需要。精度输出问题使用printf或cout输出double时默认精度可能不够。可以使用printf(“%.10f\n”, distance);或cout setprecision(10) distance endl;来指定输出的小数位数。6.2 单元测试与边界条件验证编写健壮的代码离不开测试。以下是一些应该测试的边界情况零距离两个点完全相同距离应为0.0。assert(euclidean_distance_nd_cpp({1,2,3}, {1,2,3}) 0.0);负坐标距离应该总是非负的与坐标正负无关。double d euclidean_distance_nd_cpp({-1, -2}, {3, 4}); assert(d 0);大数/小数测试坐标值极大或极小时是否发生上溢或下溢结果是否合理。维度不匹配测试传入不同维度向量时你的函数是否能正确处理断言失败或抛出异常。与简单案例的手算结果对比例如(0,0)到(3,4)的距离应为5.0。你可以使用如Google Test、Catch2等单元测试框架来组织这些测试用例。6.3 调试技巧当距离值不对劲时如果计算出的距离明显错误可以按以下步骤排查打印中间变量在函数内部打印出dx,dy, 平方和sum_of_squares看是哪一步计算出了问题。检查输入数据确保传入的坐标数组或向量没有越界访问数据被正确初始化。检查维度再三确认两个点的维度是相同的。使用调试器在IDE如VSCode配置好C调试环境、CLion、Visual Studio中设置断点单步执行观察变量值的变化。简化问题尝试用最基础的二维函数计算一个已知答案的例子先排除高维或数据结构带来的复杂性。最后分享一个我个人的小习惯在实现像欧几里得距离这样的基础数学函数时我总会写一个简单的、硬编码的测试用例放在函数实现的附近或者放在一个独立的测试文件中。这能在未来代码修改时第一时间给你反馈避免因为一些“微小”的改动而引入难以察觉的错误。基础工具的可靠性是构建复杂系统信心的第一步。

相关新闻

ComfyUI-WanVideoWrapper:如何构建下一代AI视频生成工作流

ComfyUI-WanVideoWrapper:如何构建下一代AI视频生成工作流

ComfyUI-WanVideoWrapper:如何构建下一代AI视频生成工作流 【免费下载链接】ComfyUI-WanVideoWrapper 项目地址: https://gitcode.com/GitHub_Trending/co/ComfyUI-WanVideoWrapper ComfyUI-WanVideoWrapper是一个专为WanVideo系列模型设计的ComfyUI自定义节…

2026/7/28 14:43:15阅读更多 →
Python作业-2

Python作业-2

设计一个程序,帮助小学生练习10以内的加法 详情: - 随机生成加法题目; - 学生查看题目并输入答案; - 判别学生答题是否正确? - 退出时, 统计学生答题总数,正确数量及正确率(保留两位小数点); import random n0 t0 f0 while 2>1: n1 arandom.randint(…

2026/7/28 14:43:15阅读更多 →
STM32土壤监测系统:精准农业的实时数据解决方案

STM32土壤监测系统:精准农业的实时数据解决方案

1. 项目背景与核心需求现代农业正经历从传统经验种植向数据驱动型精准农业的转型过程。土壤作为作物生长的直接载体,其质量参数直接影响农作物产量和品质。传统人工采样检测方式存在时效性差、成本高、覆盖面有限等痛点,而基于STM32的土壤质量监测系统正…

2026/7/28 14:43:15阅读更多 →
告别手忙脚乱!这款FF14智能钓鱼辅助工具让你轻松成为钓鱼大师

告别手忙脚乱!这款FF14智能钓鱼辅助工具让你轻松成为钓鱼大师

告别手忙脚乱!这款FF14智能钓鱼辅助工具让你轻松成为钓鱼大师 【免费下载链接】Fishers-Intuition 渔人的直感,最终幻想14钓鱼计时器 项目地址: https://gitcode.com/gh_mirrors/fi/Fishers-Intuition 还在为错过幻海流最佳时机而懊恼吗&#xff…

2026/7/28 15:49:39阅读更多 →
从图形化编程到Python海龟绘图:四色旋转方块阵实战解析

从图形化编程到Python海龟绘图:四色旋转方块阵实战解析

1. 项目概述:当图形化编程遇上Python海龟如果你接触过图形化编程,比如Scratch或者Mind,那你一定对拖拽积木、控制角色移动、绘制图案这些操作不陌生。它们直观、有趣,是很多编程启蒙课程的首选。但当我们想画一个更复杂、更炫酷的…

2026/7/28 15:49:39阅读更多 →
存储型XSS窃取Cookie攻防全解析:从漏洞利用到纵深防御实践

存储型XSS窃取Cookie攻防全解析:从漏洞利用到纵深防御实践

1. 项目概述:一次关于Web安全核心威胁的深度对话最近在复盘一些内部渗透测试和应急响应的案例,发现一个老生常谈却又屡禁不止的问题——存储型跨站脚本攻击。特别是当它被用来窃取用户会话凭证时,其危害性往往被低估。很多人知道XSS&#xff…

2026/7/28 15:49:39阅读更多 →
Android studio  CodeGlance 右侧预览功能消失

Android studio CodeGlance 右侧预览功能消失

如果是确认已经安装CodeGlance了,后来不知道什么原因右侧不显示预览的话,快捷键:CTRLSHIFTG,这个是打开关闭的快捷键。当然如果你不想使用快捷键来打开关闭的话,也可以去Android studio中 file --> settings-->搜…

2026/7/28 15:49:39阅读更多 →
EdgeRemover终极指南:如何彻底卸载Windows 10/11的Microsoft Edge浏览器

EdgeRemover终极指南:如何彻底卸载Windows 10/11的Microsoft Edge浏览器

EdgeRemover终极指南:如何彻底卸载Windows 10/11的Microsoft Edge浏览器 【免费下载链接】EdgeRemover A PowerShell script that correctly uninstalls or reinstalls Microsoft Edge on Windows 10 & 11. 项目地址: https://gitcode.com/gh_mirrors/ed/Edge…

2026/7/28 15:49:39阅读更多 →
基于FastAPI搭建PDF翻译微服务:从架构到部署(附完整代码)

基于FastAPI搭建PDF翻译微服务:从架构到部署(附完整代码)

前言 最近在做一个企业内部文档中台项目,需要把PDF翻译能力封装成微服务,供前端、IM机器人、定时任务等多个消费者调用。调研了一圈,发现市面上的方案要么太重(直接部署商业软件),要么太轻(纯脚…

2026/7/28 15:47:39阅读更多 →
覆盖国产 + 海外 + 开源模型,OpenClaw 2.7.9 Windows/Mac 双端部署详解

覆盖国产 + 海外 + 开源模型,OpenClaw 2.7.9 Windows/Mac 双端部署详解

🔹 工具基础介绍 OpenClaw 是开源生态中一款实用性较强的本地智能工具,凭借本地离线运行、可视化图形操作和任务自动化三大核心特性,赢得了众多用户的青睐。与普通在线对话AI工具不同,它属于能够直接操控本机软硬件的智能数字员工…

2026/7/28 4:06:39阅读更多 →
伺服阀焊完微漏毁整机?精密激光焊接三关锁住高压

伺服阀焊完微漏毁整机?精密激光焊接三关锁住高压

所谓液压伺服阀体的精密激光焊接,是用激光束对阀座壳体(通常为不锈钢或铝合金)进行密封焊接,使阀体在21-35MPa的高压液压油或压缩气体中长期运行而不发生介质泄漏。液压伺服阀是高端液压系统的"大脑"。从航空航天飞行控…

2026/7/28 2:08:06阅读更多 →
D2DX:三步实现《暗黑破坏神2》高清宽屏体验的终极指南

D2DX:三步实现《暗黑破坏神2》高清宽屏体验的终极指南

D2DX:三步实现《暗黑破坏神2》高清宽屏体验的终极指南 【免费下载链接】d2dx D2DX is a complete solution to make Diablo II run well on modern PCs, with high fps and better resolutions. 项目地址: https://gitcode.com/gh_mirrors/d2/d2dx 你是否还在…

2026/7/28 1:38:28阅读更多 →
告别臃肿!3步让你的暗影精灵笔记本重获新生

告别臃肿!3步让你的暗影精灵笔记本重获新生

告别臃肿!3步让你的暗影精灵笔记本重获新生 【免费下载链接】OmenSuperHub Control Omen laptop performance, fan speeds, and keyboard lighting, and unlock power limits. 项目地址: https://gitcode.com/gh_mirrors/om/OmenSuperHub 你是否也曾为官方Om…

2026/7/28 0:00:29阅读更多 →
RAG必踩坑!财报法规检索不准?这款开源工具让答案浮出水面,准确率飙升98.7%!

RAG必踩坑!财报法规检索不准?这款开源工具让答案浮出水面,准确率飙升98.7%!

做 RAG 的人应该都踩过这个致命的坑:把几百页的财报、法规、技术手册扔给向量库,问一个具体问题,搜出来的全是沾边但没用的内容 —— 关键信息要么被硬切块拆碎了,要么藏在几十条结果的最下面。语义相似≠真正相关,这个…

2026/7/28 0:00:29阅读更多 →
抖音视频文案提取工具全指南:免费2026版、手机App、在线工具一网打尽

抖音视频文案提取工具全指南:免费2026版、手机App、在线工具一网打尽

2026年做短视频运营,从抖音上扒文案早就不是偷偷抄笔记的事了。我刚开始做内容的时候,每天刷半小时抖音,手动把爆款视频的口播敲进备忘录,一条2分钟的视频得花十来分钟,碰到语速快的还要反复回听。后来试了一圈工具&am…

2026/7/28 0:00:29阅读更多 →
YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

如果你在部署 YOLOv8 时,发现推理速度只有可怜的 1-2 FPS,而别人的演示视频却能跑到 30 FPS 以上,那么问题很可能不在模型本身,而在于你的整个处理链路。很多开发者拿到一个训练好的 YOLOv8 模型后,会直接使用官方示例…

2026/7/27 16:57:54阅读更多 →
Coze与Dify对比指南:低代码AI应用开发从入门到实战

Coze与Dify对比指南:低代码AI应用开发从入门到实战

1. 从零到一:为什么你需要了解 Coze 和 Dify?如果你对 AI 应用开发感兴趣,但一看到“大模型”、“智能体”、“工作流”这些词就头疼,觉得门槛太高,那这篇文章就是为你准备的。很多开发者,包括我自己&#…

2026/7/28 3:17:03阅读更多 →
AI生图工具怎么选?2026年6月版实测对比

AI生图工具怎么选?2026年6月版实测对比

做自媒体的朋友应该都有体会:配图一直是个让人头疼的问题。2026年,AI生图工具已经非常成熟了,但工具太多反而不知道怎么选。以下是截至2026年6月我对主流AI生图工具的实测对比。Midjourney V8.1:速度之王2026年6月11日&#xff0c…

2026/7/28 2:35:58阅读更多 →