检查2个数组是否相同(C ++)

时间:2019-01-05 01:42:31

标签: c++

我想比较两个int数组,找到它们是否相同,如果不相同,我想找到一个数组中不存在的最小和最大数。我在c ++中使用此代码,但似乎遇到了段错误11。如果有人指出我的错误,我将不胜感激。如果有,我希望看到更好的解决方案。 +我进行了mergesort的时间限制为1秒。

#include <iostream>

using namespace std;

void merge(int *a,int s,int e)
{
  int mid = (s+e)/2;
  int i = s;
  int j = mid+1;
  int k = s;
  int temp[100];
  while(i<=mid && j<=e)
  {
    if(a[i] < a[j])
    {
      temp[k++] = a[i++];
    }
    else
    {
      temp[k++] = a[j++];
    }
  }
  while(i<=mid)
  {
    temp[k++] = a[i++];
  }
  while(j<=e)
  {
    temp[k++]  = a[j++];
  }
  for(int i=s;i<=e;i++)
  {
    a[i] = temp[i];
  }
}

void mergeSort(int a[],int s,int e)
{
  if(s>=e)
  {
    return;
  }
  int mid = (s+e)/2;
  mergeSort(a,s,mid);
  mergeSort(a,mid+1,e);
  merge(a,s,e);
}
int min_array (int array1[],int n1)
{
  int min = array1[0];
  for(int i=1;i<n1;i++)
    if(array1[i] < min)
      min = array1[i];
  return min;
}

int max_array (int array2[],int n2)
{
  int max = array2[0];
  for(int i=1;i<n2;i++)
    if(array2[i] > max)
      max = array2[i];
  return max;
}

void check_same(int a[], int b[], int n)
{
  bool check = true;
  int check1 = 2, check2 = 2, counter1 = 0, counter2 = 0, i, j;
  int pos1[n], pos2[n];
  mergeSort(a, 0, n);
  mergeSort(b, 0, n);
  for(i=0; i<n; i++)
  {
    if (a[i] != b[i])
      check = false;
    for(j=0; j<n; j++)
    {
      if (a[i] != b[j])
        check1 = 0;
      else if (a[i] == b[j])
        check1 = 1;
      else if (a[j] != b[i])
        check2 = 0;
      else if (a[j] == b[i])
        check2 = 1;
      if (check1 == 1 && check2 == 1)
        break;
    }
    if (check1 == 0)
        pos1[counter1++] = i;
    else if (check2 == 0)
      pos2[counter2++] = i;

  }
  int differents[counter1 + counter2];
  if (counter1 < counter2)
  {
    for (i=0; i<counter1; i++)
      differents[i] = a[pos1[i]];
    for (i=counter1; i<counter2; i++)
      differents[i] = b[pos2[counter2 - i]];
  }
  else
  {
    for (i=0; i<counter2; i++)
      differents[i] = b[pos2[i]];
    for (i=counter2; i<counter1; i++)
      differents[i] = a[pos1[counter1 - i]];
  }
  if (check)
    cout << "yes\n";
  else if (check == false)
    cout << "no " << min_array(differents, counter1+counter2)<< " " << max_array(differents, counter1+counter2) << endl;
}

int main()
{
  int N, i;
  cin >> N;
  int A[50000], B[50000];
  for (i=0;i<N;i++)
    cin >> A[i];
  for (i=0;i<N;i++)
    cin >> B[i];
  check_same(A, B, N);
}

3 个答案:

答案 0 :(得分:2)

您的代码不是标准的C ++,int pos1[n], pos2[n];中的行check_same无效,因为n不是编译时间常数-VLA仅在C中允许。

您可以使用标准库进行所有操作:

#include <algorithm>
#include <iostream>
#include <iterator>
#include <vector>

void check_same(int a[], int b[], int n) {
    std::sort(a, a + n);
    std::sort(b, b + n);

    if(std::equal(a, a + n, b)) {
        std::cout << "yes\n";
    } else {
        std::vector<int> elements_not_in_both;
        std::set_symmetric_difference(a, a + n, 
                                      b, b + n,
                                      std::back_inserter(elements_not_in_both));
        auto [min, max] = std::minmax_element(elements_not_in_both.cbegin(),
                                              elements_not_in_both.cend());
        std::cout << "no " << *min << " " << *max << '\n';
    }
}

int main()
{
    int N;
    std::cin >> N;
    int A[50000], B[50000];
    for (int i=0; i<N; i++)
        std::cin >> A[i];
    for (int i=0; i<N; i++)
        std::cin >> B[i];
    check_same(A, B, N);
}

Live demo

一个更好的解决方案是也不要使用C样式的数组,这样您就不会为小的输入数组分配太多的堆栈空间,并且当有人决定在大于50000个元素:

#include <algorithm>
#include <iostream>
#include <iterator>
#include <vector>

void check_same(std::vector<int>& a, std::vector<int>& b) {
    std::sort(a.begin(), a.end());
    std::sort(b.begin(), b.end());

    if(a == b) {
        std::cout << "yes\n";
     } else {
        std::vector<int> elements_not_in_both;
        std::set_symmetric_difference(a.cbegin(), a.cend(), 
                                      b.cbegin(), b.cend(),
                                      std::back_inserter(elements_not_in_both));
        auto [min, max] = std::minmax_element(elements_not_in_both.cbegin(),
                                              elements_not_in_both.cend());
        std::cout << "no " << *min << " " << *max << '\n';
    }
}

int main()
{
    int N;
    std::cin >> N;

    std::vector<int> a, b;
    a.reserve(N);
    b.reserve(N);

    std::copy_n(std::istream_iterator<int>(std::cin), N, std::back_inserter(a));
    std::copy_n(std::istream_iterator<int>(std::cin), N, std::back_inserter(b));

    check_same(a, b);
}

答案 1 :(得分:0)

请检查以下几点以解决细分错误问题:

合并功能

1)这句话int k = 0;是否正确?不应该是int temp[100];

2)此分配int temp[e - s + 1]可以吗?还是应该为a[i] = temp[i];;

3)a[i] = temp[i - s];语句正确吗?不应该是s < e

4)您是否需要基本条件s == e或其他条件?即处理mergeSort(a, 0, n);时的情况。

check_same函数

1)此通话mergeSort(a, 0, n - 1);是否正确?不应该是#include <iostream> #include <vector> #include <unordered_set> using namespace std; void check_same(int a[], int b[], int n) { int minNotInA, maxNotInA, minNotInB, maxNotInB; bool elementMissingInA = false, elementMissingInB = false; { unordered_set<int> elementsInB; for (int i = 0; i < n; i++) { elementsInB.insert(b[i]); } for (int i = 0; i < n; i++) { if (elementsInB.find(a[i]) == elementsInB.end()) { if (!elementMissingInA) { elementMissingInA = true; minNotInB = maxNotInB = a[i]; } else { if (minNotInB > a[i]) { minNotInB = a[i]; } else if (maxNotInB < a[i]) { maxNotInB = a[i]; } } } } } if (elementMissingInA) { unordered_set<int> elementsInA; for (int i = 0; i < n; i++) { elementsInA.insert(a[i]); } for (int i = 0; i < n; i++) { if (elementsInA.find(b[i]) == elementsInA.end()) { if (!elementMissingInB) { elementMissingInB = true; minNotInA = maxNotInA = b[i]; } else { if (minNotInA > b[i]) { minNotInA = b[i]; } else if (maxNotInA < b[i]) { maxNotInA = b[i]; } } } } } if (elementMissingInA and elementMissingInB) { cout << "no " << min(minNotInA, minNotInB) << " " << max(maxNotInA, maxNotInB) << "\n"; } else { cout << "yes\n"; } } int main() { int N; std::cin >> N; int A[50000], B[50000]; for (int i=0; i<N; i++) std::cin >> A[i]; for (int i=0; i<N; i++) std::cin >> B[i]; check_same(A, B, N); return 0; }

就更好的方法而言,可以使用哈希在O(n)中解决。

function shuffle(array) {

  var currentIndex = array.length, temporaryValue, randomIndex;

  // While there remain elements to shuffle...
  while (0 !== currentIndex) {

    // Pick a remaining element...
    randomIndex = Math.floor(Math.random() * currentIndex);
    currentIndex -= 1;

    // And swap it with the current element.
    temporaryValue = array[currentIndex];
    array[currentIndex] = array[randomIndex];
    array[randomIndex] = temporaryValue;
  }

  return array;
}

答案 2 :(得分:0)

感谢大家的关注和帮助。 因为我不习惯您使用的那种库,并且我现在不想学习它们(我只是在我的ece课程的第一学期),所以我更正了我的代码(都对其进行了改进并修复了段错误11) 您可以在这里看看。

#include <iostream>

using namespace std;

void merge(int *a, int s, int e)
{
    int mid = (s + e) / 2;
    int i = s;
    int j = mid + 1;
    int k = s;
    int temp[50000];
    while (i <= mid && j <= e)
    {
        if (a[i] < a[j])
        {
            temp[k++] = a[i++];
        }
        else
        {
            temp[k++] = a[j++];
        }
    }
    while (i <= mid)
    {
        temp[k++] = a[i++];
    }
    while (j <= e)
    {
        temp[k++] = a[j++];
    }
    for (int i = s; i <= e; i++)
    {
        a[i] = temp[i];
    }
}

void mergeSort(int a[], int s, int e)
{
    if (s >= e)
    {
        return;
    }
    int mid = (s + e) / 2;
    mergeSort(a, s, mid);
    mergeSort(a, mid + 1, e);
    merge(a, s, e);
}
int min_array(int array1[], int n1)
{
    int min = array1[0];
    for (int i = 1; i<n1; i++)
        if (array1[i] < min)
            min = array1[i];
    return min;
}

int max_array(int array2[], int n2)
{
    int max = array2[0];
    for (int i = 1; i<n2; i++)
        if (array2[i] > max)
            max = array2[i];
    return max;
}


void check_same(int a[], int b[], int n)
{
    int differents[50000];
    int counter1 = 0, counter2 = 0;
    int i = 0, j = 0;
    while (i < n && j < n)
    {
        if (a[i] < b[j])
        {
            differents[counter1++ + counter2] = a[i];
            i++;
        }
        else if (b[j] < a[i])
        {
            differents[counter2++ + counter1] = b[j];
            j++;
        }
        else
        {
            i++;
            j++;
        }
    }
    if (counter1 == 0 && counter2 == 0)
        cout << "yes\n";
    else 
        cout << "no " << min_array(differents, counter1 + counter2) << " " << max_array(differents, counter1 + counter2) << endl;
}

int main()
{
    int A[50000], B[50000];
    int N, i;
    cin >> N;
    for (i = 0; i<N; i++)
        cin >> A[i];
    for (i = 0; i<N; i++)
        cin >> B[i];
    mergeSort(A, 0, N-1);
    mergeSort(B, 0, N-1);
    check_same(A, B, N);
    return 0;
}