简体   繁体   中英

Comparing an array to its mirror

Okay so I have a method that needs to take in an array full of ints , then check it against it's mirror to see what the largest mirror is that it matches to. So for example I have array [7, 1, 2, 9, 7, 2, 1] , the largest array that it can match is 2, being matched at [1, 2] .

Right now I have it broken into 3 methods. One that accepts the array, another that reverses the array and returns it ( mirrorArray ). and the 3rd being counting the size of the array that matches( groupCount ). Here is what I have so far:

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

It is failing in the 3rd method somewhere (returning a 1 instead of a 2) and I'm stumped why the loops I have arnt returning what I want. Any help would be greatly appreciated.

Alright I was curious...

Here's the problem:

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

You are always comparing tempB to the first subArray of length groupSize of aFor. Change that line to

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

and it should work.

EDIT Keep the failure cases coming.. Seems an issue with the increment location of 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++;
  }

This is not the most efficient, and it might be a fun exercise to optimize. One starting approach would be to start groupSize at aFor.length and decrement. As soon as maxCount is assigned, you can early return.

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

What was happening is that Arrays.copyOfRange was filling out of bounds numbers with zeroes. I also added the early exit opt I mentioned earlier. There are probably more optimizations that can be done

Your logic between tempA and tempB has issue:

In each iteration of first loop (orignal) you pick 0->groupSize set of values and compare exactly with all similar sizes sequence in reverse array, so first iteration is

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)

Similarly in all other iteration no sequence match would be found due to your input dataset.

Now if you change your input to [7, 1, 2, 9, 7, 1, 7], maxCount would be 2

And for input [7, 1, 2, 9, 2, 1, 7], maxCount is 7

But that's due to nature of your input and issue in your code.

The problem in code is outer loop ( aFor loop) doesn't gets evaluated for each sequence set ie in iteration-2 you check only first set of size 2 ([7,1]) and further sets ([1,2],[2,9]..) are never compared so you always get maxCount=1 due to previous match.

I know that this might seem irrelevant to the question, but I tried to make the tests without creating new arrays (inplace comparaison), I hope this helps:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM