【问题标题】:Looping over parallel arrays that are different lengths遍历不同长度的并行数组
【发布时间】:2015-02-21 19:28:50
【问题描述】:

我是初学者,这是我的第一个问题。我已经在网上搜索了答案,但我做不到。你们任何人可以提供的任何帮助都会让我脸上露出笑容!

我正在编写一个同时循环两个数组的程序。这些是从用户定义的字符串转换而来的字符数组,因此它们的长度可能不同。以下是我的代码中当前的设置方式。

for(int i = 0; i < charArray1.length; i++)
    {   
        char keyChar = charArray1[i];
        char messageChar = charArray2[i];
    }

考虑上面的例子。可以这么说:

charArray1 = {'A','B','C','D'} 和
charArray2 = {'1','2','3','4','5','6','7}

目前这种情况会抛出一个超出范围的异常,这是应该的。我希望看到发生的是一个循环返回到 charArray1 的开头,而另一个循环继续到 charArray2 的结尾。

如果我要打印它,它可能如下所示。

A1、B2、C3、D4、A5、B6、C7

任何帮助将不胜感激。我已经有一段时间了。

【问题讨论】:

  • 在 for 循环中创建一个 for 循环

标签: java loops parallel-arrays


【解决方案1】:

您希望循环中的迭代次数是最长数组的长度。你可以通过Math.max(charArray1.length, charArray2.length);得到它

然后你想在索引i 处获取数组项,但是当它超过数组的长度时循环。您可以通过arr[i%arr.length] 获得。

组合:

int m = Math.max(charArray1.length, charArray2.length);
for (int i = 0; i < m; ++i) {
    char keyChar = charArray1[i%charArray1.length];
    char messageChar charArray2[i%charArray2.length];
}

编辑:

模运算符 (a%b) 为您提供将 a 除以 b 后的剩余量。

例如,b=3:

a   a%3
0    0
1    1
2    2
3    0
4    1
5    2
...

您可以看到,如果ab 是具有a&gt;=0b&gt;0 的整数,那么a%b 将始终在范围内:

0 <= a%b < b

这是长度为b的数组的可接受索引范围。

【讨论】:

  • 效果很好,谢谢!虽然追求理解这些东西而不是仅仅粘贴它,你能向我解释一下模运算符在这里做什么吗?再次感谢。
  • 告诉你除法运算的剩余部分
  • 感谢 jgr208。我明白它的作用。我试图了解它在代码中的用途以及它与通过数组索引的迭代的关系。
  • @dmitrivada 我在帖子中添加了一些关于模数在做什么的信息。
  • @khelwood 感谢您的更新。我用模数做了数学运算,立即明白了它在做什么。我不确定我是否会自己解决这个问题。非常感谢你们所有人帮助我解决了这个问题。
【解决方案2】:

有第二个变量j 来跟踪较小数组的索引。

//charArray1 = {'A','B','C','D'}
//charArray2 = {'1','2','3','4','5','6','7}

int j = 0;
for(int i = 0; i < charArray2.length; i++)
{   
    char keyChar = charArray1[j];

    j++;
    if(j == charArray1.length)
        j=0;

    char messageChar = charArray2[i];
}

这是test run

这假定charArray2 将始终是最长的数组。如果您认为这不是真的,请在进入循环之前进行检查

您也可以使用 % 运算符做一些花哨的事情,但我更喜欢这种方法,因为它对新手来说更易读。

【讨论】:

    【解决方案3】:

    您希望循环到最长数组的末尾,因此您选择两个长度中的最大值作为循环的退出条件。

    然后,您可以通过对索引使用模数同时循环两个数组,这样您就不会抛出索引越界异常:当i 变得更大时,数组的边界, 使用模 (%) 运算符,您可以从该数组的开头重新开始。

    for (int i = 0; i < Math.max(charArray1.length,charArray2.length); i++) {
       char keyChar = charArray1[i%charArray1.length];
       char messageChar = charArray2[i%charArray2.length];
    }
    

    这将独立于哪个数组更大。

    【讨论】:

      【解决方案4】:

      没有规定说for 循环的索引必须是任何数组的索引。这是一种使用计数器和两个单独的数组索引的方法:

      int totalCount = Math.max(charArray1.length, charArray2.length);
      int i = 0;
      int j = 0;
      for (int count = 0; count < totalCount; count++) {
           char keyChar = charArray1[i++];
           if (i >= charArray1.length) {
               i = 0;
           }
           char messageChar = charArray2[j++];
           if (j >= charArray2.length) {
               j = 0;
           }
           // code that outputs the two characters, or whatever
      }
      

      无论哪个数组更长,这都会起作用,并且不依赖于%

      【讨论】:

        【解决方案5】:

        你需要做的是在 for 循环中创建一个 for 循环

        for(int i = 0; i < charArray2.length; i++)
            {   
                for(int j = 0; j < charArray1.length; j++)
                    char keyChar = charArray1[j];
                char messageChar = charArray2[i];
            }
        

        这会在内部循环上循环,一旦到达终点,就会再次循环,直到到达charArray2 的结尾,此时外部 for 循环将终止,从而退出循环。还有其他方法可以做到这一点,但这是一种让像您这样的初学者更容易理解的方法。

        然后,如果您希望它打印出 A1,B2,... 完全没有两个 for 循环,您可以执行以下操作。如果您要处理大量数字,则两个 for 循环不是最好的方法,因为我认为两个 for 循环是 n^2if 语句只是像 1 这样的常量。

        int max = Math.max(charArray1.length, charArray2.length);
        int j = 0;
        for (int i = 0; i < max; ++i) {
            if(j==charArray1.length)
              j = 0;
            else
              j++;
            char keyChar = charArray1[j];
            char messageChar charArray2[i];
        }
        

        【讨论】:

        • @Cyber​​neticTwerkGuruOrc 这是怎么回事?它在数组内部循环小数组,然后在完成后用下一个字母再次循环数组。所以它将是 A1 A2 A3....B1 B2... 等等
        • @khelwood 你对答案有什么不明白的地方?
        • 他想要 A1 B2 C3 D4 A5 B6 D7。你误解了这个问题。
        • @ajb 他说可能看起来像那样。然后他继续说他想要两个循环。
        • 不,不,不,不。他认为他想要两个循环,但他是一个初学者,试图做一些与通常教科书不同的事情,所以他不知道该怎么做是可以理解的。我们应该向他展示如何产生他想要的输出(在一个循环中),而不是向他展示如何产生完全不同的输出。
        猜你喜欢
        • 2016-07-23
        • 2016-02-23
        • 2016-04-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-01-20
        • 2021-04-23
        • 1970-01-01
        相关资源
        最近更新 更多