3

举个简单的例子,假设我们正在检查 a 是否char c是字母数字:

if (48 <= c && c <= 57 ||
    65 <= c && c <= 90 ||
    97 <= c && c <= 122)
{
    // ...
}

6 操作确认

但是,不存在连续函数f(c)使得f(c) > 0表示字母数字字节值,而< 0表示其余部分?我认为至少一个:12 次多项式,“适合” 12 个点,在 x 轴上上下摆动;但也许也存在一个更小次数的函数,甚至是非多项式。这样的公式将“简化”以下操作:

if (f(c) > 0)
{
    // ...
}

这有艺术术语吗?(想到“折叠”这个词,但它不会产生任何相关的搜索结果——只有 Haskell 的折叠概念。)似乎只要我们可以将一组操作的 codomain 映射到一个足够精细的 codomain粒度,我们可以得到这样的“折叠”。那么,我的问题是:“折叠”可以节省时间吗?或者是否有一些守恒原则迫使计算“折叠”的成本匹配(甚至超过)计算原始“粗略”操作的成本。

4

3 回答 3

6

多项式与 x 轴相交 6 次,即它有 6 个实根,因此 6 次多项式就足够了。

f(c) = -(c-48)*(c-57)*(c-65)*(c-90)*(c-97)*(c-122)

在此处输入图像描述

这当然会浪费时间,做 5 次乘法比 5 次逻辑运算慢得多。此外,&&并且||经常短路,您不需要全部进行。

于 2013-05-09T19:44:52.970 回答
4

在您的特定情况下,最佳形式是:

unsigned u = c;
if (u-48<10 || (u|32)-97<26)

当然,这并不能按照您希望的方式解决问题,但是相同的概念(即(1)将针对一个范围的两个比较转换为一个无符号减法和比较,以及(2)使用按位或组合多个范围检查,其长度是相同的,并且对齐匹配这样)通常可以推广到其他情况。

于 2013-05-09T22:13:04.170 回答
2

是否有某种原因该功能isalnum()不能满足您的需求?别忘了#include <ctype.h>

于 2013-05-09T19:44:20.190 回答