【问题标题】:Adding two character arrays and storing the result as characters in another char array in Java在Java中添加两个字符数组并将结果作为字符存储在另一个字符数组中
【发布时间】:2014-11-22 21:10:35
【问题描述】:

我想添加两个字符数组并将结果作为字符存储在另一个字符数组中。 加法涉及从两个数组中添加两个英文字母作为操作数。 加法会将 z 环绕回 a 。

例如。 输入:Array1 和 Array 2,输出为 Array 3

数组 1 :abcdeyz

数组 2 :aaaaaaa

数组 3 :bcdefza

下面是我的代码的一部分,它不起作用。 请提出任何更改

    int c = 0;

    char array3[] = new char[count] ;    

for(int a=0;a<array1.length;a++)
    {
        for(int b=0;b<array2.length;b++)
        {
            int temp = (array1[a] + array2[b]) % 26 ;
            array3[c] = (char) temp ; 
            c++ ;
        }
    }

【问题讨论】:

  • 那么把 ascii 值加起来?
  • @jgr208 不,它更像ROT13,但范围可变。
  • 那不会把两个数组加在一起
  • @Tom 是的,但是根据 2 个数组的输入,每个字符都会被替换为不同的字符
  • 为什么要使用 2 个嵌套循环?您只需要一个for 循环,如果“密钥”不够长,则应复制它,直到足够长为止。

标签: java arrays ascii modulo


【解决方案1】:

提示 - 'a' 的值不是 0

问题出在一线 -

int temp = (array1[a] + array2[b]) % 26 ;

这是修改后的代码(假设所有字符都是小写)-

    int c = 0;

    char array3[] = new char[count] ;    

for(int a=0;a<array1.length;a++)
    {
        for(int b=0;b<array2.length;b++)
        {
            int temp = ( (array1[a]-'a') + (array2[b]-'a')) % 26 ;
            array3[c] = (char) (temp+'a') ; 
            c++ ;
        }
    }

【讨论】:

  • 如果 array1[a]='x' 和 array2[b]='z' 怎么办?我们需要 %26 保持在 [0,26) 范围内,根据 OP 的声明“加法会将 z 环绕回 a”
  • 你能帮我个忙吗?试试这段代码,看看你是否得到了 array3 的所需输出。我想,你会得到的第一件事是ArrayIndexOutOfBoundsException
  • 取决于计数。根据 OP,它将是 array1.length*array2.length。你可以在这里查看 - ideone.com/r20S1F
  • 但这不是 OP 想要的输出。
  • @Tom 是的,它给出了一个 ArrayIndexOutOfBoundsException
【解决方案2】:

使用 26 取模是处理 a-z 到 1-26 转换的好方法。这样,您的程序就可以不知道实际的 ASCII 字符数。

其他一些问题:

  1. 不区分大小写。我建议在处理之前将您的字母转换为小写。
  2. 特殊情况的处理。如果您的数组长度不同怎么办?或者如果他们的角色不是 信?

下面的代码是处理这些事情的一种方法。

public static int letterToInt(char letter) {
    char letterToConvert = Character.toLowerCase(letter);
    int codeForA = (int)'a';
    int numberOfLetter = ((int)letterToConvert) - codeForA + 1;
    if(numberOfLetter < 1 || numberOfLetter > 26) {
        throw new IllegalArgumentException(
                "The character argument can only be a-z or A-Z, but was '" + letter + "'");
    }
    return numberOfLetter;
}

public static char intToLetter(int number) {
    if(number < 1 || number > 26) {
        throw new IllegalArgumentException(
                "The number can only be 1-26, but was " + number);
    }
    int codeForA = (int)'a';
    return (char)(codeForA + number - 1);
}

public static char addLetters(char letter1, char letter2) {
    int numberFromAddedLetters =
            letterToInt(letter1) + letterToInt(letter2);
    int modulo = numberFromAddedLetters % 26;
    return intToLetter(modulo == 0 ? 26 : modulo);
}

public static char[] addLetterArrays(char[] array1, char[] array2) {
    char[] longerArray;
    char[] shorterArray;
    if(array1.length >= array2.length) {
        longerArray = array1;
        shorterArray = array2;
    } else {
        longerArray = array2;
        shorterArray = array1;
    }

    char[] addedLetters = new char[longerArray.length];
    for(int index = 0; index < longerArray.length; index++) {
        if(index < shorterArray.length) {
            addedLetters[index] = addLetters(longerArray[index], shorterArray[index]);
        } else {
            addedLetters[index] = longerArray[index];
        }
    }
    return addedLetters;
}

// Test it out
public static void main(String[] args) {
    char[] letters1 = "abcdeyz".toCharArray();
    char[] letters2 = "aaaaaaa".toCharArray();
    // Prints [b, c, d, e, f, z, a]
    System.out.println(Arrays.toString(addLetterArrays(letters1, letters2)));
}

【讨论】:

    【解决方案3】:

    这是一个关于如何执行此操作的固定且有效的示例:

    public static void main(String[] args) {
        char[] array1 = new char[] {'a', 'b', 'c', 'd', 'e', 'y', 'z'};
        char[] array2 = new char[] {'a', 'a', 'a', 'a', 'a', 'a', 'a'};
        char[] array3 = new char[array1.length];
    
        for (int i = 0; i < array1.length; i++) {
          array3[i] = toChar((toInt(array1[i]) + toInt(array2[i]) + 1) % 26);
        }
        System.out.println(Arrays.toString(array3));
    }
    
    private static int toInt(char chr) {
        return chr - 'a';
    }
    
    private static char toChar(int value) {
        return (char)(value + 'a');
    }
    

    这里有一些想法需要注意(- 'a' 部分除外,其他答案已经提到):

    • 您只需要一个循环即可完成此任务。如果您使用 2 个嵌套循环,那么您将添加 array1 的每个字母和 array2 的每个字母。你会得到一个更大的array3。而且由于结果与预期的结果不符... :)

    • + 1 中的 + 1 是必需的,因为 char - 'a' 是“从零开始的”。因此'a' + 'b' 将导致'b' 而不是'c',因为您将计算0 + 1(如果您通过添加'a' 将其“转换”回char,则将是'b')(我希望这个表达是可以理解的:D)

    • array2 必须至少与 'array1' 具有相同的长度。它几乎就像padding in cryptography。 (我省略了填充部分以保持这段代码简短)

    【讨论】:

    • 能否请您扩展您的第一点:如果我使用 2 个循环,我需要一个更大的数组 3
    • 假设您有这些数组:{'a', 'b'}{'c', 'd'}array3 的长度也应该是 2。但是array3 将是{'a+c', 'a+d', 'b+c', 'b+d'},因为您将array1 的每个条目与array2每个 条目相加,而不仅仅是相应的条目(即在同一索引上)。
    • :所以如果我有 2 个大数组使用两个循环可能是不正确的方法,因为我的第三个数组的大小会非常大
    • 结果会出错。就像上面的例子:预期:{'d', 'f'},实际:{'d', 'e', 'e', 'f'}
    • 非常感谢@tom:你的代码终于正确地得到了密文
    【解决方案4】:

    这样写:

    int temp = (((array1[a] - 'a') + (array2[b] - 'a')) % 26) + 'a';
    

    这样做的目的是将两个字符转换为它们在字母表中的相应位置,对字母表中的字符数进行加法运算以获得环绕效果,然后转换回正确的 ascii 值。

    请注意,您的代码有问题,因为您的行为好像字母表的 ascii 值是它们各自在字母表中的位置,这是不正确的。

    【讨论】:

      猜你喜欢
      • 2017-10-18
      • 1970-01-01
      • 1970-01-01
      • 2017-04-08
      • 2013-06-22
      • 1970-01-01
      • 2018-06-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多