Funkcja sortująca dwie tablice i zwracająca ich połączenie

0

Witam mam za zadanie napisać funkcję, która otrzymuje pięć parametrów wskaźnik na tablicę int a, wskaźnik na tablicę int b, rozmiar a, rozmiar b, i wskaźnik który ma wartość o długości połączonych tablic. Z pierwszej tablicy usuwamy duplikaty, podobnie z drugiej. Następnie łączymy te dwie tablice sortujemy połączone tablice i długość tak utworzonej tablicy umieszczamy we wskaźniku ostatnim parametrze funkcji. Następnie zwracamy tak utworzoną nową tablicę. Poniżej zamieszczam kod:

#include <stddef.h>
#include <stdlib.h>
int compare(const void *a, const void *b)
{
  return *(int*)a-*(int*)b;
}

int *testit(const int *a, const int *b, size_t az, size_t bz, size_t *cz) {
int *res=(int*)malloc(sizeof(int)*(az+bz));
size_t i,j;
qsort(a,az,sizeof(int),compare);
qsort(b,bz,sizeof(int),compare);
for(i=0,j=0;i<az;)
{
  if(a[i]!=a[i+1])
    res[j++]=a[i++];
  if(a[i]==a[i+1])
  {
    while((a[i]==a[i+1])&&(i<az))
      i++;
    res[j++]=a[i++];
  }
 }
for(i=0;i<bz;)
{
  if(b[i]!=b[i+1])
    res[j++]=b[i++];
  if(b[i]==b[i+1])
  {
    while((b[i]==b[i+1])&&(i<bz))
      i++;
    res[j++]=b[i++];
  }
 }
 *cz=j;
 qsort(res,*cz,sizeof(int),compare);
return res;
}

Problem polega na tym, że serwer przy kompilacji wyrzuca mi błąd o nieprawidłowym rozmiarze tablicy we wskaźniku *cz. Poniżej opis błędu

ERROR < incorrect array length >

Array a: {13, 15, 28, 71, 79, 80, 98}

Array b: {8, 11, 14, 28, 28, 36, 46, 63, 65, 80, 86, 88, 89, 91}

Expected: {8, 11, 13, 14, 15, 28, 28, 36, 46, 63, 65, 71, 79, 80, 80, 86, 88, 89, 91, 98}

Submitted: {0, 8, 11, 13, 14, 15, 28, 28, 36, 46, 63, 65, 71, 79, 80, 80, 86, 88, 89, 91, 98}

Mam pytanie jak to poprawić. Nie mam pomysłu na zapisanie we wskaźniku innej wartości, bo przecież j ma długość połączonych tablic?

0

Na moje oko to alokujesz tablicę res na rozmiar taki jak mają zsumowane tablice wejściowe, ale ty chcesz mieć tablicę wynikową o rozmiarze pomniejszonym o usunięte duplikaty.
PS: To nie jest błąd przy kompilacji tylko nie przechodzi jakiś test.

0

Nie jestem w stanie tego obejść, bo najpierw musiałbym liczyć duplikaty, odjąć je od az+bz i potem jeszcze raz w pętlach przypisywać do res wartości z tablic. Tutaj mam kolejną informację z serwera.
ERROR < incorrect array length >

Array a: {1}

Array b: {2, 3, 4}

Expected: {1, 2, 3, 4}

Submitted: {1, 1, 2, 3, 4}
Czyli przekazuję tablicę o jeden większą niż by to wynikało z az+bz

1

Masz UB:

for(i=0,j=0;i<az;)
{
  if(a[i]!=a[i+1])

Dla i == az-1, a[i+1] wychodzi poza koniec tablicy.
Generalnie, używanie tych wartości do czegokolwiek znaczy, że może się stać praktycznie wszystko potem.

0

To jest zadanie raczej dla początkujących poziom w skali trudności 7 z dostępnych 8. Tak , że nie wiem czy mój algorytm jest poprawny czy można to uprościć.

0
gonskabalbinka napisał(a):

To jest zadanie raczej dla początkujących poziom w skali trudności 7 z dostępnych 8. Tak , że nie wiem czy mój algorytm jest poprawny czy można to uprościć.

Pomysł ogólny jest dobry (i można w nim nieco usprawnić, w szczególności ostatni qsort nie jest optymalnym podejściem) ale powinieneś(powinnaś?) wyeliminować te odwołania do nieistniejących elementów, inaczej nigdy program nie będzie poprawny.

0

Nadal nie wiem gdzie w tym programie jest błąd bo nawet przy uwzględnieniu warunków brzegowych dalej jest nieprawidłowy rozmiar tablicy?

0
#include <stddef.h>
#include <stdlib.h>
int compare(const void *a, const void *b)
{
  return *(int*)a-*(int*)b;
}

int *testit(const int *a, const int *b, size_t az, size_t bz, size_t *cz) {
size_t i,j;
qsort(a,az,sizeof(int),compare);
qsort(b,bz,sizeof(int),compare);
int *res=(int*)malloc(sizeof(int)*(az+bz));

for(i=0,j=0;i<az-1;i++)
  if(a[i]!=a[i+1])
    res[j++]=a[i];
res[j++]=a[az-1];
for(i=0;i<bz-1;i++)
  if(b[i]!=b[i+1])
    res[j++]=b[i];
 res[j++]=b[bz-1];
*cz=j;
qsort(res,*cz,sizeof(int),compare);
return res;
}

I teraz przechodzi mi testy w większości poprawnie, ale wyrzuca mi błąd:
Test Crashed
Caught unexpected signal: SIGSEGV (11). Invalid memory access.

2

Jest opcja, że rozrzutnie sobie alokujesz az+bz komórek, a system tam jest tak skonfigurowany, że pozwoli tylko na *cz komórek.

Poza tym, nie ma co prawda błędnego dostępu do pamięci na końcu, ale za to kopiujesz ten ostatni element niezależnie od tego, czy był identyczny z przedostatnim, czy nie.

1 użytkowników online, w tym zalogowanych: 0, gości: 1