java如何在不使用任何内置方法或函数的情况下,以恒定时间(O(1))获取字母表(126)中字符的数值/位置? 3 月,4 周 Questions & Answers 412 如何在不使用任何内置方法或函数且不考虑字符大小写的情况下,以恒定时间(O(1))获取字母表(1-26)中字符的数值/位置
# 1 楼答案 我们可以得到它们的ASCII值,然后从起始字符ASCII(a - 97, A - 65)中减去 char ch = 'a'; if(ch >=65 && ch <= 90)//if capital letter System.out.println((int)ch - 65); else if(ch >=97 && ch <= 122)//if small letters System.out.println((int)ch - 97);
# 2 楼答案 严格来说,在C/C++中不可能实现可移植性,因为无法保证字符的顺序 这就是说,对于一个连续的序列,Char - 'a'和Char - 'A'显然给你一个小写或大写字母的位置,你可以写 Ord= 'a' <= Char && Char <= 'z' ? Char - 'a' : ('A' <= Char && Char <= 'Z' ? Char - 'A' : -1); 如果你想让效率高于安全性,可以利用ASCII码的二进制表示形式,并使用无分支 #define ToUpper(Char) (Char | 0x20) Ord= ToUpper(Char) - 'a'; (非字母字符的输出被视为未指定) 与规范相反,这些代码片段返回[0, 25]范围内的位置,对于基于零的索引语言来说更自然
# 3 楼答案 如果你的编译器支持二进制文字,你可以使用 int value = 0b00011111 & character; 如果没有,则可以使用31而不是0b00011111,因为它们是等效的 int value = 31 & character; 或者如果你想用十六进制 int value = 0x1F & character; 还是八进制 int value = 037 & character; 您可以使用任何方式来表示值31 这是因为在ASCII中,小写值的前缀是011,大写值是010,然后是1-26的二进制等效值。 通过使用0001111的位掩码和and操作数,我们将3个最高有效位转换为零。这给我们留下了00001到11010,1到26
# 4 楼答案 添加到very good (self) answer of Charles Staal 假设ascii编码,下面的代码可以工作。更新自Yves Daoust的善意评论 int Get1BasedIndex(char ch) { return ( ch | ('a' ^ 'A') ) - 'a' + 1; } 这将使字符大写并更改索引 然而,更具可读性的解决方案是: int Get1BasedIndex(char ch) { return ('a' <= ch && ch <= 'z') ? ch - 'a' + 1 : ch - 'A' + 1; } 还有一种解决方案是恒定时间,但需要一些额外的内存: static int cha[256]; static void init() { int code = -1; fill_n (&cha[0], &cha[256], code); code = 1; for(char s = 'a', l = 'A'; s <= 'z'; ++s, ++l) { cha[s] = cha[l] = code++; } } int Get1BasedIndex(char ch) { return cha[ch]; }
# 1 楼答案
我们可以得到它们的ASCII值,然后从起始字符ASCII(
a - 97, A - 65
)中减去# 2 楼答案
严格来说,在C/C++中不可能实现可移植性,因为无法保证字符的顺序
这就是说,对于一个连续的序列,
Char - 'a'
和Char - 'A'
显然给你一个小写或大写字母的位置,你可以写如果你想让效率高于安全性,可以利用ASCII码的二进制表示形式,并使用无分支
(非字母字符的输出被视为未指定)
与规范相反,这些代码片段返回
[0, 25]
范围内的位置,对于基于零的索引语言来说更自然# 3 楼答案
如果你的编译器支持二进制文字,你可以使用
如果没有,则可以使用31而不是0b00011111,因为它们是等效的
或者如果你想用十六进制
还是八进制
您可以使用任何方式来表示值31
这是因为在ASCII中,小写值的前缀是011,大写值是010,然后是1-26的二进制等效值。 通过使用0001111的位掩码和and操作数,我们将3个最高有效位转换为零。这给我们留下了00001到11010,1到26
# 4 楼答案
添加到very good (self) answer of Charles Staal
假设ascii编码,下面的代码可以工作。更新自Yves Daoust的善意评论
这将使字符大写并更改索引
然而,更具可读性的解决方案是:
还有一种解决方案是恒定时间,但需要一些额外的内存: