Jak złaczyć dwie tablice?

0

Jak złączyć 2 tablice posortowane niemalejąco w jedn,ą zapisując do tablicy trzeciej.....
dostajemy 2 posortowane, i wynikiem ma być trzecia tablica także posortowana składająca się z 2 poprzednich
Nie wiem jak to zrobić

2

Iterujesz po obu, kopiując mniejszy element, aż do końca obu tablic. Inkrementujesz tylko wskaźnik tej, z której skopiowałeś.

2

http://stackoverflow.com/a/19719407
Tutaj zakładają, że tablice mają ten sam rozmiar, ale nie powinno być problemem zmiana, by te początkowe tablice miały różne rozmiary.

0

zrobiłem ale sie program zawiesza :(

#include <stdio.h>
#define n_1 2
#define n_2 3

void merge(int tab1[], int tab2[], int tab3[], int amount)
{
    int amount_t1 = 0, amount_t2 = 0;
    int i = 0, j;
    while (tab1[i++] != '\0')
        ++amount_t1;
    i = 0;
    while (tab2[i++] != '\0')
        ++amount_t2;
    if (amount_t1 > amount_t2) {
        for (i = 0; i < amount_t2; ++i)
            if (tab1[i] < tab2[i] || tab1[i] == tab2[i])
                tab3[i] = tab1[i];
        for (i = 0; i + amount_t2 < amount; ++i)
            tab3[i] = tab1;
    }
    else {
        for (i = 0; i < amount_t1; ++i)
            if (tab1[i] < tab2[i] || tab1[i] == tab2[i])
                tab3[i] = tab1[i];
        for (i = 0; i + amount_t1 < amount; ++i)
            tab3[i] = tab2;
    }
    for (i = 0; i < 5; ++i)
        printf("%d\t", tab3[i]);
}
int main(int argc, char* argv[])
{

    int amount = n_1 + n_2;
    int tab1[n_1] = { 2, 4 };
    int tab2[n_2] = { 1, 3, 7 };
    int tab3[n_1 + n_2];
    merge(tab1, tab2, tab3, amount);

    return 0; 
0

Tablice nie są zakończone zerem. C-stringi są. Musisz przekazać wielkości tablic do funkcji.

0

no i wykodziłe, mogłem zajrzeć wcześniej do wykładu ;-; ,rozumiem o co chodziło z tymi wskażnikami
No i jest probem, bo działa poprawnie ale nie jak tablice są różnej długości

#include <stdio.h>
#define n_1 3
#define n_2 2

void merge(int tab1[], int tab2[], int tab3[], int n1, int n2)
{
    int amount = n1 + n2;
    int i = -1;
    int *W1 = tab1, *W2 = tab2; //dlaczego jak wpisywałem &tab1 to program się wkurzał ? to jest uzyskanie adresu adresu tablicy?
    while (++i < amount) {
        
        if(*W1 == *W2) {
            tab3[i] = *W1;
            ++*W1;
            ++*W2;
           }
        if (*W1 > *W2) {
            tab3[i] = *W2;
            ++W2;
        }
        else {
            tab3[i] = *W1;
            ++W1;
        }
    }

    for (i = 0; i < 5; ++i)
        printf("%d\t", tab3[i]);
}
int main(int argc, char* argv[])
{

    int amount = n_1 + n_2;
    int tab1[n_1] = { 2, 2, 5 };
    int tab2[n_2] = { -5, 4 };
    int tab3[n_1 + n_2];
    merge(tab1, tab2, tab3, n_1, n_2);

    return 0;
}
0

//tutaj musi być warunek az do wyczerpania jakies tablicy ale nie wiem jak to zrobic ->

#include <stdio.h>
#define n_1 3
#define n_2 2

void merge(int tab1[], int tab2[], int tab3[], int n1, int n2)
{
    int amount = n1 + n2, end_Ofsmaller;
    int i = -1;
    int *W1 = tab1, *W2 = tab2, *longer;
    if(n1 > n2) end_Ofsmaller = n2;
    else end_Ofsmaller = n1;

   for( i = 0; i < end_Ofsmaller; ++i) {// tutaj musi być warunek az do wyczerpania jakies tablicy ale nie wiem jak to zrobic
        if(*W1 == *W2) {
            tab3[i] = *W1;
            ++*W1;
            ++*W2;
           }
        if (*W1 > *W2) {
            tab3[i] = *W2;
            ++W2;
        }
        else {
            tab3[i] = *W1;
            ++W1;
        }
    }

    if(end_Ofsmaller == n2 )
        while (++end_Ofsmaller < amount)
        tab3[end_Ofsmaller] = tab1[end_Ofsmaller];

    else
        while (++end_Ofsmaller < amount)
        tab3[end_Ofsmaller] = tab2[end_Ofsmaller];
    for (i = 0; i < amount; ++i)
        printf("%d\t", tab3[i]);
}
int main(int argc, char* argv[])
{

    int amount = n_1 + n_2;
    int tab1[n_1] = { 2, 2, 5 };
    int tab2[n_2] = { -5, 4 };
    int tab3[n_1 + n_2];
    merge(tab1, tab2, tab3, n_1, n_2);

    return 0;
}
 
0

"//dlaczego jak wpisywałem &tab1 to program się wkurzał ? to jest uzyskanie adresu adresu tablicy?" - bo nazwa tablicy to wskaźnik na jej pierwszy element, jak dasz &tab1 to tak jakbyś chciał wyłuskać adres wskaźnika (podwójny wskaźnik).
Jak nie wiesz dlaczego źle złącza ci tablice o różnych rozmiarach to sobie wypisz jakie kolejne wartości przyjmują zmienne pod adresami W1 i W2:
2 -5 (2 > -5)
2 4 ( 2 < 4)
2 4 (2 < 4)
5 4 (5 > 4)
5 2 (5 > 2)
czyli zgodnie z działaniem tego programu wpisze ci do tablicy kolejno: -5, 2, 2, 4, 2.
Jak widać takie porównania nie za bardzo działają dla tablic o różnych rozmiarach.

1

A czy nie lepiej jest zamiast inicjalizować zmienną iteracyjną int i jedną dla wszystkich pętli w ten sposób:

 int i;
for (i=0; ...){
...
}
for(i=0;...){
...
}

, inicjalizować int i dla każdej pętli z osobna w ten sposób:

 for (int i=0; ....){
...
}
 for (int i=0; ....){
...
}

?
Ten drugi "nawyk" wydaje mi się dużo lepszy.

0

memcpy.

0

@bl4ster: generowany kod jest w obu przypadkach taki sam, czytelność też, więc powiedziałbym, że to wyłącznie kwestia gustu.

0

TL;DR

Zjadasz wartości, o tu:

        if(*W1 == *W2) {
            tab3[i] = *W1;
            ++*W1;
            ++*W2;
           }
0

a czyli co? dlaczego zjadam, jak są takie same, czyli np. 4 i 4 to ide dalej w tablicy i wpisuje tylko 1 jedynkę

0

wynikiem ma być trzecia tablica także posortowana składająca się z 2 poprzednich

Zmieniasz założenia.

0
#include <iostream>

void scal(int* tab1, int len1, int* tab2, int len2, int* tab3)
{
    int *t1, *t2, *t3;
    for (t1 = tab1, t2 = tab2, t3 = tab3; len1 || len2;) {  // co to jest? o co chodzi z tym for?założenie jest żę len 1 lub len 2, a reszta?
        if (len1 && len2) {
            if (*t1 < *t2) {
                *t3++ = *t1++;
                len1--;
            }
            else {
                *t3++ = *t2++;
                len2--;
            }
        }
        else if (len1) {
            *t3++ = *t1++;
            len1--;
        }
        else if (len2) {
            *t3++ = *t2++;
            len2--;
        }
    }
}

void print(int* tab, int len, char* str)
{
    std::cout << str << ": [ ";
    for (int i = 0; i < len; i++) {
        std::cout << tab[i] << " ";
    }
    std::cout << "]" << std::endl;
}

int main()
{
    int t1[] = { 1, 3, 5 };
    int t2[] = { 2, 4, 6 };
    int t3[6];
    scal(t1, 3, t2, 3, t3);
    print(t3, 6, (char*)"tab3");
    return 0;
} 
0
for (t1 = tab1, t2 = tab2, t3 = tab3; len1 || len2;) 

Na początku przypisujesz wartości do t1, t2, t3 a potem iterujesz tak długo jak choć jedno z len1 i len2 nie jest zerem.

Zdecydowanie preferuję wersję z trzema pętlami zamiast zbędnego drzewka ifów.

Btw, w C++ od takich rzeczy masz std::merge.

0

if (len1 && len2) oznacza jeśli np. 4 i 4 ?

0

Obie wartości są konwertowane na bool za pomocą standardowych konwersji. W skrócie: dla x ≠ 0, będzie to true, a dla x = 0 będzie to false. Czyli if(len1 && len2) wymaga aby obie wartości były niezerowe.

0

Nie testowałem:

void scal(int* tab1, int len1, int* tab2, int len2, int* tab3)
{
    int lenx = len1 < len2 ? len1 : len2;
    int *t1 = tab1, *t2 = tab2, *t3 = tab3;
	int idx = 0;
	
	while(idx++ < lenx) {
	  if (*t1 < *t2) {
		*t3++ = *t1++;
	  } else if (*t1 > *t2) {
	    *t3++ = *t2++; 
	  } else {
		*t3++ = *t1++;
	    *t3++ = *t2++; 
	  }
	}

    int idx1 = idx;
	int idx2 = idx;
	
	while(idx1++ < len1) {
		*t3++ = *t1++;
	}

	while(idx2++ < len2) {
		*t3++ = *t2++;
	}
}

0

int lenx = len1 < len2 ? len1, endOFone = len1 : len2, endOFone = len2; dlaczego nie moga tak zrobić? bardzo mi to porzebne, dla jeden endOFone = len1 działa el jak dołoże drugą po : to nie działa

0

Zrobiłem **powinno ** działać, ale program się zawiesza, why?

#include <stdio.h>
#define n_1 3
#define n_2 2

void merge(int tab1[], int tab2[], int tab3[], int len1, int len2)
{
    int amount = len1 + len2;
    int i ;
    int *W1 = tab1, *W2 = tab2, *W3 = tab3;
    int lenx = len1 < len2 ? len1 : len2 ;

   while(len1 && len2){ //to przez tą pętlę ale nie wiem dlaczego, co jest żle

        if(*W1 == *W2) {
            *W3++ = *W1++;
            *W3++ = *W2++;
            --len1;
            --len2;
           }
        if (*W1 > *W2) {
            *W3++ = *W2++;
            --len2;
        }
        else {
            *W3++ = *W1++;
            --len1;
        }

    }

    if( len1 ){
        while (len1)
        *W3++ = *W1++;
        --len1;
    }
    else{
        while (len2)
        *W3++ = *W2++;
        --len1;
    }
    for (i = 0; i < amount; ++i)
        printf("%d\t", tab3[i]);
}
int main(int argc, char* argv[])
{

    int amount = n_1 + n_2;
    int tab1[n_1] = { 2, 2, 5 };
    int tab2[n_2] = { -5, 4 };
    int tab3[n_1 + n_2];
    merge(tab1, tab2, tab3, n_1, n_2);

    return 0;
}
 
0
    if( len1 ){
        while (len1)
        *W3++ = *W1++;
        --len1;
    }
    else{
        while (len2)
        *W3++ = *W2++;
        --len1;
    }

po sformatowaniu poprawnym, bez dodawania niezbędnych klamerek:

if (len1) {
    while (len1)
        *W3++ = *W1++;
    --len1;
}
else {
    while (len2)
        *W3++ = *W2++;
    --len1;
}

Inaczej mówiąc: dodaj klamerki.

0

po zmianie danych program się nie włacza nie wiesz co jest grane?

#include <stdio.h>
#define n_1 2
#define n_2 3

void merge(int tab1[], int tab2[], int tab3[], int len1, int len2)
{
    int amount = len1 + len2;
    int i ;
    int *W1 = tab1, *W2 = tab2, *W3 = tab3;
    int lenx = len1 < len2 ? len1 : len2 ;

   while(len1 && len2){

        if(*W1 == *W2) {
            *W3++ = *W1++;
            *W3++ = *W2++;
            --len1;
            --len2;
           }
        if (*W1 > *W2) {
            *W3++ = *W2++;
            --len2;
        }
        else {
            *W3++ = *W1++;
            --len1;
        }

    }

    if( len1 )
        while (len1){
        *W3++ = *W1++;
        --len1;
    }
    else
        while (len2){
        *W3++ = *W2++;
        --len1;
    }
    for (i = 0; i < amount; ++i)
        printf("%d\t", tab3[i]);
}
int main(int argc, char* argv[])
{

    int amount = n_1 + n_2;
    int tab1[n_1] = { 2, 5};
    int tab2[n_2] = { -5, 4,9 };
    int tab3[n_1 + n_2];
    merge(tab1, tab2, tab3, n_1, n_2);

    return 0;
}

0
        while (len2){
        *W3++ = *W2++;
        --len1;
    }

Metoda Kopiego-Pejsta strikes again. len1len2. Na przyszłość z debuggera korzystaj sam.

0

ja nic nie kopiowałem, się tylko pomyliłem, nie zauważyłem, ciągle mi się to zdarza,
a wartośći były złe, bo podałem nieposortowane wartości, uff ,już myślałem że wszsystko będe pisał od nowa,
Dddziękuwa wszystkim :)

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