Losowanie bez powtórzeń, mój program - proszę o krytykę

2015-01-20 16:03
0
  1. wprowadza się początek i koniec przedziału (std::cin)
  2. wykonywana jest "funkcjaKontrolna" wykorzystująca dwa argumenty wcześniej wprowadzone (tj. początek i koniec przedziału). W skrócie ta funkcja TYLKO dodaje na zasadzie +1 od początku do końca przedziału. Dlaczego? Ponieważ ilość elementów tablicy i ich suma muszą się zgadzać z tą, która później zostanie odpalona.
  3. wykonywana jest funkcja "losujBezPowtorzen" z tymi samymi argumentami, tylko że tym razem nie ma dodawania, ale faktycznie wymuszam na funkcji rand() aby wylosowała mi dokładnie te liczby które chce - tj. rand() losuje tak długo, aż wylosuje liczbę której wcześniej nie było. Innym słowy funkcja "ma dosyć łatwo" na początku, ale już przy losowaniu ostatniej liczby ma tylko 1 prawidłową liczbę do wylosowania. Ilość elementów i suma elementów zawsze będzie się zgadzać z tą z "funkcjaKontrolna".

Uwagi

  1. Użyłem goto aby wyjść z wielokrotnie zagnieżdżonej pętli

Dla tych co mają dużo wolnego czasu: jak mógłbym ulepszyć swój kod?
Z góry dzięki za pomoc.

#include "stdafx.h"
#include <iostream>         //std:cout + cin
#include <conio.h>          //_getch()
#include <cstdlib>          //pseudolosowe liczby calkowite
#include <ctime>            //time();
using namespace std;

void funkcjaKontrolna(int k_poczatek, int k_koniec)
{
    cout << "FUNKCJA KONTROLNA, bez losowania, jej wyniki musza byc takie same jak w funkcji wlasciwej" << endl;
    const int iloscElementow = (k_koniec - k_poczatek) +1;      
    int tablicaKontrolna[1000];
    for (int a=0 ; a<iloscElementow ; a++)          
    {
        tablicaKontrolna[a] = k_poczatek;
        k_poczatek++;
        cout << "\tElement\t\t" << a << "\ttablicy ma wartosc:\t" << tablicaKontrolna[a] << endl;
    }
    int suma = 0;
    for(int a=0; a<iloscElementow ; a++)
    {
        suma = suma + tablicaKontrolna[a];
    }
    cout << "\tIlosc elementow przedzialu to:\t\t\t\t" << iloscElementow << endl;
    cout << "\tSuma wartosci elementow tablicy to:\t\t\t" << suma << "\n\n";
    return;
}

void losujBezPowtorzen(int* tablicaZewn, int poczatekPrzedzialu, int koniecPrzedzialu, int *wsk_iloEle, int *wsk_sumEle)
{   
    cout << "FUNKCJA WLASCIWA, losuje w oparciu o rand()" << endl;
    *wsk_iloEle = (koniecPrzedzialu - poczatekPrzedzialu) +1;
    int stash;
    for (int b=0 ; b<*wsk_iloEle ; b++)
    {
wroc:
        stash = ((rand() % *wsk_iloEle) + poczatekPrzedzialu);
        if(b!=0)        
            for(int d=0; d<b ; d++)
            {
                if(stash == tablicaZewn[d])goto wroc;   
            }
         tablicaZewn[b] = stash; 
         cout << "\tElement\t\t" << b << "\ttablicy ma wartosc:\t" << tablicaZewn[b] << endl; 
    }
    int sumaa = 0;
    for (int c=0 ; c<*wsk_iloEle ; c++)
    {
        sumaa = sumaa + tablicaZewn[c];
    }
    *wsk_sumEle = sumaa;
    cout << "\tIlosc elementow przedzialu:\t\t\t\t" << *wsk_iloEle << endl;
    cout << "\tSuma wartosci elementow tablicy:\t\t\t" << *wsk_sumEle << endl;

    return;
}

int _tmain(int argc, _TCHAR* argv[])
{   
    cout << "******************************************\n\n\tkvsnagi prodakszyns prezents:\n\trandom function without repeating\n\n******************************************\n\n\n" ;

    srand(time(NULL));
    int poczatekPrzedzialu, koniecPrzedzialu;
    cout <<"FUNKCJA MAIN\n\tWprowadz poczatek i koniec przedzialu,\n\tpamietaj ze max. rozmiar tablicy to 1000,\n\ta wiec nie elementow nie moze byc >1000" << endl;
    cout <<"\n\tWprowadz poczatek przedzialu:\t";
    cin >> poczatekPrzedzialu;
    int kontrola=0;
    do
    {
        kontrola = 0;
        cout <<"\tWprowadz koniec przedzialu:\t";
        cin >> koniecPrzedzialu;
        if(poczatekPrzedzialu > koniecPrzedzialu || poczatekPrzedzialu == koniecPrzedzialu)
        {
            cout << "\tKoncowa wartosc przedzialu musi byc wieksza niz poczatkowa wartosc." << endl;
            kontrola = 1;
        }
    }
    while(kontrola==1);
    cout << endl;

    funkcjaKontrolna(poczatekPrzedzialu, koniecPrzedzialu);

    int tablica[1000];
    int iloscElementow;
    int *wsk_iloEle = &iloscElementow;
    int sumaElementow;
    int *wsk_sumEle = &sumaElementow;
    losujBezPowtorzen(tablica, poczatekPrzedzialu, koniecPrzedzialu, wsk_iloEle, wsk_sumEle);

    _getch();
    return 0;
}

Pozostało 580 znaków

2015-01-20 16:29
1

Pierwsza myśl: używaj C++.
1) przekaż parametry przez referencje zamiast wskaźników
2) używaj std::vector
3) ++i zamiast i++
4) w pętlach używaj i jako indeksu zamiast kolejnych liter alfabetu
5) if niepotrzebny, po wywaleniu można wywalić goto

if(b!=0)
    for(int d=0; d<b ; d++)

6) sumowanie w tablicy można zrealizować za pomocą std::accumulate
7) teoretycznie Twoje losowanie może trwać do końca świata, efektywniejszy sposób podano wielokrotnie na forum

Pozostało 580 znaków

2015-01-20 16:37
0

Błąd jest taki że korzystasz z goto, jest to niedopuszczalne. Do wychodzenia z pętli służy break lub najlepiej warunek, który podajesz na początku(w do...while na końcu).
Jeżeli korzystasz z C++, to staraj się nie używać wskaźników i tablic w stylu C, lepszym pomysłem jest korzystanie z std::array. Wtedy zamiast korzystać z wskaźników, możesz korzystać z iteratorów. A do funkcji przekazuj przez referencją, a nie wskaźnik.
Prosty sposób na to samo(jeżeli dobrze zrozumiałem): wygenerować tablicą wyrazów 1...1000 i potem losowo ją sortować funkcją http://www.cplusplus.com/reference/algorithm/random_shuffle/

Później przyszło mi na myśl:

  • Wiem że na początku ułatwia to zlokalizowanie ew. błędu, ale w przyszłości staraj się ograniczyć mieszanie kodu z wyświetlaniem komunikatów. Najlepiej jakby do obliczeń służyła jedna funkcja, a do wyświetlania wyników inna. Wtedy funkcja licząca, będzie znacznie krótsza i łatwiej jest się w niej dopatrzeć ew. błędów, nawet bez uruchamiania kodu.
  • Na końcu funkcji "zwracającej" void, nie musisz dawać return;
edytowany 2x, ostatnio: Zellus, 2015-01-20 17:49

Pozostało 580 znaków

2015-01-27 06:58
Zimny Mleczarz
0

Napisz program losujący liczbę z przedziału <0;100> tak długo aż wylosuje liczbę z przedziału <10;15>. Do losowania liczb służy funkcja rand().

Coś tu nie działa :(

#include<stdio.h>
main()
{int x,i;
    srand(time(NULL));
    do 
    {
        x=rand()%101;
        i=rand()%6+10;

    }   
    while(x==i);
        printf("wylosowana liczba to: %d",x);
return 0;
}

dodanie znacznika <quote> - @furious programming

edytowany 2x, ostatnio: furious programming, 2016-12-13 18:26

Pozostało 580 znaków

2015-01-27 07:21
Czarny Kaczor
0

wywal i i warunek while(x>9 && x<16)

Pozostało 580 znaków

2015-01-27 09:13
1
int main()
{
   int x;
   srand(time(NULL));
   do{
       x = rand() % 101;
   while(x<10 || x > 15)
   cout << x << endl;
}
edytowany 1x, ostatnio: Zellus, 2015-01-27 09:14

Pozostało 580 znaków

Liczba odpowiedzi na stronę

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