C\ Wskazniki

0

Czesc,
czy mogli byście pomóc mi w jednym zadaniu ?

Mam napisać funkcję która:

a) przyjmie tablicę wskaźników na inty

b) i jej długość

Funkcja powinna zwracać sumę wszystkich wskazywanych wartości, gdzie jedna wskazywana wartość może być dodana tylko raz, niezależnie od liczby wskaźników wskazujących na nią.

Nie za bardzo rozumiem to polecenie, na razie doszedłem do tego że:
-deklaruje funkcję
ale nie wiem co dalej począć z jej definicją

void (int ** tablica, int rozmiar) 
{
int i; 
for(i=0; i<rozmiar; i++) 
// dodawanie elementów tablicy; 
{
 // TU MAM ZSUMOWAĆ ELEMENTY ? 
}
}
 
1

Trzeba:
Zrobić kopię tej tablicy.
Posortować kopię wg adresów.
Przyjmujemy że poprzedni dodany do sumy wskaźnik był z adresem 0
Przeglądamy posortowaną tablicę wskaźników i jeżeli adres int'a nie jest taki sam jak poprzedni adres to dodajemy do sumy i zmieniamy poprzedni adres dodany.

0

Czy mógłbyś rozwinąć swoją odpowiedź. Wiem że mogę wymagać za dużo, ale nie jestem w stanie tego za bardzo pojąć.
W jaki sposób mogę zrobić kopię tablicy ?
Posortować kopię wg adresów ? Jakim sposobem ?

"Przeglądamy posortowaną tablicę wskaźników i jeżeli adres int'a nie jest taki sam jak poprzedni adres to dodajemy do sumy i zmieniamy poprzedni adres dodany."

Czy chodzi Ci o sytuację w której:

 
for(i=0; i<rozmiar_tab; i++) 
{
if (&tab[i] != &tab[i-1])
{
tab[i]+=suma; 
}

Przepraszam jeśli wypisuję brednie ale nie jestem za bardzo w stanie tego pojąć, i to już nie problem braku obeznania się z programowaniem ale zwyczajne niezrozumienie tematu.

Jeśli mógłbyś chociaż rozwinać swoją wypowiedź, komentując mój kod byłbym wdzięczny !

0

Ok, więc mam zrobioną "kopię" tablicy wskaźników.

int **tab1; 
tab1=(int**)malloc(rozmiar * sizeof(int)); 
int i; 
for(i=0; i<tab_size; i++)
{
  strcpy(tab1[i], tab[i]); 
}

Nie za bardzo wiem jak mogę posortować te tablicę względem adresów, załóżmy że mamy adres jakiegoś wskaźnika:

int *a=&b;

Co teraz mam z nim począć ? Jak je posortować, z tego co wiem to bubblesort i quicksort stosuję się tylko do liczb, a w adresach mamy różne znaki, tj. również litery.

0
sek1 napisał(a):

Ok, więc mam zrobioną "kopię" tablicy wskaźników.

tab1=(int**)malloc(rozmiar * sizeof(int)); 

Na pewno? Chcesz utworzyć kopię tablicy wskaźników, a tworzysz tablicę o rozmiarze liczb typu int. I dlaczego używasz strcpy. Przecież ta funkcja kopiuje C stringi.

sek1 napisał(a):

a w adresach mamy różne znaki, tj. również litery.

To są też liczby, tylko że w zapisie szesnastkowym. Jedyne co ci potrzebne przy sortowaniu to operator <.

0
sek1 napisał(a):

z tego co wiem to bubblesort i quicksort stosuję się tylko do liczb, a w adresach mamy różne znaki, tj. również litery

Nie masz sortować adresów, a wartości (int-y) znajdujące się pod tymi adresami.

a w adresach mamy różne znaki, tj. również litery.

Poczytaj o systemie heksadecymalnym, bo ten wątek może za niedługo trafić do perełek.

#Edit - also, źle kopiujesz tablicę. Nie masz pojęcia co robisz...

0

Przynajmniej podałem przykład zamiast czekać na gotowca.

0
void (int ** tablica, int rozmiar) 
{
int suma = 0;

int i; 
for(i=0; i<rozmiar; i++) 
// dodawanie elementów tablicy; 
{
suma += tablica[i];

tablica[i] = 0;
}

return suma;
}

Taki gotowiec, ale może nie spełniać założeń ;)

0

Przecież to jest praktycznie kopia tego co sam napisałem.
Ok, kopię powinno (przynajmniej tak mi się wydaje) zrobić tak:

void kopiuj(int tab1[],int tab2[], int size){
      int i;
      int temp; 
      for (i=0;i<size;i++){
         temp=tab1[i];
         tab1[i]=tab2[i];
         tab2[i]=temp;
      }
} 

 
1

Nie, ten Twój kod robi coś innego. Po jego wykonaniu wartości w tablicach tmp1 i tmp2 byłyby zamienione między sobą.

Dlaczego nie po prostu?

for (i=0;i<size;i++)
 tab2[i] = tab1[i]; // lub na odwrót (tab1[i] = tab2[i]) - nie wiem co u Ciebie jest czym

(oczywiście zakładamy, że wskaźniki na obie tablice są już zainicjowane i wskazują na odpowiedni obszar pamięci)

0

Faktycznie.
Czy przy sortowaniu można użyć zwykłego bubblesorta ?

0

Do sortowania możesz użyć dowolnego algorytmu.

1

_13th_Dragon dokładnie opisał jak to można zrobić, a w C++ zrobiłbym tak:

int sumujRozneKomorki(int ** tablica, int rozmiar) 
{
    std::set<int *> uniqeAddresses;
    for(int i=0; i<rozmiar; ++i)
        uniqeAddresses.insert(tablica[i]);
    int sum = 0;
    for(std::set<int *>::const_iterator i=uniqeAddresses.cbegin();
             i!=uniqeAddresses.cend();
             ++i) {
        sum += **i;
    }
    return sum;
}
0

Tylko że w C nie mam kontenerów i nie mogę używać STL'a :)
Mimo wszystko dzięki za rozwiązanie.

0
Patryk27 napisał(a):

Nie masz sortować adresów, a wartości (int-y) znajdujące się pod tymi adresami.

Akurat w tym zadaniu adresy są istotne, bo to one nie mogą się powtarzać. Standardowe rozwiązania to trochę wolniejsze, ale zajmujące mniej pamięci rozwiązanie, które zaproponował _13th_Dragon, albo użycie struktury danych typu Zbiór na wskaźniki na int'y. Rozwiązanie, które podałem wcześniej, oczywiście nie jest za dobre, bo maże nie po swoich danych. I wywołanie drugi raz tej funkcji, na tej samej tablicy, zwróci 0.

1

Trochę skrócona wersja w C++:

template<typename T>
T unique_ptr_sum(T** arr, size_t length)
{
    set<T*> elements(arr, arr + length);
    return accumulate(elements.begin(), elements.end(), 0, [](T sum, T* ptr) -> T { return sum + *ptr; });
}

Względnie zamiast własnej funkcji sumującej (tutaj lambdy) można użyć boost::indirect_iterator.

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