Forum > Software > Program w C, tablica.

Strona 1 z 1 1
skocz

czaro2

  • czaro2
  • wiadomość Użytkownik

  • 585 wypowiedzi

Wysłane 2015-01-26 20:46

Witam!
Pozwólcie, że przejdę od razu do rzeczy. Otóż miałem napisać funkcję w ANSI C, która usunie z tablicy elementy ujemne. Operacja miała zostać wykonana bez użycia dodatkowej tablicy, a finalna tab nie mogła zawierać dziur. Udało mi się napisać kod, który zamieszczam poniżej. Wszystko ładnie się kompiluje, rezultaty pokrywają się z oczekiwanymi, jednak Profesor chce, aby funkcja nie opierała się na kopii elementów(trzeba użyć wskaźników). Nie jestem w stanie niczego wymyślić, dlatego proszę o pomoc. Z góry dzięki!

int usunUjemneElementy(int t[], int n)
{
    int i,j,c=0;

    for(i=0;i<n;i++)
    {
        if(t[i]<0) t[i]=0;
        else c++;
    }

    for(i=0;i<n;i++)
    {
        if(t[i]!=0)
        {
            for(j=0;j<i;j++)
            {
                if(t[j]==0)
                {
                    t[j]=t[i];
                    t[i]=0;
                    j=i;
                }
            }
        }
    }

    return c;
}

KeeL

  • KeeL
  • wiadomość Użytkownik

  • 71 wypowiedzi

Wysłane 2015-01-26 21:46

Nie wiem czy Ci to pomoże, ale może po prostu posortować tablicę, wtedy od pewnego elementu zostaną wartości do usunięcia.

Ewentualnie można zamieniać elementy, na przykład jak wykryjesz ujemny element to go zamień z ostatnim. 

Mike*[PL]*

Wysłane 2015-01-27 00:36 , Edytowane 2015-01-27 00:40

void zsun(int *t,int odkad,int rozmiar){
    for(int i=odkad;i<(rozmiar-1);++i){
        t[i]= t[i+1];
    }
    t[rozmiar-1] = 0;  -> kurczac tablice na ostatniej pozycji wstawiam symboliczne 0
}


void usunUjemneElementy(int *t,int rozmiar){
    for(int i=0;i<rozmiar;++i){
        if(t[i]<0){
            zsun(t,i,rozmiar);
        }
    }
}


main(){
...
    const int rozmiar = 10;
    int tab[rozmiar]{10,20,30,-40,50,60,-70,80,90,100};
    usunUjemneElementy(tab,rozmiar);  -> nazwa tablicy jest jednocześnie adresem jej pierwszego ( [0] ) elementu

*Skoro cały czas operujemy na jednej tablicy, to trzeba czyms wypelnic te luki.
*Przesyłając tablice do parametru funkcji typu tablicowego, nie kopiujesz jej (też zasyłasz oryginał)

Yoshi_80

Wysłane 2015-01-27 13:55 , Edytowane 2015-01-27 13:59

To zadanie to chyba klasyczne zadanie na wskaźniki, kiedyś na studiach robiłem je w pascalu.

Należy stworzyć strukturę o polach :
{
dane
wskaźnik na poprzedni element
wskaźnik na następny element
}

Następnie w pętli tworzymy operatorem new obiekty tej struktury w wymaganej ilości, tak że do pierwszego w polu następny przypisujemy wskaźnik na drugi a drugiemu w polu poprzednim wskaźnik na pierwszy itd aż do zadanej ilości elementów.
To jest tzw lista dwukierunkowa. Można też tworzyć listy jednokierunkowe ze wskaźnikiem na poprzedni element. Jednak wtedy można się poruszać w jednym kierunku po tej liście, znamy ostatni zawsze "dokopujemy" się po kolei do ostatniego.
Teraz usuwając elementy o wartości -1 w polu dane, po prostu wyszukujemy pętlą jak znajdziemy to sąsiednim elementom przypisujemy zawartość wskaźnika na poprzedni i następny element z tego znalezionego a jego traktujemy poleceniem delete :-). W sumie lista jednokierunkowa wystarczy, łatwiej będzie zrobić.

Mike*[PL]*

Wysłane 2015-01-27 19:15

@Yosh_80

Tylko zbudowanie takiej struktury (może jako kontener + iterator?) jest nieporównywalnie cięższe od problemu przedstawionego przez Czaro2. Jeśli ma tylko przeczyścić tablice z wartości ujemnych to tak chyba będzie najprościej.

PS. Notacja tablicowa użyta w obu funkcjach to zwykłe działanie na wskaźniku (równie dobrze można użyć składni (*t++) ).

Strona 1 z 1 1
skocz

Kto jest online: 1 użytkowników, 146 gości

magx2k ,