Prosta funkcja usuwajaca zdublowane cyfry w tablicy - spr

soku11
Użytkownik
Użytkownik
Posty: 6607
Rejestracja: 16 sty 2007, o 19:42
Płeć: Mężczyzna
Podziękował: 119 razy
Pomógł: 1823 razy

Prosta funkcja usuwajaca zdublowane cyfry w tablicy - spr

Post autor: soku11 »

WITAM!
Jak w temacie. Mam funkcje, ktora powinna kasowac powielone elementy w tablicy tab[size] i uzupelnic ja od nowa samymi cyframi nie powtarzajacymi sie i zmienic ej rozmiar na wymagany (size). Oto kod:

Kod: Zaznacz cały

typedef unsigned int uint;
typedef const unsigned int cuint;


void remove_dup(uint tab[],uint *size)
{
  uint return_tab[*size],ret_tab_pos=0;
  uint temp,x;
  uint new_size=0;

  if(*size==0 || *size==1) return;
	
  for(x=0;x<*size;x++) return_tab[x]=0;
	
  for(x=0;x<*size;x++)
  if( (temp=count_number(tab,*size,tab[x]))==1)
      return_tab[ret_tab_pos++]=tab[x];
   else tab[x]=0;
	
  while(return_tab[new_size])new_size++; 

  for(x=0;x<*size;x++) tab[x]=0;

  for(x=0;x<new_size;x++) 
    tab[x]=return_tab[x];

  *size=new_size;
}
Gdzie funkcja zliczajaca wystapienie count_number ma postac:

Kod: Zaznacz cały

uint count_number(uint tab[], uint rozmiar, cuint number)
{
  uint count=0,x;
  for(x=0;x<rozmiar;x++)
    if(tab[x] == number  ) count++;
	
  return count;
}
Z gory dzieki za poswiecenie chwili i sprawdzenie POZDRO
Awatar użytkownika
kadiii
Użytkownik
Użytkownik
Posty: 642
Rejestracja: 20 gru 2005, o 21:04
Płeć: Mężczyzna
Lokalizacja: Wrocław
Pomógł: 130 razy

Prosta funkcja usuwajaca zdublowane cyfry w tablicy - spr

Post autor: kadiii »

Trochę toporny i nieczytelny program, ale poprawny(w sensie wyniku).
Rafal88K
Użytkownik
Użytkownik
Posty: 311
Rejestracja: 15 mar 2007, o 16:52
Płeć: Mężczyzna
Lokalizacja: Lublin
Podziękował: 28 razy
Pomógł: 54 razy

Prosta funkcja usuwajaca zdublowane cyfry w tablicy - spr

Post autor: Rafal88K »

Teraz trochę inne rozwiązanie

Jeżeli chcesz, żeby nic się nie powtarzało to wczytaj ciąg, następnie go posortuj i zobacz poniższy program:

Kod: Zaznacz cały

#include <algorithm>
#include <iostream>
#include <string>
using namespace std;

int main(int argc, char** argv)
{
    string myStr;
    string::iterator it;

    cin >> myStr;

    it = unique(myStr.begin(), myStr.end());
    myStr.erase(it, myStr.end());

    cout << myStr;

    cout << endl;
    system("pause");
    return 0;
}
smiechowiec
Użytkownik
Użytkownik
Posty: 374
Rejestracja: 21 cze 2007, o 11:28
Płeć: Mężczyzna
Lokalizacja: Łostowice
Pomógł: 146 razy

Prosta funkcja usuwajaca zdublowane cyfry w tablicy - spr

Post autor: smiechowiec »

Choć algorytm jest poprawny można by go jeszcze nico ulepszyć.
soku11 pisze:WITAM!
Mam funkcje, ktora powinna kasowac powielone elementy w tablicy tab[size] i uzupelnic ja od nowa samymi cyframi nie powtarzajacymi sie i zmienic ej rozmiar na wymagany (size).
Rozumiem, że przyjąłeś założenie że w tablicy nie mogą wystapić zera, bo jeżeli tak, wtedy program może nie działać do końca poprawnie, bo za kryterium końca tablicy przyjałeś wartość 0;
Kolejny problem to przypadek gdy oryginalna tablica zawiera komplet różnych liczb wtedy pętla
while(return_tab[new_size])new_size++;
może wyjść poza zakres tablicy.

Można spróbować
Znaleźć najmnieszy element tablicy wejściowej element_min i wpisać go tablicawyjściowa[0]
W pętli while (lub for) znajdywać kolejne elementy tablicy wejściowej większe od element_min
i podstwić je pod element_min wpisując jednocześnie do tablicawyjściowa[i++]
Warunkeim końca pętli jest brak w niej elementu większego od aktualnej wrtości element_min.
Na zakończenie tak jak miałeś przepisujesz tablicawyjściowa do tablicawejściowa, a *size = i
Przykładowy kod

Kod: Zaznacz cały

#include <stdio.h>

typedef unsigned int uint; 
 
void remove_dup(uint tab[], uint *size) { 
  uint return_tab[*size];
  uint i, imin = tab[0], imax = tab[0], imm;
  uint new_size = 0; 

  if (*size < 2) return;

  /* Szukamuy najmniejszego i największego elementu */
  for(i = 1; i < *size; i++) {
    if (tab[i] < imin)
      imin = tab[i];
    if (tab[i] > imax)
      imax = tab[i];
  }
  /* Podstawiamy wartość pierwszego elementu */
  return_tab[new_size++] = imin;
  /* Dodajemy kolejne elementy do tablicy tymczasowej return_tab */
  while (imin < imax) {
    imm = imax;
    for(i = 0; i < *size; i++)
      if ((tab[i] > imin) && (tab[i] < imm))
        imm = tab[i];
    imin = imm;
    return_tab[new_size++] = imin;
  }
  /* Ustalenie nowego rozmiaru */
  *size = new_size;
  /* Przepisanie zawartości */
  for(i = 0; i < *size; i++)
    tab[i] = return_tab[i];

  return;
} 

 
int main() {
  uint tab[] = {1,2,3,3,5,5,7,7,7,10,11,0,12,13};
  uint i, size = sizeof(tab) / sizeof(int);
  for (i = 0; i < size; i++)
    printf("%i ", tab[i]);
  puts("");
  remove_dup(tab, &size);
  for (i = 0; i < size; i++)
    printf("%i ", tab[i]);
  puts("");
  return 0;
}
soku11
Użytkownik
Użytkownik
Posty: 6607
Rejestracja: 16 sty 2007, o 19:42
Płeć: Mężczyzna
Podziękował: 119 razy
Pomógł: 1823 razy

Prosta funkcja usuwajaca zdublowane cyfry w tablicy - spr

Post autor: soku11 »

Rafal88K, dzieki, jednak ma to byc w C a nie cpp :P Co do posta smiechowca - tak tablica wejsciowa nie ma elementu zerowego :) A tak z ciekawosci - jak koniec tablcy typu int to kod o znaku 0 ('\0'), czy co?? Tzn jak to zapisac by obslugiwalo i 0??

Co do tego, ze wyjdzie poza zakres to nie za bardzo rozumiem :/

Kod: Zaznacz cały

while(return_tab[new_size])new_size++;
To ma z zalozenia zliczac ilosc elementow w tablicy return_tab wiec nie wiem co to ma wspolnego z typem cyfr w tablicy wejsciowej tab[*size]... Przeciez tworze tablice return_tab na tyle elementow co ma tab[*size]... Chyba ze cos przeoczylem to prosilbym o uswiadomienie :)
Twoj kod zaraz sprawdze :P Dzieki wszystkim za rady/podpowiedzi. POZDRO
smiechowiec
Użytkownik
Użytkownik
Posty: 374
Rejestracja: 21 cze 2007, o 11:28
Płeć: Mężczyzna
Lokalizacja: Łostowice
Pomógł: 146 razy

Prosta funkcja usuwajaca zdublowane cyfry w tablicy - spr

Post autor: smiechowiec »

soku11 pisze:jak koniec tablcy typu int to kod o znaku 0 ('\0'), czy co?? Tzn jak to zapisac by obslugiwalo i 0??
1. Tablice w C nie mają końca, jedynie do ciągów typu char[] dodajemy jako ostatni znak, znak o kodzie zero, więc rzeczywista długość tablicy jest równa strlen(tablica) + 1
a deklaracja
char tab[] = "abc";
oznacza formalnie
char tab[4] = "abc";
bo znak zero powinien należeć do łańcucha znaków.
2. Tablice typu int to obszar w pamięci, np
int tab[3]; to deklaracja trzech zmiennych typu int, nie ma dodatkowego elementu oznaczającego koniec tablicy, tuż za jedną zmienną tworzone są następne, a nazwa tablicy jest aliasem do adresu pierwszej zmiennej tablicy.
Przykładowy program

Kod: Zaznacz cały

#include<stdio.h>

int i;
int tab3[3] = {1,2,3};
int tab1[3] = {4,5,6};

int main(){
for(i = 0; i < 6; i++)
  printf("%i ", tab3[i]);
}
Wynik to
1 2 3 4 5 6
mimo że tab3 ma tylko 3 elementy.
soku11 pisze:Co do tego, że wyjdzie poza zakres to nie za bardzo rozumiem :/

Kod: Zaznacz cały

while(return_tab[new_size])new_size++;
Ja ten kod rozumiem tak
dopóki wartość elementu tablicy o indeksie new_size jest różna od zera zwiększaj indeks.
Więc, jeżeli w tablicy nie ma elementu zerowego, po dojściu do końca tablicy pętla wykracza poza obszar tablicy return_tab co sprawdziłem podstawiając ciąg kolejnych liczb naturalnych.
soku11
Użytkownik
Użytkownik
Posty: 6607
Rejestracja: 16 sty 2007, o 19:42
Płeć: Mężczyzna
Podziękował: 119 razy
Pomógł: 1823 razy

Prosta funkcja usuwajaca zdublowane cyfry w tablicy - spr

Post autor: soku11 »

Ok teraz rozumiem Wielkie dzieki jeszcze raz Niedlugo pewnie zaloze jeszcze jeden temat apropo poprawnosci dzialania kolejnej funkcji, bo cos mi sie nieraz program wiesza gdy sie jej uzyje za duzo razy :/ I tam rowniez licze na twoja pomoc, bo widze ze znasz sie na rzeczy. POZDRO
ODPOWIEDZ