【问题标题】:Incremented by a value x but it gets incremented by value x-1按值 x 递增,但按 x-1 值递增
【发布时间】:2017-03-05 13:32:07
【问题描述】:

我正在实现一个算法,当用户给出输入字符串时,字符串中的每个字符(如果是字母表)都应该按给定的值递增(这里是旋转器)。我正在使用此代码 2 小时,但无法弄清楚为什么当我按值 rotator 递增时,它会按 rotator-1 递增。

public class Solution {

public static void main(String[] args) {
    /* Enter your code here. Read input from STDIN. Print output to STDOUT. Your class should be named Solution. */
    Scanner in = new Scanner(System.in);
    int length = in.nextInt();
    String input = in.next();
    int nextvalue = 0;
    int temp = 0;
    char array[] = input.toCharArray();
    int rotator =  in.nextInt();
    for(int i = 0; i < length; i++){
        if((array[i] >= 'a' && array[i] <= 'z') || (array[i] >= 'A' && array[i] <= 'Z')){
            nextvalue = (int)array[i] + rotator;
            array[i] = (char)nextvalue;

            if((int)array[i] > (int)'z'){
                temp = (int)array[i] - (int)'z';
                nextvalue = (int)'a' + temp -1;
                array[i] = (char)nextvalue;
             }
            else if((int)array[i] > (int)'Z'){
                temp = (int)array[i] - (int)'Z';
                nextvalue = (int)'Z' + temp -1;
                array[i] = (char)nextvalue;
            }
        }
    }
    System.out.println(array);
    }
}

如果有两个if语句要处理(溢出条件)如果字母> z或> Z,则首先在里面。现在,如果我删除这两个语句,除了溢出条件之外的所有内容都会正确打印

(无溢出条件) 样品 I/P:

11

中产阶级

2

样品 O/P:

okffng-Qwv|

(有溢出条件) 样品 I/P:

11

中产阶级

2

样品 O/P:

njeemf-Qvub

为什么会这样?我还检查了 inner if condition 中使用 print 语句,因为只有一个溢出条件,它只为这个输入执行一次。

感谢您的帮助/建议。谢谢。

【问题讨论】:

  • char array[] 语法不正确。你的意思是char[] array
  • 反对者请发表评论!
  • @Gooz 实际上,我认为这是合法的语法,虽然可能不是您在 Oracle 官方网站上看到的。
  • @Gooz 在 java 中都有效
  • @TimBiegeleisen,哦,真的,我真的不知道。

标签: java if-statement increment


【解决方案1】:

我认为处理溢出情况的最简单方法是使用模运算符让字符环绕任意次数以到达当前逻辑位置。像这样的东西应该可以工作:

for (int i=0; i < length; i++) {
    if (array[i] >= 'a' && array[i] <= 'z') {
        int currDiff = (int)array[i] - (int)'a';
        int newPos = (int)'a' + ((rotator + currDiff) % 26);
        array[i] = (char)newPos;
    }
    else if (array[i] >= 'A' && array[i] <= 'Z') {
        int currDiff = (int)array[i] - (int)'A';
        int newPos = (int)'A' + ((rotator + currDiff) % 26);
        array[i] = (char)newPos;
    }
}

我使用输入字符串abcdefgrotator 值51 测试了这段代码,它返回zabcdef。这是意料之中的,因为我们比两轮完整的轮换少了一步。因此,a 在一个完整的旋转后降落在z 上,随后的字符也随之而来。

请注意,这里有一种更好的处理字符位置演算的方法,但此答案与您在原始问题中的处理方式保持一致。

最后说明:

模数运算符% 返回在它之前继续它的数字除法的余数。在我上面给出的解决方案中,我采用有效旋转器 % 26。这里,有效旋转器是字母与 aA 的当前距离 plus 无论我们想要多少步旋转。通过取这个数字 mod 26,我们总是会得到一个介于 0 和 25 之间的数字。因此,我们总是会从 aA 采取 0 到 25 步,这是您在程序中想要的行为。

【讨论】:

  • @minigeek 有错误,再试一次
  • 在让我再次检查您的编辑之前给出了一些错误的操作
  • 做到了。你能补充一点解释这 % 的东西是如何工作的吗
【解决方案2】:

因为您在循环中修改了两次。

for(int i = 0; i < length; i++){
    if((array[i] >= 'a' && array[i] <= 'z') || (array[i] >= 'A' && array[i] <= 'Z')){
        nextvalue = (int)array[i] + rotator;
        array[i] = (char)nextvalue; //<-- modifies from m to o

        if((int)array[i] > (int)'z'){
            temp = (int)array[i] - (int)'z';
            nextvalue = (int)'a' + temp -1;
            array[i] = (char)nextvalue;
         }
        else if((int)array[i] > (int)'Z'){
            temp = (int)array[i] - (int)'Z';
            nextvalue = (int)'Z' + temp -1;
            array[i] = (char)nextvalue; //<--modifies again from o to n
        }
    }
}

【讨论】:

  • 即在if条件下但是。只有当溢出发生时,才应该改变,我错了吗?
  • 当您的第一个输入 (11) 大于字符串中的字符数时,它总是会溢出。为什么不只使用 char 数组的长度?那么你就不会有任何溢出。
【解决方案3】:

错误在这一行:

if ((int) array[i] > (int) 'Z') {

您必须记住,小写字母出现在大写字母“之后”:“Z”由 90 表示,(例如)“j”由 106 表示(更多信息请参阅this)。 'Q' 不受此错误影响的原因是因为它也是一个大写字母,因此具有比'Z' 更小的十进制表示。

要解决此问题,您必须将上面的代码行替换为类似以下内容的内容:

if ((int) array[i] > (int) 'Z' && (int) array[i] <= (int) 'Z' + rotator) {

【讨论】:

【解决方案4】:

代替

nextvalue = (int)'Z' + temp -1;

不应该

nextvalue = (int)'A' + temp -1;

【讨论】: