简体   繁体   中英

What's the best way to compare two integer arrays and find the first to last difference?

Supposing two integer arrays nums and numsCopy,for example:

int[] nums = {2,5,3,8,6,10}
int[] numsCopy = {2,3,5,6,8,10}

I want to compare thus two arrays and finnd the first and the last different integers and recording their position and then count the length, what's the best way to do that? using java.

You could use two for loops, if both arrays have the same size. One starting at the start one at the end:

int start;
for (start = 0; start < nums.length; start++) {
  if (nums[start] != numsCopy[start])
     break;
}
if (start == nums.length)
  return; // there are no different entries

int end;
for (end = nums.length - 1; end >= 0; end--) {
  if (nums[end] != numsCopy[end])
     break;
}
// the distance of the first to the last entry
int dist = end - start;
// the count of elements in the rang from first to last
int count = dist + 1;

This code would exit early at the return if there are no differences in the two arrays. If there is exactly one difference count would be 1 . In your example the count would be 4 . Generally, count is between 1 and nums.length .

Here is a compact (and possibly more efficient) version using while loops and reducing the number of tests like greybeard suggested in the comments. The result (early exit or value in count ) is exactly the same as in the above more verbose version.

int start = 0;
while (nums[start] == numsCopy[start]) {
  if (++start == nums.length)
     return; // there are no different entries
}
int end = nums.length - 1;
while (nums[end] == numsCopy[end]) end--;
int count = end - start + 1;

The best way is, of course, to use two iterations. As @greybeard mentioned, we'd really like to know what is wrong with using two iterations.

Still, to answer the question, a possible way (by no means the best way), without using two for loops etc, would be to delegate the task to the Java9 stream API:

if (nums.length != numsCopy.length)
   throw new IllegalArgumentException("Arrays are not the same length");

IntPredicate elementsEqual = i -> nums[i] == numsCopy[i];
int first = IntStream.range(0, nums.length)
    .dropWhile(elementsEqual)
    .findFirst()
    .getAsInt();
int last = IntStream.iterate(nums.length - 1, i -> i >= first, i -> i - 1)
    .dropWhile(elementsEqual)
    .findFirst()
    .getAsInt();
int count = last - first + 1;

Throws NoSuchElementException if no differences are found.

If all you wanted was the length of the difference subsequence, you could do this in one stream statement:

long length = IntStream.iterate(nums.length - 1, i -> i >= 0, i -> i - 1)
    .dropWhile(elementsEqual)
    .limit(1)
    .flatMap(end -> IntStream.rangeClosed(0, end))
    .dropWhile(elementsEqual)
    .count();

This returns the length of the required subsequence, or 0 if the arrays match.

1) Get size of 1st array . 2) Get size of 2nd array. 3) Run the loop for the smallest of two. 4) Compare each array store the result.

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