这个函数(为方便起见用C编写,但这对问题并不重要)决定数组的大小我相信它可以转换成一个if-else链,甚至可以转换成一个等式,但我还不够聪明,看不出如何。(我试着写下明显的“如果其他”链,但却陷入了困境。)
// 0 <= from <= 0x10FFFF
// 1 <= len <= 0x10FFFF
unsigned int size_for_block(unsigned int from, unsigned int len)
{
unsigned int size = 0;
for (unsigned int i = 0; i < len; i++) {
unsigned int point = from + i;
if (0xD800 <= point && point <= 0xDFFF)
;
else if (point <= 0xFFFF)
size += 1;
else
size += 2;
}
return size;
}
如果有一种通用的、独特的技术将这种循环转换为算术,那将是一个理想的答案如果不这样做,这个例子的解决方案就可以了。
最佳答案
首先,为了简单起见:
to = from + len - 1
我认为它可以分成三个方程,每个“部分”。即:
答:
0
至0xD800 - 1
B:
0xD800
至0xDFFF
C:
0xDFFF + 1
到无穷远A和C部分是“值”2,B部分是1除非我曲解了你的代码——只有两个部分吗?
因此,将每个截面值乘以它所属范围的长度:
答:
if (from < 0xD800) size += 2 * min((0xD800 - 1) - from + 1, len)
假设
min
是一个返回其参数中较小值的函数:范围是“from
到节末尾,或len
,以较短者为准”范围是(结束-开始+1)。B:
if (to > 0xD800) size += 1 * min(0xDFFF - 0xD800 + 1, to - D800 + 1)
这里的逻辑是相似的:“完整的部分,或者部分的开始到
to
,以较短者为准”。C:
if (to > 0xDFFF + 1) size += 2 * (to - (0xDFFF + 1) + 1)
这更简单,因为没有终点:只需从开始计数到
to
。我不知道这对电脑是否更有效不过,这对我的大脑来说肯定没那么有效。