Wskazniki - maksymalna i minimalna wartość w tablicy

0

Witam, zaczynam naukę wskaźników w c++ i mam problem w zadaniu.. Jednym z moich zadań jest znalezienie maksymalnego i minimalnego elementu w tablicy. Kod się kompiluję, ale niestety wyniki nie są zadowalające..

#include <iostream>
#include <cstdlib>

using namespace std;

void maxi(int *wsk ,int rozmiar);

void wypisz(int tab[], int rozmiar);
void wczytaj(int tab[], int rozmiar);

int main(int argc, char *argv[])
{

    int rozmiar;
    cout<<"Ile elementow ma miec tablica?"<<endl;
    cin>>rozmiar;

    int *tab= new int[rozmiar];  

     wczytaj( tab,rozmiar);
     wypisz(tab,rozmiar);
     maxi(tab,rozmiar);

    delete [] tab;

    return 0;
}
//*********************************
void wczytaj(int tab[], int rozmiar){

for (int i=0; i<rozmiar; i++)
        tab[i]=rand()/100;
}

//********************************

void wypisz(int tab[], int rozmiar){

    for(int i=0; i<rozmiar; i++)
        cout<<tab[i]<<endl;
}

//********************8
void maxi(int *wsk, int rozmiar){

   int *maxi;
   maxi=wsk;   // ustawienie maxi na początek tablicy
   int *mini;
   mini=wsk;   

    for(int i=0; i<rozmiar;i++){
        if ( *(maxi++) < *(wsk++)  )   {
        maxi = wsk;
   }

}
   cout<<"maksymalna wartosc to:"<<*maxi<<endl;   
   
   
   for(int i=0; i<rozmiar;i++){
        if ( *(mini++) > *(wsk++)  )   {
        mini = wsk;
   }

}
   cout<<"minimalna wartosc to:"<<*mini<<endl;         
   
}
0

Za bardzo chciałeś przykozaczyć i robisz ++ na wskaźniku wsk za wcześnie. Bo wewnatrz ifa masz już przesunięte wskaźniki. Poza tym na mini i maxi NIE powinieneś robić żadnego ++!

0

No racja, w ifie już mam przesunięcie.. usunąłem ++ ale efekt taki sam jak wcześniej..

0

Zrobiłem tak, teraz jest ok?

#include <iostream>
#include <cstdlib>

using namespace std;

void maxi(int *wsk ,int rozmiar);

void wypisz(int tab[], int rozmiar);
void wczytaj(int tab[], int rozmiar);

int main(int argc, char *argv[])
{

    int rozmiar;
    cout<<"Ile elementow ma miec tablica?"<<endl;
    cin>>rozmiar;

    int *tab= new int[rozmiar];   

     wczytaj( tab,rozmiar);
     wypisz(tab,rozmiar);
     maxi(tab,rozmiar);

    delete [] tab;

    return 0;
}
//*********************************
void wczytaj(int tab[], int rozmiar){

for (int i=0; i<rozmiar; i++)
        tab[i]=rand()/100;
}

//********************************

void wypisz(int tab[], int rozmiar){

    for(int i=0; i<rozmiar; i++)
        cout<<tab[i]<<endl;
}

//********************8
void maxi(int *wsk, int rozmiar){

   int *maxi;
   maxi=wsk;   // ustawienie maxi na początek tablicy
   int *mini;
   mini=wsk;   

    for(int i=0; i<rozmiar;i++,wsk++){
        if ( *(maxi) < *(wsk)  )   {
        (maxi) = (wsk);
   }

}
   cout<<"maksymalna wartosc to:"<<*maxi<<endl;   
   
   
   for(int i=0; i<rozmiar;i++,wsk++){
        if ( *(mini) > *(wsk)  )   {
        mini = wsk;
   }

}
   cout<<"minimalna wartosc to:"<<*mini<<endl;         
   
}

Jednak nie liczy dobrze wartości minimalnej..

0

Po pierwszej pętli twój wskaźnik ustawiony jest na ostatni element w tablicy, dlatego iterując dalej po wsk wychodzisz poza jej zakres; w drugiej pętli możesz dekrementować wskaźnik co sprawi, że cofniesz się do adresu początkowego i ponownie przejrzysz wszystkie elementy w tablicy.

tak na marginesie,
w funkcji inicjalizującej dane, dodaj nad pętlą srand(time(NULL)) :)

0

Zrobiłem w jednej pętli i działa dobrze, a jak zrobię drugą pętle tak jak niżej, to raz działa dobrze, a raz nie.. (np. jeżeli wpiszę, że rozmiar ma być 8 to znajduję element najmniejszy)

 for(int i=rozmiar; i>0;i--,wsk--){
        if ( *(mini)  > *(wsk)  )   {
        mini = wsk;
   }

Bo chyba bardziej mi zależy na tym drugim sposobie, bo dalej mam napisać funkcję sortowania też w oparciu o ten wskaźnik.

0

Za bardzo kombinujesz z tymi wskaźnikami. min i max trzymaj w zwykłym int, dlaczego to są wskaźniki?

std::pair<int, int> minmax(int* tab, size_t size) {
    assert(size > 0);
    int max_val, min_val;
    max_val = min_val = *tab;
    for (size_t i = 1; i < size; ++i, ++tab) {
        if (max_val < *tab) {
            max_val = *tab;
        } else if (min_val > *tab) {
            min_val = *tab;
        }
    }
    return std::make_pair(min_val, max_val);
}
0

Bo mam za zadanie to na wskaźnikach robić..
Dodałem jeszcze funkcję sortującą, tylko mi nie sortuje, bo pewnie wskaźnik jest źle ustawiony.. element min i max dobrze znajduje.

#include <iostream>
#include <cstdlib>
#include <ctime>
 
using namespace std;
 
void maxi(int *wsk ,int rozmiar);
 
void wypisz(int tab[], int rozmiar);
void wczytaj(int tab[], int rozmiar);
 void sortuj( int *wsk, int rozmiar);
void posortowana(int *wsk, int rozmiar);
int main(int argc, char *argv[])
{
 	srand(time(NULL));
    int rozmiar;
    cout<<"Ile elementow ma miec tablica?"<<endl;
    cin>>rozmiar;
 
    int *tab= new int[rozmiar];   
 
     wczytaj( tab,rozmiar);
     wypisz(tab,rozmiar);
     maxi(tab,rozmiar);
 
 	 sortuj(tab, rozmiar);
  	  posortowana(tab,rozmiar);
    delete [] tab;
 
    return 0;
}
//*********************************
void wczytaj(int tab[], int rozmiar){
 
for (int i=0; i<rozmiar; i++)
        tab[i]=rand()/100;
}
 
//********************************
 
void wypisz(int tab[], int rozmiar){
 
    for(int i=0; i<rozmiar; i++)
        cout<<tab[i]<<endl;
}
 
//********************8
void maxi(int *wsk, int rozmiar){
 
   int *maxi;
   maxi=wsk;   // ustawienie maxi na początek tablicy
   int *mini;
   mini=wsk;   
 
    for(int i=0; i<rozmiar;i++,wsk++){
        if ( *(maxi) < *(wsk)  )   {
        (maxi) = (wsk);
   }
   
   else if ( *(mini)  > *(wsk) )
 mini = wsk;
}
   
 
  cout<<"maksymalna wartosc to:"<<*maxi<<endl;   
   cout<<"minimalna wartosc to:"<<*mini<<endl;         
 
}
 //**************************************************
void sortuj( int *wsk, int rozmiar){
	bool wszystko=false;    // ustawienie zmiennej wszystko na false
	int temp;  // zmienna pomocnicza
	
	while(wszystko == false){    // rob dopoki wszystko = false, czyli dopoki tablica jest nieuporządkowana
		wszystko=true;           
		
		for(int i=1; i<rozmiar; i++){
			if( *(wsk+i) < *(wsk) ){
				wszystko=false;
				temp=*(wsk+i);
				*(wsk+i)=*(wsk);
				*(wsk)=temp;					
			}						
		}		
		
	}
					
}

//*********************************************
void posortowana(int *wsk, int rozmiar){
	cout<<"Tablica po sortowaniu:"<<endl;
    
    for(int i=0; i<rozmiar; i++)
        cout<<*(wsk+i)<<endl;
	
0

Na pewno ta funkcja ma robic AZ 2 rzeczy? Bo dla mnie to totalna bzdura.
http://ideone.com/LeyOk2

0

Nie rozumiem o co Ci chodzi.. funkcja znajdująca min i max działa dobrze (pewnie ta, którą podałeś działa lepiej ?).. Problem jest chyba w sortowaniu.

0

Ok, już rozumiem o co chodzi (jednak między wypisaniem, a znalezieniem jest spora różnica). A co do sortowania to mam taką funkcję, która działa dobrze :

void sortuj( int tab[], int rozmiar){
	bool wszystko=false;    // ustawienie zmiennej wszystko na false
	int temp;  // zmienna pomocnicza
	
	while(wszystko == false){    // rob dopoki wszystko = false, czyli dopoki tablica jest nieuporządkowana
		wszystko=true;           
		
		for(int i=0; i<rozmiar; i++){
			if( tab[i+1]<tab[i]){
				wszystko=false;
				temp=tab[i+1];
				tab[i+1]=tab[i];
				tab[i]=temp;					
			}						
		}		
		
	}
					
}

Chciałem ją przerobić żeby na wskaźnikach można ją było zaimplementować.

0

Ok, a jak można by to zrobić korzystając ze wskaźnika int wsk ? Kolega Rooy napisał, że ten wskaźnik będzie pokazywał na ten sam element, jednak tego nie widzę.. przecież pętla for przechodzi kolejną iterację i wraz z nią wskaźnik też się zwiększa ((wsk+i))..

0

No racja.. czyli nie da rady tego zrobić korzystając z tego wskaźnika int *wsk?

0

Dobra rada ;) Zrobiłem tak, że dodałem kolejną zmienną (u) wewnątrz pętli for- tak, że "i" zmienia się od 1, a "u" od 0, czyli zapewnia to, że oba wskaźniki się przesuwają. Myślę, ze nie jest to najgorsze rozwiązanie.. (program dobrze działa).

A tak przy okazji, wie ktoś może jak wygląda sortowanie bąbelkowe dla tablicy np. dwuwymiarowej (bo na razie napotykam się tylko na jednowymiarowe..)

0

Tak samo tylko że porównujesz/wymieniasz dwa wiersze (ewentualnie kolumny) zamiast dwóch liczb.

0

No to np. chciałbym posortować tablicę względem wierszy, rosnąco. Zrobiłem tablicę dynamiczną i mam do niej funkcję (wczytaj- jej wielkość), wypisz i nie wiem jak ją posortować.

funkcję deklaruję np. tak:

void wczytaj(int** tablica, int wiersze, int kolumny);

A mam problem z denicją (znalazłem taki algorytm http://algorytmy.info/~jendrek/KodKontroler/kod/263/?PHPSESSID=74c5e45fa71743faa5e34ad5e302d85e )
Ale nie nie potrafię przełożyć do swojego programu.. Wcześniej w programie podałem już ilość wierszy i kolumn.

void wczytaj(int** tablica, int wiersze, int kolumny){

int i,j;
  
for(int j=0;j<kolumny;j++)
	    {
         for(int k=0;k<wiersze-1;k++)    //sortowanie bąbelkowe
	                {
	                 
	                for(int i=0;i<wiersze;i++){	
             
	             if(tablica[i][j]>tablica[i+1][j]){

	              	   int temp=tablica[i][j];
	                tablica[i][j]=tablica[i+1][j];
	                tablica[i+1][j]=temp;
	          }
	         }
	       }
	    }
0

Zrobiłem sortowanie dla tablic statycznych i wszystko gra.. czyli pewnie z tymi wskaźnikami znowu coś nie gra.. No i mały błąd chyba jest w 2 pętli for.. powinno k się zwiększać do elementu o 1 mniejszego niż ilość kolumn (tyle będzie maksymalnie zamian miejscami elementów tablicy w każdym wierszu).

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