5

这似乎是一个非常简单的问题,但在互联网上几乎没有关于它的文章,而且我很难自己正确地实现它。在 Java 中对 ASCII 字符实现模块化比较函数的最佳方法是什么,以便比较“环绕”字母表的末尾?我想将它用于“介于”函数中,该函数可以在任意位置分割整个字母表,并在被问及“y”是否在“x”和“b”之间时正确返回“真”。

我已经找到了所有关于字符模运算的问题和答案,所以我知道如何使用这样的代码进行模加法(​​字符移位):

char shifted = (((original - 'a') + 1) % 26) + 'a';

但是,这是基于 Java 内置的模块化算术函数,没有等效的比较。即使我使用的是普通整数,我也无法询问 Java 是否 a < b < c mod 26(如果 a = 24、b = 25 和 c = 1,它应该返回 true)。

所以一般的问题是,在 Java中实现模块化比较操作的最佳方式是什么?如果这是一个太难的问题,是否至少有一种方法可以让这种比较适用于 ASCII 字母表?

4

3 回答 3

2

在循环队列中进行测试A < B < C时,您始终可以假设A <= B并且已经环绕或不环绕。

如果A < B,则没有发生换行。如果有B < C or C < A,则 B 介于 A 和 C 之间。

如果A > B,那么你已经包裹了。如果B < C and C < A,则 B 在 A 和 C 之间。

您需要自己定义如何处理 A==B、B==C 或 A==C。

于 2012-07-08T22:24:47.583 回答
1

所以你的问题是:字符和c_1之间的字符,只要字母环绕?c_2c_3

  • 将每个字符转换为数字(即 , a = 1, b = 2..., z = 26)。在您的示例中,这将c_1 = 'y' = 25介于c_2 = 'x' = 24c_3 = 'b' = 2) 之间。
  • 如果c_3 < c_2,则将 26 添加到c_3。在您的示例中,情况就是这样,因为2 < 24.
  • 我们现在有c_1 = 25,c_2 = 24c_3 = 28
  • 检查是否c_1 >= c_2 && c_1 <= c_3持有。如果是这样,则字符位于两个边界之间。如果不成立,则继续下一步。
  • 添加 26c_1并检查该值是否满足上述检查。如果是这样,则该字符在包装边界内。如果没有,则停止。

在这种方法中,您基本上是在“第二个”字母表中添加 26。所以:

... 23 24 25 26 1 2 3 4

变成:

... 23 24 25 26 27 28 29 30

然后,您可以像往常一样进行算术运算。

编辑:根据 MvG 的评论更新算法。确实有多种情况:“24和2之间是25吗?” 还有“1在24和2之间吗?”。在后一种情况下,您还需要检查 (1 + 26) 是否在 24 和 (2 + 26) 之间 - 这成立,因此字符 'a' 确实介于 'x' 和 'b' 之间。

于 2012-07-08T20:36:35.177 回答
0

根据您的喜好,您可能希望使用模数运算符而不是 if 语句。要在一行中执行比较,请执行以下操作:

public static boolean isStrictlyBetween(char a, char x, char b) {
    // assuming x, a, and b are all the same case (lower or upper).
    return ((x - a + 26) % 26) < ((b - a + 26) % 26);
}

此代码表示如果从 a 到 x 的顺时针距离小于从 a 到 b 的顺时针距离,则返回 true。+26 确保差异表达式的结果是正数(负数的百分比在某些语言中表现得很奇怪)。% 26 执行您想要的模数。

于 2012-07-08T23:01:44.757 回答