2017-10-24 5 views
-2

例えば、2つの整数配列NUMSとnumsCopyを想定:2つの整数配列を比較し、最初から最後までの違いを見つける最良の方法は何ですか?

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

私は、このように二つの配列を比較して、最初と最後の異なる整数とその位置を記録しfinndして、長さをカウントする、最良の方法は何ですそれをするには? javaを使用しています。

+1

何の長さを数えますか? – dasblinkenlight

+1

2つのポインタを持つ1つの反復を使用して、開始時に開始するものと終了時に始まるもの(両方とも互いに向かい合って動きます)と、どちらか一方で停止します:a) 、またはb)一度それらが交差したら、 – alfasin

+0

@ dasblinkenlightは最も長い差の長さを数えます。たとえば、最初の異なる値は5/3で、位置は1で、最後の差は6/8で長さは4です。 – ReturnHttp402

答えて

0

もちろん、2つの繰り返しを使用することをお勧めします。 @greybeardが述べたように、私たちは本当に2つの繰り返しを使って何が問題なのかを知りたいと思っています。

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; 

例外:まだ

は、2つの forループなどを使用せずに、(決して最善の方法で)質問、可能な方法に答えるために、Java9ストリームAPIへのタスクを委任することです差異がない場合は NoSuchElementExceptionとなります。

あなたが望んでいたすべての差分サブシーケンスの長さだった場合、あなたは1つのストリーム文でこれを行うことができますが:配列が一致した場合

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(); 

これは必要なサブシーケンス、または0の長さを返します。

0

両方の配列が同じサイズの場合、2つのforループを使用できます。開始端に1つから始まるワン:2列に差がない場合には、このコード

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; 

returnで早期に終了します。正確に1つの違いがある場合count1となります。あなたの例では、count4になります。一般に、countは、1nums.lengthの間です。ここ

コンパクト(そしておそらくより効率的な)バージョンループしながら使用してコメントで示唆老いようなテストの数を減らすことです。結果(早期出口またはcountの値)は、上記のより詳細なバージョンとまったく同じです。

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; 
+0

私は 'start == end'になったときに2番目のループを止めたいと思います。ああ、配列インデックスの例外を避けるために 'length-1'から始めるでしょう。 – AJNeufeld

+0

@AJNeufeldしかし、1つまたは複数の異なるエントリがあったかどうかをどのように知っていますか? 2番目の点は本当です、ありがとうございます。 – Cryptjar

+1

'start == nums.length'の場合、別のエントリはありません。そして、 'end> start'の間に2番目のループが走っていれば、' end'は 'length-1'で始まるので、' count'は実際には-1になります。 – AJNeufeld

-1

1)1番目の配列のサイズを取得します。 2)2番目の配列のサイズを取得します。 3)最小2つのループを実行します。 4)各アレイの結果を比較します。

関連する問題