曼哈顿距离是两个等长向量间的度量,需对每维绝对差求和;c++中需手写循环或用std::inner_product配合lambda实现,注意类型匹配、边界检查与溢出风险。

曼哈顿距离的定义和C++计算逻辑
曼哈顿距离不是数组自身的属性,而是两个**等长向量(或点)之间**的度量。如果你有一维 std::vector<int></int> 或原生数组 int arr[N],要算曼哈顿距离,必须提供两个同长度的数组——比如点 A 和点 B,然后对每个维度求绝对差再累加。
常见误解是“单个数组的曼哈顿距离”,这在数学上无定义;实际场景中,你真正需要的是:
- 两个坐标点(如二维平面上的
(x1, y1)和(x2, y2)) - 两个高维特征向量(如图像直方图、嵌入向量)
- 两个字符串的字符频次数组(需先对齐维度)
用for循环手动计算最稳妥
标准库没有现成的“数组曼哈顿距离”函数,手写循环清晰、可控、无依赖。注意边界检查和整型溢出风险。
示例:计算两个 std::vector<double></double> 的曼哈顿距离
double manhattan_distance(const std::vector<double>& a, const std::vector<double>& b) {
if (a.size() != b.size()) throw std::invalid_argument("vectors must have same size");
double sum = 0.0;
for (size_t i = 0; i <ul>
<li>用 <code>std::abs</code> 而非 <code>abs</code>,避免整型/浮点重载歧义</li>
<li>参数用 <code>const std::vector&</code> 避免拷贝开销</li>
<li>如果确定不会越界且追求极致性能,可改用原生指针 + <code>size_t</code> 长度传入</li>
</ul>
<h3>用std::inner_product配合lambda(C++17+)</h3>
<p>想一行写完又不牺牲可读性?<code>std::inner_product</code> 可以复用,但需自定义二元操作符——它默认做点积,我们要的是“绝对差之和”。</p>
<pre class="brush:php;toolbar:false;">#include <numeric>
#include <cmath><p>double manhattan_distance(const std::vector<float>& a, const std::vector<float>& b) {
return std::inner_product(a.begin(), a.end(), b.begin(), 0.0f,
std::plus{},
[](float x, float y) { return std::abs(x - y); });
}</float></float></p></cmath></numeric>
- 第5个参数
std::plus{}是累加器(加法),第6个是每对元素的变换操作 - 注意初始值类型必须匹配返回类型(如用
0.0f对应float向量) - 该写法在GCC/Clang下通常能自动向量化,但MSVC优化效果不稳定
常见错误和边界情况
实际编码时最容易栽在这些地方:
- 传入空数组:未检查
a.empty()就访问a[0]→ 段错误 - 混用有符号/无符号类型:比如用
int i = 0; i ,当 <code>vec.size() == 0时size()返回size_t(永远 ≥ 0),导致死循环 - 用
abs处理long long:应改用llabs,否则可能截断 - 浮点数比较误用:曼哈顿距离本身不涉及相等判断,但若后续用于阈值比较(如
dist ),需考虑精度损失
多维坐标(如 struct Point { int x, y; };)建议先展平为一维容器再算,比嵌套循环更易维护和向量化。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











