Aar*_*rke 7 c c++ strcmp lexicographic
由于我完全不同意的原因,但是"尽管我的反对意见仍在继续判决的权力(反可用性)",我有一个排序例程,它将基本的strcmp()与其名称排序进行比较.它很棒; 很难弄错那个人.但是,在第11个小时,已经确定以数字开头的条目应该在以字母开头的条目之后出现,与ASCII顺序相反.他们引用EBCDIC标准的数字跟随字母,所以先前的假设不是普遍的事实,我没有权力赢得这个论点......但我离题了.
这就是我的问题所在.我用新函数调用nonstd_strcmp替换了对strcmp的所有适当引用,现在需要实现修改以完成排序更改.我使用FreeBSD源作为我的基础:http://freebsd.active-venture.com/FreeBSD-srctree/newsrc/libkern/strncmp.c.html
if (n == 0)
return (0);
do {
if (*s1 != *s2++)
return (*(const unsigned char *)s1 -
*(const unsigned char *)(s2 - 1));
if (*s1++ == 0)
break;
} while (--n != 0);
return (0);
Run Code Online (Sandbox Code Playgroud)
我想我可能需要花一些时间来真正思考它应该如何完成,但我确信我不是唯一一个经历过刚刚释放规范变化的大脑死亡的人.
Mar*_*som 16
您需要做的是为每个角色创建一个订购表.这也是进行不区分大小写的比较的最简单方法.
if (order_table[*s1] != order_table[*s2++])
Run Code Online (Sandbox Code Playgroud)
请注意,可能会对字符进行签名,在这种情况下,表的索引可能会为负数.此代码仅用于签名字符:
int raw_order_table[256];
int * order_table = raw_order_table + 128;
for (int i = -128; i < 128; ++i)
order_table[i] = (i >= '0' && i <= '9') ? i + 256 : toupper(i);
Run Code Online (Sandbox Code Playgroud)
如果你的权力就像我遇到的所有其他权力一样,你可能想让它成为一个选项(即使它被隐藏):
排序:
o字母后面的数字
o数字后的字母
或者更糟糕的是,他们可能会发现他们希望数字按数字排序(例如"A123" 在 "A15"之后),那么它可以是
o字母后面的数字
o数字后的字母
o字母后的智能数字
o智能数字后面的字母
这可以诊断出真正的问题,而不是症状.我打赌他们可能会在第11小时和第59分钟改变主意.
在这种只有大写字母(如注释中的 OP 中提到的)和数字 0-9 的特殊情况下,您也可以省略顺序表,而是将两个不同的字符乘以 4 并比较结果模 256。 ASCII 数字的范围(48 到 57) 不会溢出 8 位 (57 \xc3\x97 4 = 228),但大写字母的范围 (65 到 90) 会溢出 (65 \xc3\x97 4 = 260)。当我们比较模 256 的乘积时,每个字母的值将小于任何数字的值: 90\xc3\x974 % 256 = 104 < 192 = 48\xc3\x974
\n\n代码可能类似于:
\n\nint my_strcmp (const char *s1, const char *s2) {\n for (; *s1 == *s2 && *s1; ++s1, ++s2);\n return (((*(const unsigned char *)s1) * 4) & 0xFF) - \\\n (((*(const unsigned char *)s2) * 4) & 0xFF);\n}\nRun Code Online (Sandbox Code Playgroud)\n\n当然,顺序表解决方案通常更加通用,因为它允许为每个字符定义排序顺序 \xe2\x80\x94 该解决方案仅适用于大写字母与数字的特殊情况。(但例如在微控制器平台上,即使节省表使用的少量内存也可能是一个真正的好处。)
\n