【问题标题】:Comparing an array to its mirror将阵列与其镜像进行比较
【发布时间】:2013-05-21 12:39:45
【问题描述】:

好的,所以我有一个方法需要接收一个充满ints 的数组,然后对照它的镜像检查它,看看它匹配的最大镜像是什么。所以例如我有数组[7, 1, 2, 9, 7, 2, 1],它可以匹配的最大数组是2,在[1, 2]匹配。

现在我将它分为 3 种方法。一个接受数组,另一个反转数组并返回它 (mirrorArray)。第三个是计算匹配数组的大小(groupCount)。这是我目前所拥有的:

public int maxMirror(int[] nums) {
  int[] revArray = mirrorArray(nums);

  return groupCount(nums, revArray);
}

private int[] mirrorArray(int[] nums) {
  int[] newArray = new int[nums.length];

  for (int i = nums.length-1, j = 0; i >= 0; i--, j++) {
    newArray[j] = nums[i];
  }

  return newArray;
}

private int groupCount(int[] aFor, int[] bRev) {
  int maxCount = 0;
  int groupSize = 1;

  //get aFor value
  for (int i = 0; i < aFor.length; i++) {
    int[] tempA = Arrays.copyOfRange(aFor, 0, groupSize);

    //loop through bRev and check for matches
    for (int j = 0; j < bRev.length; j++) {
      int[] tempB = Arrays.copyOfRange(bRev, j, j+groupSize);

      if (Arrays.equals(tempA, tempB)) {
        maxCount = tempA.length;
      }
    }

    groupSize++;
  }
  return maxCount;
}

它在某处的第 3 种方法中失败(返回 1 而不是 2),我很困惑为什么我的循环没有返回我想要的东西。任何帮助将不胜感激。

【问题讨论】:

  • 它是怎么失败的?你得到一个例外?返回值是否错误?
  • 返回的值有误。例如,如果它遍历上面示例中的数组,它返回一个 1,而它应该是一个 2。
  • groupCount方法被调用时aForbRev中的值是什么?
  • aFor 是最初传入的正向数组,bRev 是相反的。在mirrorArray 方法中计算。
  • 检查我的答案,我在没有分配新数组的情况下解决了问题(性能大幅提升!),希望对您有所帮助:)

标签: java arrays loops


【解决方案1】:

好吧,我很好奇……

问题来了:

int[] tempA = Arrays.copyOfRange(aFor, 0, groupSize);

您总是将 tempB 与 aFor 的长度为 groupSize 的第一个子数组进行比较。将该行更改为

int[] tempA = Arrays.copyOfRange(aFor, i, i + groupSize);

它应该可以工作。

编辑让失败案例不断出现。似乎 groupSize 的增量位置存在问题

   while (groupSize < aFor.length) {
      //get aFor value
      for (int i = 0; i < aFor.length; i++) {
        int[] tempA = Arrays.copyOfRange(aFor, i, i + groupSize);

        //loop through bRev and check for matches
        for (int j = 0; j < bRev.length; j++) {
          int[] tempB = Arrays.copyOfRange(bRev, j, j+groupSize);

          if (Arrays.equals(tempA, tempB)) {
            maxCount = groupSize;
          }
        }
      }
      groupSize++;
  }

这不是最有效的,它可能是一个有趣的优化练习。一种起始方法是从aFor.length 开始 groupSize 并递减。只要分配了maxCount,就可以提前返回。

编辑 2

 int groupSize = aFor.length;
 while (groupSize >= 0) {
      //get aFor value
      for (int i = 0; i <= aFor.length - groupSize; i++) { // note this change
        int[] tempA = Arrays.copyOfRange(aFor, i, i + groupSize);

        //loop through bRev and check for matches
        for (int j = 0; j <= bRev.length - groupSize; j++) { // note this change
          int[] tempB = Arrays.copyOfRange(bRev, j, j+groupSize);

          if (Arrays.equals(tempA, tempB)) {
            return groupSize;
          }
        }
      }
      groupSize--;
  }
  return 1;
}

发生的事情是 Arrays.copyOfRange 用零填充超出范围的数字。我还添加了我之前提到的提前退出选项。可能还有更多的优化可以做

【讨论】:

  • +1 有同样的想法,但我不确定aFor 的镜像是bRev
  • 是的,我之前尝试过,当我补充说我仍然从一些数组中得到错误时。例如,数组[1,2,1,4] 返回一个 2,而它应该是 3。
  • 这太接近了。我将你的 while 更改为 while (groupsize &lt;= aFor.length),因为它不会到某些数组的末尾,但我仍然收到错误:(。例如,[1,2,3,8,9,3,2,1] 返回 8,而它应该是 3。跨度>
  • 感觉自己很痛苦,但是,这只会带来更多错误。 (但不同)在[1, 2, 1, 4] 这样的数组上,当应该返回 3 时,我将返回 2 =[
  • 没关系,我明白了!我将循环更改为groupsize &gt;= 0 & i &lt;= .. & j &lt;= ..,一切顺利!谢谢你帮了大忙!
【解决方案2】:

tempAtempB 之间的逻辑有问题:

在第一个循环(原始)的每次迭代中,您选择 0->groupSize 值集并与反向数组中所有相似大小的序列进行精确比较,因此第一次迭代是

Orignal array (aFor) : [7, 1, 2, 9, 7, 2, 1]
Reverse array (bRev) : [1, 2, 7, 9, 2, 1, 7]
Iteration-1:
tempA=> [7]
tempB=> [1],[2],[7]...
maxCount = 1; (in first iteration, multiple single value matche)

Iteration-2:
tempA=> [7,1]
tempB=> [1,2],[2,7]...
maxCount = 1; (no match of [7,1], maxCount continues from first iteration)

类似地,在所有其他迭代中,由于您的输入数据集,不会找到序列匹配。

现在,如果您将输入更改为 [7, 1, 2, 9, 7, 1, 7],ma​​xCount 将为 2

对于输入 [7, 1, 2, 9, 2, 1, 7],ma​​xCount 为 7

但这是由于您输入的性质和代码中的问题。

代码中的问题是外循环(aFor 循环)不会针对每个序列集进行评估,即在第 2 次迭代中,您只检查大小为 2 的第一组([7,1])和更多组([ 1,2],[2,9]..) 永远不会进行比较,因此由于之前的匹配,您总是得到 maxCount=1。

【讨论】:

    【解决方案3】:

    我知道这似乎与问题无关,但我尝试在不创建新数组的情况下进行测试(就地比较),我希望这会有所帮助:

    public static int getMaxMirrorSub(int[] arr) {
        for (int eqLength = arr.length; eqLength >= 0; eqLength--) {
            for (int arrayStart = 0; arrayStart < arr.length; arrayStart++) {
                for (int mirrorStart = arr.length - 1; mirrorStart >= eqLength - 1; mirrorStart--) {
                    int indexArray = arrayStart, indexMirror = mirrorStart;
                    while(indexArray < arr.length 
                            && indexMirror >= 0 
                            && arr[indexArray] == arr[indexMirror]){
    
                        indexArray++; indexMirror--;
                    }
    
                    if (indexArray - arrayStart == eqLength)
                        return eqLength;
                }
            }
        }
        return 0;
    }
    

    【讨论】:

      【解决方案4】:
      public int maxMirror(int[] nums) {
        int[] reverse = null;
        int max = 0;
        for(int i = 0; i < nums.length; i++) {
           for(int k = 0; k < nums.length; k++) {
              if(i > k) { 
                } else {
                  reverse = reverseSection(nums, i, k);
                  if(searchFor(reverse, nums)) {
                     if(reverse.length > max) { max = reverse.length; }
                  }
               }
           }
        }
      
        return max;
      }
      
      public int[] reverseSection(int[] nums, int begin, int end) {
         int[] nArray = new int[end - begin + 1];
         int numbs = end - begin;
         for(int i = begin; i <= end; i++) {
            nArray[numbs] = nums[i];
            numbs--;
         }
         return nArray;
      }
      
      public boolean searchFor(int[] reverse, int[] nums) {
          int index = 0;
          boolean check = false;
              for(int i = 0; i < nums.length; i++) {
              if(nums[i] == reverse[index]) {
                  index++;
      
                  if(index >= reverse.length) {
                      return true;
                  }
              } else {
                  index = 0;
              }
          }
          return false;
      }
      

      【讨论】:

      • 除了提供代码外,还请包含一些文字来解释您的答案的作用以及它如何解决 OP 的问题。这将有助于未来有相同或类似问题的读者使用您的答案。
      猜你喜欢
      • 2017-08-05
      • 1970-01-01
      • 2019-05-23
      • 1970-01-01
      • 1970-01-01
      • 2017-08-15
      • 2020-12-30
      • 1970-01-01
      • 2021-01-15
      相关资源
      最近更新 更多