将字母转换为它们在字母表中的相对位置(C#)

3

我一段时间前找到了这段代码,我想理解它是如何工作的)

int index = (int)c % 32 +1;

我曾成功地使用这条代码将字母转换为数字 - 例如,a变成1(A也是)。请有人能解释一下这是如何发生的吗?(我稍微研究了一下32进制,但并不更明智)另外,是否有一种简单的方法将整数转换回字母?


那个 + 1 在那里实际上没有意义。有了它,'a''A' 将给你 2(而不是 1)。想法可能是将其设置为 - 1,以获得从零开始的索引。 - poke
请注意术语。您似乎专注于英文字母表。在英语写作中使用了一些不属于英文字母表的“字母”,当然还有其他字母表。通常,我们将术语“字母表”留给语言学家和语言机构。Unicode试图提供完整的书写系统,由各种类别的字符组成。它将某些字符分类为“字母”——在1,112,064个“字符”中有93,455个字母。LINQPad Instant Share - Tom Blodget
3个回答

6
所有字母都有整数代码。例如,'a' 的代码为 97。因此,(int)'a' 是 97。所以 (int)'a' % 32 是 1。因为英文字母少于 32 个,所以一切都能正确转换。同时,巧合的是,大小写字母之间的差异为 32(例如,'a' - 'A' == 32)。因此,这也适用于大写字母。
要将整数转换回字母,您还可以使用整数代码。例如,'A' + index - 1 将给出字母表中编号为 index 的大写字母。同样地,'a' + index - 1 将给出相同编号的小写字母。
请参考 ASCII 码表,了解符号的整数代码。

32在aA之间的差异并不是唯一(必要)的巧合。更重要的是,65和97都是模32余1。 - poke
是的,我的意思是它们都对32取模为1,因为它们之间的差值为32。 - justanothercoder
这真的只是巧合吗?我知道早期计算机程序员在某些方面非常具有前瞻性,但我不禁想知道他们是否也是有意为之。 - C Bauer
这样做的一个可能目的与位运算有关。32是2^5,因此要加或减32,可以设置或取消位。这是非常快速的操作。 - justanothercoder

4
这一切都归因于字符(和字符串)的实际表示方式。每个字符都使用代码点进行编码,它们只是数字。许多代码点组成了一个代码页,它本质上是将数字映射到实际字符的表格。
忽略Unicode附带的大型代码页,现在您只需查看ASCII即可,这是前128个代码点的编码。在那里,您可以看到标准的大写字母从数字65开始,而小写字母从数字97开始。
因此,在您的公式中,如果我们假设c始终是来自字母表的字符,我们知道它的数值在65和90之间,或在97和122之间。因此,取字符'A''a',我们分别有数值65或97。
所有剩下的就是巧合,即大写字母和小写字母表以32的差异开始,而65模32为1。这使得(int)c % 32给出了字母表中从1开始的字符索引。

2
这是因为.NET的默认字符编码是UTF-16。对于字母,它会与ASCII匹配。如果你查看ASCII表,你会发现大写字母A-Z的编码从位置65开始,小写字母a-z的编码从位置97开始。你提供的公式将返回大写或小写'A'为1,大写或小写'B'为2等。根据该表,您还可以将介于1和26之间的整数转换为所选大小写的字符:对于大写字母,将整数加上64,对于小写字母,加上96。

一个 .NET 字符串是一系列 UTF-16 代码单元的计数序列。UTF-8 是流和文件的默认编码。 - Tom Blodget

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接