将数组与其镜像进行比较

时间:2013-05-21 12:39:46

标签: java arrays loops

好的,所以我有一个方法需要接受一个满是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)并且我难以理解为什么循环我已经返回我想要的东西。任何帮助将不胜感激。

4 个答案:

答案 0 :(得分:5)

好吧,我很好奇......

问题在于:

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

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

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 :(得分:2)

tempAtempB之间的逻辑有问题:

在第一个循环(orignal)的每次迭代中,您选择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], maxCount将为2

     

对于输入[7,1,2,9,2,1,7], maxCount为7

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

代码中的问题是外循环(aFor循环)没有得到每个序列集的评估,即在迭代-2中你只检查第一组大小2([7,1])和进一步设置([1,2],[2,9] ..)永远不会被比较,所以你总是得到maxCount = 1,因为之前的比赛。

答案 2 :(得分:1)

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

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;
}

答案 3 :(得分:0)

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;
}