• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

question-closed Program ma za zadanie wylosować numerek z dziennika wykluczając z losowania numery nieobecnych osób.

Object Storage Arubacloud
0 głosów
1,339 wizyt
pytanie zadane 4 lutego 2019 w C i C++ przez Trzeci Nowicjusz (220 p.)
zamknięte 10 stycznia 2020 przez Trzeci
#include <iostream>
#include <stdlib.h>
#include <time.h>
using namespace std;

int main()
{
    int ile_uczniow,ile_nieobecnych,losowanie,numerek[ile_nieobecnych],x;

    cout << "Podaj ilosc uczniow: ";
    cin>>ile_uczniow;

    cout << "Podaj ilosc nieobecnych uczniow: ";
    cin>>ile_nieobecnych;
    cout <<endl;


    for(int i=0; i<=ile_nieobecnych; i++)

    {
        cout<<"Podaj numerek:";
        cin>>numerek[i];

    }


    cout <<endl;
    x = ile_uczniow - ile_nieobecnych;


    while(losowanie!=numerek)
    {
        srand(time(NULL));
        losowanie = rand()%x+1;
    }


    cout <<"Wylosowany numer to: "<<losowanie;
    cin.get();
    return 0;
}

W czym tkwi błąd???Czy jest inny sposób na wykluczenie liczb z losowania??? błąd występuje w pętli while

komentarz zamknięcia: ...
komentarz 4 lutego 2019 przez mokrowski Mędrzec (155,460 p.)

Tu masz raczej błędy koncepcyjne. Kilka pytań:

1. Co jeśli wprowadzę ilość nieobecnych większą niż uczniów?

2. Jeśli losujesz nieobecnego, następny nieobecny będzie z pozostałych uczniów. Jeśli będziesz losował nieobecnych ze wszystkich uczniów, będziesz miał błąd wylosowania ucznia który już jest nieobecny ("gubisz jednego nieobecnego")

Chyba zgadzasz się że: ilość_nieobecnych + ilość_obecnych == ilość_uczniów ?

 

komentarz 4 lutego 2019 przez Trzeci Nowicjusz (220 p.)
A masz  jakiś pomysł na ten kod???Z góry dziękuje za pomoc ;)
komentarz 4 lutego 2019 przez Mavannkas Bywalec (2,290 p.)
Zaraz go dokleję do mojej odpowiedzi :)

1 odpowiedź

0 głosów
odpowiedź 4 lutego 2019 przez Mavannkas Bywalec (2,290 p.)
wybrane 4 lutego 2019 przez Trzeci
 
Najlepsza

Tablica nie ma wartości zdefiniowanej podczas tworzenia. Podczas tworzenia tablicy jej wielkość jest losowa. (8 linia)

srand nie powinno być w pętli bo się krzaczy ;-) (33 linia)

x nie powinno być granicą losowania, przecież jeśli nie ma 4 osób np 1,2,3,4 to dalej może być osoba z nr 30 co nie? (28 linia)

W warunku kończącym pętle nie masz żadnej zmiennej odpowiadającej za przechodzenie po tablicy "numerek" intiger nie może być porównany do wskaźnika (wszystko wywala kompilator)(31 linia)

Zdefiniuj ją po wczytaniu ilości nieobecnych. A poza tym aby program działał poprawnie polecam wczytanie wszystkich numerów, wylosowanie liczby od 1 do 30 i późniejsze sprawdzanie czy wylosowany numer przypadkiem nie jest w tablicy nieobecnych,

#include <iostream>
#include <ctime>
#include <cstdlib>
int load()
{
    int bufor;
    while(true)
    {
        std::cin>>bufor;
        if(!std::cin.fail())
            break;
        std::cin.clear();
        std::cin.ignore(1000,'\n');
        std::cout<<"Wartosc nie jest liczba\n";
    }
    return bufor;

}
int main ()
{
    srand(time(NULL));
    int maxPupil, absPupil,* T=nullptr, siz=0;
    std::cout<<"Podaj ile uczniow jest w klasie (liczac nieobecnych) ";
    maxPupil=load();
    std::cout<<"Podaj numery nieobecnych uczniow (jak skonczysz wprowadz 0) ";
    while( true )
    {
        absPupil=load();
        if( absPupil == 0 )
             break;
        if(!(absPupil>0&&absPupil<=maxPupil))
        {
            std::cout<<"Zly numer\n";
            continue;
        }
        int * nw = new int[ siz + 1 ];
        for( int i = 0; i < siz; ++i )
             nw[ i ] = T[ i ];
        nw[ siz ] = absPupil;
        delete[] T;
        T = nw;
        siz++;
    }
    int ran;
    bool flage=true;
    while(flage)
    {
        flage=false;
       ran=std::rand()%maxPupil+1;
       for(int i=0;i<siz;i++)
        if(T[i]==ran)
        {
         flage=true;
         break;
        }
    }
    std::cout<<"Szczesliwy numerek to... "<<ran;
}

 

komentarz 4 lutego 2019 przez Mavannkas Bywalec (2,290 p.)

@Trzeci, Fajne obejście problemu haha. W 50 linii masz wylonczyc zamiast wyłączyć. I zamiast if wykorzystaj switch-case

komentarz 4 lutego 2019 przez sebeks Mądrala (5,300 p.)

@mokrowski, Jak to czytałem to najpierw przyszła mi na myśl funkcja rekurencyjna, która losuje osobę z tablicy. Sprawdza czy osoba jest obecna jeśli tak to zwraca jej numer(index), a jeśli nie to wywołuje się jeszcze raz. Jednak faktycznie takie działanie może wiele razy trafiać w osobę nieobecną. Np .przypadek grypy w klasie i wielu nieobecnych uczniów. Więc przyszło mi do głowy inne rozwiązanie. Mamy tablicę osób obecnych i nieobecnych. Robimy funkcję filtrującą i najpierw wyciągamy z tej tablicy tylko osoby obecne do nowej dynamicznej tablicy, potem mierzymy długość nowej tablicy i losujemy osobę z nowej tablicy zawierającej tylko osoby obecne. Co sądzisz o takim rozwiązaniu?

komentarz 4 lutego 2019 przez mokrowski Mędrzec (155,460 p.)

@sebeks, w proponowanym rozwiązaniu będziesz miał bardzo wiele realokacji pamięci i .. 3 tablice!

@Mavannkas, ze względu na brak determinizmu czyli to co pisałem wcześniej. Nie widzę sensu czepiania się szczegółów w kodzie... 

No dobrze... napiszę uproszczony problem i  opatrzony komentarzami... zastrzegam że to nie jest dobry styl pisania ale mam przekazać ideę:

#include <iostream>
#include <cstdlib>
#include <ctime> // Dla ew. zasiewu generatora.

int main() {
	unsigned ilosc_uczniow;
	unsigned ilosc_nieobecnych;
	unsigned indeks_szczesciarza;

	// Zasiew generatora (zresztą bardzo kiepskiego)
	// https://www.youtube.com/watch?v=LDPMpc-ENqY
	srand(0); // Tu zmieniaj liczby jeśli chcesz by wyniki były powtarzalne lub podaj time(NULL) wtedy "losowe"

	std::cout << "Podaj ilość uczniów: ";
	std::cin >> ilosc_uczniow;
	// TODO: Kontrola poprawności wprowadzonych danych...
	std::cout << "Podaj ilu uczniów jest nieobecnych: ";
	std::cin >> ilosc_nieobecnych;
	// TODO: Kontrola poprawności wprowadzonych danych...
	if (ilosc_uczniow < ilosc_nieobecnych) {
		std::cerr << "Jeśli jest więcej nieobecnych niż uczniów, kogo chcesz wylosować?\n";
		exit(EXIT_FAILURE);
	} else if (ilosc_uczniow == ilosc_nieobecnych) {
		std::cerr << "Jeśli wszyscy są nieobecni, kogo chcesz wylosować?\n";
		exit(EXIT_FAILURE);
	}

	// Dynamiczne tworzenie tabeli uczniów o podanej w trakcie działania wielkości.
	unsigned * uczniowie = new unsigned[ilosc_uczniow]; // Uwaga: jest new, powinno pod koniec programu pojawić się delete
	// Wypełnienie tabeli numerami uczniów, numer zgodny z indeksem w tabeli.
	for (unsigned i = 0; i < ilosc_uczniow; ++i) {
		uczniowie[i] = i;
	}

	// Pętla wybierania nieobecnych, losuje z zakresu zmniejszającego się po każdym wybraniu nieobecnego.
	// Nieobecny jest zamieniany z obecnym na końcu tabeli.
	for (unsigned i = 0; i < ilosc_nieobecnych; ++i) {
		// To załatwia wybór nieobecnych z malejącego zakresu.
		unsigned indeks_nieobecnego = rand() % (ilosc_uczniow - i);
		// indeks "na końcu tabeli", - 1 bo poprawne indeksy to [0, ilosc_uczniow)
		unsigned indeks_docelowy = ilosc_uczniow - i - 1;
		// Zamiana uczniów. Nieobecny wędruje na koniec tabeli, w jego miejsce wstawiany 
		// jest ten z końca.
		unsigned numer_ucznia = uczniowie[indeks_nieobecnego];
		uczniowie[indeks_nieobecnego] = uczniowie[indeks_docelowy];
		uczniowie[indeks_docelowy] = numer_ucznia;
	}

	// Po tych operacjach masz w zakresach:
	// - [0, ilosc_uczniow - ilosc_nieobecnych - 1] - obecnych uczniów
	// - [ilosc_uczniow - ilosc_nieobecnych, ilosc_uczniow - 1] - nieobecni uczniowie.
	
	// Wypisanie uczniów obecnych
	std::cout << "Obecni uczniowie   : ";
	for (unsigned i = 0; i < (ilosc_uczniow - ilosc_nieobecnych); ++i) {
		std::cout << uczniowie[i] << ' ';
	}
	std::cout << '\n';

	// Wypisanie uczniów nieobecnych
	std::cout << "Nieobecni uczniowie: ";
	for (unsigned i = ilosc_uczniow - ilosc_nieobecnych; i < ilosc_uczniow; ++i) {
		std::cout << uczniowie[i] << ' ';
	}
	std::cout << '\n';

	indeks_szczesciarza = rand() % (ilosc_uczniow - ilosc_nieobecnych);
	
	std::cout << "Szczęściarzem jest : " << uczniowie[indeks_szczesciarza] << '\n';

	delete [] uczniowie;

	return EXIT_SUCCESS;
}

 

komentarz 5 lutego 2019 przez Trzeci Nowicjusz (220 p.)

@Mavannkas,
wink

komentarz 5 lutego 2019 przez Trzeci Nowicjusz (220 p.)

@mokrowski, Wow

Podobne pytania

+1 głos
1 odpowiedź 117 wizyt
0 głosów
1 odpowiedź 575 wizyt
0 głosów
1 odpowiedź 307 wizyt

92,555 zapytań

141,403 odpowiedzi

319,554 komentarzy

61,939 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...