模块比较字符

时间:2012-07-08 20:28:27

标签: java math ascii string-comparison

这似乎是一个非常简单的问题,但是在互联网上关于它的报道却很少,而且我很难自己正确地实现它。在Java中对ASCII字符实现模块化比较函数的最佳方法是什么,这样比较“包围”字母表的结尾?我想将它用于可以在任意位置对整个字母进行分区的“between”函数,并在被询问'y'是否在'x'和'b'之间时正确返回“true”。

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

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

然而,这是基于Java的内置模块化算术函数,它没有相应的对比。即使我使用普通的int,我也无法询问Java是否< b< c mod 26(如果a = 24,b = 25,c = 1则返回true。)

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

3 个答案:

答案 0 :(得分: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.

答案 1 :(得分:1)

所以你的问题是:字符c_1c_2之间是字符c_3,前提是字母表包裹?

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

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

... 23 24 25 26 1 2 3 4

变为:

... 23 24 25 26 27 28 29 30

然后你就可以像往常那样进行算术运算。

修改:根据MvG的评论更新算法。确实存在多种情况:“24到2之间是25?”而且“在24和2之间是1?”。在后一种情况下,你还需要检查(1 + 26)是否介于24和(2 + 26)之间 - 这是因为字符'a'确实在'x'和'b'之间。

答案 2 :(得分: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执行所需的模数。