• 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.

0 głosów
709 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 VIP (147,000 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 VIP (147,000 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ź 61 wizyt
0 głosów
1 odpowiedź 135 wizyt
0 głosów
1 odpowiedź 151 wizyt

86,541 zapytań

135,291 odpowiedzi

300,649 komentarzy

57,288 pasjonatów

Motyw:

Akcja Pajacyk

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

Oto dwie polecane książki warte uwagi. Pełną listę znajdziesz tutaj.

...