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

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;
}
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++)
  1. sumowanie w tablicy można zrealizować za pomocą std::accumulate
  2. teoretycznie Twoje losowanie może trwać do końca świata, efektywniejszy sposób podano wielokrotnie na forum
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;
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

0

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

1
int main()
{
   int x;
   srand(time(NULL));
   do{
       x = rand() % 101;
   while(x<10 || x > 15)
   cout << x << endl;
}

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