Zadanie-Wartości losowe w tablicy dynamicznej

Zadanie-Wartości losowe w tablicy dynamicznej
K1
  • Rejestracja:prawie 10 lat
  • Ostatnio:ponad 9 lat
  • Postów:16
0

Witam
Potrzebuje napisać program w którym funkcja generuje dwie tablice dynamiczne,wypełnia je wartościami losowymi od 0 do 5 tak aby były od razu posortowane.Program ma wyświetlać te dwie tablice.
[C]

Kopiuj
 
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int tworzenie(int rozmiar,int rozmiar1,int *wsk,int *wsk1)
{
	int i;
	wsk=(int*)malloc(rozmiar*sizeof(int));
	if(wsk==NULL)
	return -1;	
	wsk1=(int*)malloc(rozmiar1*sizeof(int));
	if(wsk==NULL)
	return -1;	
	srand(time(0));
	for (i=0;i<rozmiar;i++)
	{
		wsk[i]=rand() % 6+i;
		printf("%d ",wsk[i]);	
	}
	for(i=0;i<rozmiar1;i++)
	{
		wsk1[i]=rand() % 6+i;
		printf("%d ",wsk1[i]);	
	}
        free(wsk);
	free(wsk1);

}
int main() 
{
	
	int r,r1,*w1,*w2;
	printf("Podaj rozmiar pierwszej tablicy ");
	scanf("%d",&r);
	fflush(stdin);
	printf("Podaj rozmiar drugiej tablicy ");
	scanf("%d",&r1);
	fflush(stdin);
	tworzenie(r,r1,*w1,*w2);

	return 0;
	system("pause"); 
}



Program przestaje działać po podaniu rozmiarów tablic.Z góry dzięki za pomoc.

twonek
  • Rejestracja:prawie 11 lat
  • Ostatnio:prawie 2 lata
  • Postów:2500
0
Kopiuj
tworzenie(r,r1,*w1,*w2);

Powinno być

Kopiuj
tworzenie(r, r1, w1, w2);

bo w tej chwili przekazujesz jakieś śmieciowe wartości pod adresami wskazanymi przez w1 i w2.
Drugą sprawą jest, po co przekazujesz te wskaźniki? Funkcja tworzenie() może operować na lokalnych wskaźnikach, a te przekazane są bezużyteczne bo i tak operujesz na ich kopii.

K1
  • Rejestracja:prawie 10 lat
  • Ostatnio:ponad 9 lat
  • Postów:16
0

Ok rozumiem.Program działa lecz dalej mam problem z tym losowaniem ponieważ liczby nie są z przedziału 0-5 oraz tablica nie jest posortowana.
Mam jeszcze pytanie jak zrobić ten program alby wyświetlanie tablic odbywało się w funkcji main() a nie w funkcji tworzenie()

Kopiuj
 
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int tworzenie(int rozmiar,int rozmiar1)
{
	int *wsk,*wsk1;
	int i;
	wsk=(int*)malloc(rozmiar*sizeof(int));
	if(wsk==NULL)
	return -1;	
	wsk1=(int*)malloc(rozmiar1*sizeof(int));
	if(wsk==NULL)
	return -1;	
	srand(time(0));
	for (i=0;i<rozmiar;i++)
	{
		wsk[i]=rand() % 6+i;
		printf("%d ",wsk[i]);	
	}
	printf("\nDruga tablica ");
	for(i=0;i<rozmiar1;i++)
	{
		wsk1[i]=rand() % 6+i;
		printf("%d ",wsk1[i]);	
	}
	free(wsk);
	free(wsk1);

}
int main() 
{
	
	int r,r1;
	printf("Podaj rozmiar pierwszej tablicy ");
	scanf("%d",&r);
	fflush(stdin);
	printf("Podaj rozmiar drugiej tablicy ");
	scanf("%d",&r1);
	fflush(stdin);
	tworzenie(r,r1);

	return 0;
	system("pause"); 
}



TomaszLiMoon
  • Rejestracja:prawie 10 lat
  • Ostatnio:dzień
  • Postów:530
0

Liczby z przedziału 0-5 uzyskujesz za pomocą

Kopiuj
  
 wsk[i] = rand() % 6 ;

Cały kod można też rozbić na dwie funkcje:

Kopiuj
 
int* tworzenie( int rozmiar )
{
    int* wsk=(int*)malloc(rozmiar*sizeof(int));
    if(wsk==NULL) return NULL;    
 
    srand(time(0));
    for (i=0;i<rozmiar;i++)
     {
        wsk[i]=rand() % 6;
     }
    return wsk;   
}

void przegladaj( int *tablica , int rozmiar )
{
 if( tablica !=NULL )
  {
   for(i=0;i<rozmiar;i++)
    {       
      printf("%d ",tablica[i]);    
    }
   free(tablica); 
  }
}

int main() 
{
 
    int rozmiar1,rozmiar2;
    printf("Podaj rozmiar pierwszej tablicy ");
    scanf("%d",&rozmiar1);
    fflush(stdin);
    printf("Podaj rozmiar drugiej tablicy ");
    scanf("%d",&rozmiar2);
    fflush(stdin);
  
    przegladaj( tworzenie(rozmiar1), rozmiar1 );  
    przegladaj( tworzenie(rozmiar2), rozmiar2 );
 
    return 0;
    system("pause"); 
}
bogdans
Moderator
  • Rejestracja:prawie 17 lat
  • Ostatnio:prawie 5 lat
0

Ja bym w ogóle nie losował liczb w tablicy. Losowałbym pozycję ostatniego zera, ostatniej jedynki,...


To smutne, że głupcy są tak pewni siebie, a ludzie mądrzy - tak pełni wątpliwości. Bertrand Russell
edytowany 2x, ostatnio: bogdans
K1
  • Rejestracja:prawie 10 lat
  • Ostatnio:ponad 9 lat
  • Postów:16
0

Potrzebuje jeszcze dopisać funkcję która połączy te dwie tablice w jedną.Próbowałem to zrobić ale coś nie działa jak powinno.
Z góry dzięki za pomoc :)

Kopiuj
 
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int* tworzenie(int rozmiar)
{
    int i;
	int* wsk=(int*)malloc(rozmiar*sizeof(int));
    if(wsk==NULL) 
	printf("Alokacja nie powiodla sie/n");    
    srand(time(0));
    for (i=1;i<rozmiar;i++)
     {
        wsk[0]=rand() % 6;
		wsk[i]=wsk[i-1]+(rand() % 6);
     }
    return wsk;   
}
 
void przegladaj( int *tablica , int rozmiar )
{
int i;
 if( tablica!=NULL )
  {
   for(i=0;i<rozmiar;i++)
    {       
      printf("%d ",tablica[i]);    
    }
   free(tablica); 
  }
}
int* laczenie(int *tablica,int *tablica1,int *tablica3,int rozmiar1,int rozmiar2)
{
	int i;
	for(i=0; i<rozmiar1;i++) 
	tablica3[i+rozmiar1]=tablica1[i]; 
	return tablica3;
}

int main() 
{
	
	int r1,r2;
	printf("Podaj rozmiar pierwszej tablicy ");
	scanf("%d",&r1);
	fflush(stdin);
	printf("Podaj rozmiar drugiej tablicy ");
	scanf("%d",&r2);
	fflush(stdin);
	printf("Tablica pierwsza\n");
	przegladaj(tworzenie(r1),r1);
	printf("\nTablica druga\n");  
    przegladaj(tworzenie(r2),r2);
	
	printf("\nTablica polaczona\n");
	przegladaj(laczenie(tworzenie(r1),tworzenie(r2),tworzenie(r1+r2+1),r1,r2),r1+r2+1);  
	
	return 0;
	system("pause"); 
}

bogdans
Moderator
  • Rejestracja:prawie 17 lat
  • Ostatnio:prawie 5 lat
0

Twój kod jest błędny - utworzone tablice nie spełniają warunków zadania. Jeśli nie chcesz skorzystać z mojego pomysłu (bardzo zmniejsza losowań - przy tablicy o mln. elementów będzie 5 losowań zamiast miliona), to zmień swój kod:

Kopiuj
    wsk[0]=rand() % 6;
    for (i=1;i<rozmiar;i++)
     {
        wsk[i]=wsk[i-1]+(rand() % (6-wsk[i-1]));
     }
    return wsk;

To smutne, że głupcy są tak pewni siebie, a ludzie mądrzy - tak pełni wątpliwości. Bertrand Russell
K1
  • Rejestracja:prawie 10 lat
  • Ostatnio:ponad 9 lat
  • Postów:16
0

Ja bym w ogóle nie losował liczb w tablicy. Losowałbym pozycję ostatniego zera, ostatniej jedynki,...

Nie bardzo rozumiem jak mam zrobić to losowanie. Mógłbyś mi to jakoś rozjaśnić?

bogdans
Moderator
  • Rejestracja:prawie 17 lat
  • Ostatnio:prawie 5 lat
0

Algorytm poniżej jest trochę inny, losuje kolejno: ile zer, ile jedynek,...,ile czwórek. Jeśli suma tych ilości jest mniejsza od rozmiaru tablicy, to na końcu piszę piątki.

Kopiuj
    int filled = 0;
    int howMany;
    for(i=0;i<5;i++)
    {
        howMany = rand() % (rozmiar - filled);
        for(int j=filled;j<filled+howMany;j++)
        {
            wsk[j] = i;
        }
        filled+=howMany;
    }
    for(int j=filled;j<rozmiar;j++)
    {
        wsk[j] = 5;
    }

Nie znam funkcji srand, ale jeśli instrukcja srand(time(0)); jest wewnątrz funkcji tworzenie, to wylosowane tablice są identyczne. Przenieś te instrukcję do maina.


To smutne, że głupcy są tak pewni siebie, a ludzie mądrzy - tak pełni wątpliwości. Bertrand Russell
TomaszLiMoon
  • Rejestracja:prawie 10 lat
  • Ostatnio:dzień
  • Postów:530
0

Algorytm losujący liczbę zer, jedynek itp. nie daje rozkładu losowego.
Wartość oczekiwaną dla poszczególnych liczb nie jest taka sama.
Na przykład zer jest zbyt dużo w stosunku do piątek.

bogdans
Wiem, ale jest wymóg wypełnia je wartościami losowymi od 0 do 5 tak aby były od razu posortowane. Algorytm autora: losujemy pierwszą liczbę, potem nie mniejszą drugą,... daje jeszcze mniej losowe rozkłady.
K1
  • Rejestracja:prawie 10 lat
  • Ostatnio:ponad 9 lat
  • Postów:16
0

Zostanę jednak przy rand(). Czy mógłby ktoś zerknąć na tą funkcję laczenie() bo coś tam w pętli jest zepsute i zwraca zupełnie coś innego.
Dzięki :)

bogdans
Twój wybór, ale Twój algorytm daje jeszcze mniej losowe rozkłady.
bogdans
Moderator
  • Rejestracja:prawie 17 lat
  • Ostatnio:prawie 5 lat
0

O co Ci chodzi w tym wierszu?

Kopiuj
przegladaj(laczenie(tworzenie(r1),tworzenie(r2),tworzenie(r1+r2+1),r1,r2),r1+r2+1);
  • dlaczego rozmiar połączonej tablicy to r1+r2+1, powinno być r1+r2,
  • dlaczego wywołujesz tworzenie(r1) i tworzenie(r1), utworzysz przecież nowe tablice różne od tych, które utworzyłeś i wyświetliłeś wcześniej.

To smutne, że głupcy są tak pewni siebie, a ludzie mądrzy - tak pełni wątpliwości. Bertrand Russell
edytowany 1x, ostatnio: bogdans
K1
  • Rejestracja:prawie 10 lat
  • Ostatnio:ponad 9 lat
  • Postów:16
0

Ok faktycznie tworze przecież nowe tablice-oczywisty błąd. Tylko w jaki sposób mam przekazać do funkcji łączenie tablice które będą wcześniej utworzone przez funkcję tworzenie- z tym mam największy problem.

bogdans
Moderator
  • Rejestracja:prawie 17 lat
  • Ostatnio:prawie 5 lat
0

W C++ jestem początkujący, więc kod jest pewnie naiwny i nieelegancki.

Kopiuj
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int* tworzenie(int rozmiar)
{
    int i;
    int* wsk = (int*)malloc(rozmiar*sizeof(int));
    if(wsk == NULL)
        printf("Alokacja nie powiodla sie/n");

    /*wsk[0]=rand() % 6;
    for (i=1;i<rozmiar;i++)
     {

        wsk[i]=wsk[i-1]+(rand() % (6-wsk[i-1]));
     }*/

    int filled = 0;
    int howMany;
    for(i=0;i<5;i++)
    {
        howMany = rand() % (rozmiar - filled);
        //printf("%d ",howMany);
        for(int j=filled;j<filled+howMany;j++)
        {
            wsk[j] = i;
        }
        filled+=howMany;
    }
    for(int j=filled;j<rozmiar;j++)
    {
        wsk[j] = 5;
    }
    return wsk;
}

void przegladaj(int *tablica , int rozmiar)
{
    int i;
    if( tablica!=NULL )
    {
        for(i=0;i<rozmiar;i++)
        {
            printf("%d ",tablica[i]);
        }
        free(tablica);
    }
}
int* laczenie(int *tab1,int *tab2,int rozmiar1,int rozmiar2)
{
    int* wsk = (int*)malloc((rozmiar1+rozmiar2)*sizeof(int));
    if(wsk == NULL)
        printf("Alokacja nie powiodla sie/n");
    int i1 = 0;
    int i2 = 0;
    int i = 0;
    while(i1 < rozmiar1 && i2 < rozmiar2)
    {
        if(tab1[i1] <= tab2[i2])
        {
            wsk[i] = tab1[i1];
            i1++;
        }
        else
        {
            wsk[i] = tab2[i2];
            i2++;
        }
        i++;
    }
    while(i1 < rozmiar1)
    {
        wsk[i] = tab1[i1];
        i1++;
        i++;
    }
    while(i2 < rozmiar2)
    {
        wsk[i] = tab2[i2];
        i2++;
        i++;
    }
    return wsk;
}

int main()
{

    int r1,r2;
    srand(time(0));
    printf("Podaj rozmiar pierwszej tablicy ");
    scanf("%d",&r1);
    fflush(stdin);
    printf("Podaj rozmiar drugiej tablicy ");
    scanf("%d",&r2);
    fflush(stdin);
    int* tab1 = tworzenie(r1);
    printf("Tablica pierwsza\n");
    przegladaj(tab1,r1);
    printf("\nTablica druga\n");
    int* tab2 = tworzenie(r2);
    przegladaj(tab2,r2);

    printf("\nTablica polaczona\n");
    przegladaj(laczenie(tab1,tab2,r1,r2),r1+r2);

    return 0;
}

To smutne, że głupcy są tak pewni siebie, a ludzie mądrzy - tak pełni wątpliwości. Bertrand Russell
fasadin
1. Autor chyba chcial tylko w C. 2. Skoro w C to nie mozna deklarowac zmiennych w petli. 3. Skoro C++ to lepiej uzywac new/delete cout cin oraz includy nie powinny byc cstdio zamiast stdio.h
Endrju
Pewnie, że w C można zadeklarować zmienne w pętli. Obudź się, jest 21 wiek, czasy C90 minęły.
fasadin
racja ;)
katelx
@fasadin przed chwila mi wmawiales ze w c jest inline a tu taka wtopa... ;)
Endrju
Przecież w C JEST inline. :-/ (Uwaga: nie działa tak samo w jak w C++)
fasadin
Kazdy sie myli, warto wyjasniac. Nie odczuwalem tego jako wtopa tylko odczuwam to jako lekcje ;) Dlatego specjalnie zalinkowalem do komentarza Endrju " Obudź się, jest 21 wiek, czasy C90 minęły.". Wiec pisanie ze w C nie ma inline jest tak samo prawdziwe ze w forze nie mozna deklarowac zmiennych ;) Bylo to prawda ale jakies 25 lat temu
katelx
@fasadin byla wtopa, moja z tym inline
fasadin
wtopa nie wtopa, nie wazne ;) wazne, ze kazdy ma takie samo zdanie jezeli chodzi o inline :)

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.