これが(コードに基づいて)トリックを行うべきだと思うことです。基本的に、コードは2つのケースをチェックしませんでした:
最初は、最小値が配列内の最初の 2 つの値の間にある場合です。
2 つ目は、1 つの配列のすべての値をチェックしたが、2 つ目の配列にまだ値がある場合です。(ケース a[0,1,2], b[-1,-2,-3,-5,-6,2] を考えてみましょう)
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
int comp(const void * a,const void * b)
{
if (*(int*)a==*(int*)b)
return 0;
else if (*(int*)a < *(int*)b)
return -1;
else
return 1;
}
int main()
{
int x,y;
printf("x: ");
scanf ("%d", &x);
int a[x];
srand(time(NULL));
for (int i = 0; i < x; i++)
{
a[i] = rand() % 30 - 15;
//scanf ("%d", &a[i]);
printf ("%d\n",a[i]);
}
printf("y: ");
scanf ("%d", &y);
int b[y];
for (int i = 0; i < y; i++)
{
b[i] = rand() % 30 - 15;
//scanf ("%d", &b[i]);
printf ("%d\n",b[i]);
}
qsort(a,x,sizeof(int),comp) ;
qsort(b,y,sizeof(int),comp) ;
int i = 0, j = 0;
int * inc; // using a pointer to select which var to increment. Avoid repeating code, optional and subjective approach.
int minimum = abs(a[0]-b[0]); // Set min to be a[0] - b[0] which is never checked in the loop
/* Added the min > 0 condition to avoid looping unnecessarily and avoid the break statement
Changed the condition from && to || in order to handle the second case
Changed the != to < which is more restrictive */
while (minimum > 0 && (i < (x - 1) || j < (y - 1)))
{
int z;
if ( i == x-1) // we've reached the end of a, inc j automatically
{
inc = &j;
z = abs(a[i]-b[j+1]);
}
else if ( j == y -1 ) // we've reached the end of b, inc i automatically
{
inc = &i;
z = abs(a[i+1]-b[j]);
}
else // here's the original loop, rewritten to shorten the code
{
int zi = abs(a[i+1]-b[j]);
int zj = abs(a[i]-b[j+1]);
if ( zi < zj)
{
inc = &i;
z = zi;
}
else
{
inc = &j;
z = zj;
}
}
if ( z < minimum)
{
minimum = z;
}
(*inc)++;
}
printf("min: ");
printf ("%d\n", minimum);
return 0;
}