为什么在递归调用中索引字符串会产生不同的结果?
Why does indexing a string inside of a recursive call yield a different result?
在我天真的 edit-distance finder 实现中,我必须检查两个字符串的最后一个字符是否匹配:
ulong editDistance(const string a, const string b) {
if (a.length == 0)
return b.length;
if (b.length == 0)
return a.length;
const auto delt = a[$ - 1] == b[$ - 1] ? 0 : 1;
import std.algorithm : min;
return min(
editDistance(a[0 .. $ - 1], b[0 .. $ - 1]) + delt,
editDistance(a, b[0 .. $ - 1]) + 1,
editDistance(a[0 .. $ - 1], b) + 1
);
}
这会产生预期的结果,但是如果我用它的定义替换 delt
它总是 returns 1 在非空字符串上:
ulong editDistance(const string a, const string b) {
if (a.length == 0)
return b.length;
if (b.length == 0)
return a.length;
//const auto delt = a[$ - 1] == b[$ - 1] ? 0 : 1;
import std.algorithm : min;
return min(
editDistance(a[0 .. $ - 1], b[0 .. $ - 1]) + a[$ - 1] == b[$ - 1] ? 0 : 1, //delt,
editDistance(a, b[0 .. $ - 1]) + 1,
editDistance(a[0 .. $ - 1], b) + 1
);
}
为什么这个结果会改变?
运算符的优先级与您期望的不同。在const auto delt = a[$ - 1] == b[$ - 1] ? 0 : 1;
中没有歧义,在editDistance(a[0 .. $ - 1], b[0 .. $ - 1]) + a[$ - 1] == b[$ - 1] ? 0 : 1
中却有(貌似)。
简化:
auto tmp = editDistance2(a[0..$-1], b[0..$-1]);
return min(tmp + a[$-1] == b[$-1] ? 0 : 1),
//...
);
这里有趣的部分被解析为(tmp + a[$-1]) == b[$-1] ? 0 : 1
,tmp + a[$-1]
不等于b[$-1]
。解决办法是把东西包在括号里:
editDistance(a[0 .. $ - 1], b[0 .. $ - 1]) + (a[$ - 1] == b[$ - 1] ? 0 : 1)
在我天真的 edit-distance finder 实现中,我必须检查两个字符串的最后一个字符是否匹配:
ulong editDistance(const string a, const string b) {
if (a.length == 0)
return b.length;
if (b.length == 0)
return a.length;
const auto delt = a[$ - 1] == b[$ - 1] ? 0 : 1;
import std.algorithm : min;
return min(
editDistance(a[0 .. $ - 1], b[0 .. $ - 1]) + delt,
editDistance(a, b[0 .. $ - 1]) + 1,
editDistance(a[0 .. $ - 1], b) + 1
);
}
这会产生预期的结果,但是如果我用它的定义替换 delt
它总是 returns 1 在非空字符串上:
ulong editDistance(const string a, const string b) {
if (a.length == 0)
return b.length;
if (b.length == 0)
return a.length;
//const auto delt = a[$ - 1] == b[$ - 1] ? 0 : 1;
import std.algorithm : min;
return min(
editDistance(a[0 .. $ - 1], b[0 .. $ - 1]) + a[$ - 1] == b[$ - 1] ? 0 : 1, //delt,
editDistance(a, b[0 .. $ - 1]) + 1,
editDistance(a[0 .. $ - 1], b) + 1
);
}
为什么这个结果会改变?
运算符的优先级与您期望的不同。在const auto delt = a[$ - 1] == b[$ - 1] ? 0 : 1;
中没有歧义,在editDistance(a[0 .. $ - 1], b[0 .. $ - 1]) + a[$ - 1] == b[$ - 1] ? 0 : 1
中却有(貌似)。
简化:
auto tmp = editDistance2(a[0..$-1], b[0..$-1]);
return min(tmp + a[$-1] == b[$-1] ? 0 : 1),
//...
);
这里有趣的部分被解析为(tmp + a[$-1]) == b[$-1] ? 0 : 1
,tmp + a[$-1]
不等于b[$-1]
。解决办法是把东西包在括号里:
editDistance(a[0 .. $ - 1], b[0 .. $ - 1]) + (a[$ - 1] == b[$ - 1] ? 0 : 1)