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

Losowanie bez powtórzeń, mój program - proszę o krytykę
KV
  • Rejestracja:ponad 10 lat
  • Ostatnio:około 9 lat
  • Postów:20
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.

Kopiuj
#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;
}
twonek
  • Rejestracja:prawie 11 lat
  • Ostatnio:prawie 2 lata
  • Postów:2500
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
Kopiuj
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
Zellus
  • Rejestracja:prawie 13 lat
  • Ostatnio:około 4 lata
  • Lokalizacja:Wrocław
  • Postów:474
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
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 :(

Kopiuj
#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: flowCRANE
0

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

Zellus
  • Rejestracja:prawie 13 lat
  • Ostatnio:około 4 lata
  • Lokalizacja:Wrocław
  • Postów:474
1
Kopiuj
int main()
{
   int x;
   srand(time(NULL));
   do{
       x = rand() % 101;
   while(x<10 || x > 15)
   cout << x << endl;
}
edytowany 1x, ostatnio: Zellus
Kliknij, aby dodać treść...

Pomoc 1.18.8

Typografia

Edytor obsługuje składnie Markdown, w której pojedynczy akcent *kursywa* oraz _kursywa_ to pochylenie. Z kolei podwójny akcent **pogrubienie** oraz __pogrubienie__ to pogrubienie. Dodanie znaczników ~~strike~~ to przekreślenie.

Możesz dodać formatowanie komendami , , oraz .

Ponieważ dekoracja podkreślenia jest przeznaczona na linki, markdown nie zawiera specjalnej składni dla podkreślenia. Dlatego by dodać podkreślenie, użyj <u>underline</u>.

Komendy formatujące reagują na skróty klawiszowe: Ctrl+B, Ctrl+I, Ctrl+U oraz Ctrl+S.

Linki

By dodać link w edytorze użyj komendy lub użyj składni [title](link). URL umieszczony w linku lub nawet URL umieszczony bezpośrednio w tekście będzie aktywny i klikalny.

Jeżeli chcesz, możesz samodzielnie dodać link: <a href="link">title</a>.

Wewnętrzne odnośniki

Możesz umieścić odnośnik do wewnętrznej podstrony, używając następującej składni: [[Delphi/Kompendium]] lub [[Delphi/Kompendium|kliknij, aby przejść do kompendium]]. Odnośniki mogą prowadzić do Forum 4programmers.net lub np. do Kompendium.

Wspomnienia użytkowników

By wspomnieć użytkownika forum, wpisz w formularzu znak @. Zobaczysz okienko samouzupełniające nazwy użytkowników. Samouzupełnienie dobierze odpowiedni format wspomnienia, zależnie od tego czy w nazwie użytkownika znajduje się spacja.

Znaczniki HTML

Dozwolone jest używanie niektórych znaczników HTML: <a>, <b>, <i>, <kbd>, <del>, <strong>, <dfn>, <pre>, <blockquote>, <hr/>, <sub>, <sup> oraz <img/>.

Skróty klawiszowe

Dodaj kombinację klawiszy komendą notacji klawiszy lub skrótem klawiszowym Alt+K.

Reprezentuj kombinacje klawiszowe używając taga <kbd>. Oddziel od siebie klawisze znakiem plus, np <kbd>Alt+Tab</kbd>.

Indeks górny oraz dolny

Przykład: wpisując H<sub>2</sub>O i m<sup>2</sup> otrzymasz: H2O i m2.

Składnia Tex

By precyzyjnie wyrazić działanie matematyczne, użyj składni Tex.

<tex>arcctg(x) = argtan(\frac{1}{x}) = arcsin(\frac{1}{\sqrt{1+x^2}})</tex>

Kod źródłowy

Krótkie fragmenty kodu

Wszelkie jednolinijkowe instrukcje języka programowania powinny być zawarte pomiędzy obróconymi apostrofami: `kod instrukcji` lub ``console.log(`string`);``.

Kod wielolinijkowy

Dodaj fragment kodu komendą . Fragmenty kodu zajmujące całą lub więcej linijek powinny być umieszczone w wielolinijkowym fragmencie kodu. Znaczniki ``` lub ~~~ umożliwiają kolorowanie różnych języków programowania. Możemy nadać nazwę języka programowania używając auto-uzupełnienia, kod został pokolorowany używając konkretnych ustawień kolorowania składni:

```javascript
document.write('Hello World');
```

Możesz zaznaczyć również już wklejony kod w edytorze, i użyć komendy  by zamienić go w kod. Użyj kombinacji Ctrl+`, by dodać fragment kodu bez oznaczników języka.

Tabelki

Dodaj przykładową tabelkę używając komendy . Przykładowa tabelka składa się z dwóch kolumn, nagłówka i jednego wiersza.

Wygeneruj tabelkę na podstawie szablonu. Oddziel komórki separatorem ; lub |, a następnie zaznacz szablonu.

nazwisko;dziedzina;odkrycie
Pitagoras;mathematics;Pythagorean Theorem
Albert Einstein;physics;General Relativity
Marie Curie, Pierre Curie;chemistry;Radium, Polonium

Użyj komendy by zamienić zaznaczony szablon na tabelkę Markdown.

Lista uporządkowana i nieuporządkowana

Możliwe jest tworzenie listy numerowanych oraz wypunktowanych. Wystarczy, że pierwszym znakiem linii będzie * lub - dla listy nieuporządkowanej oraz 1. dla listy uporządkowanej.

Użyj komendy by dodać listę uporządkowaną.

1. Lista numerowana
2. Lista numerowana

Użyj komendy by dodać listę nieuporządkowaną.

* Lista wypunktowana
* Lista wypunktowana
** Lista wypunktowana (drugi poziom)

Składnia Markdown

Edytor obsługuje składnię Markdown, która składa się ze znaków specjalnych. Dostępne komendy, jak formatowanie , dodanie tabelki lub fragmentu kodu są w pewnym sensie świadome otaczającej jej składni, i postarają się unikać uszkodzenia jej.

Dla przykładu, używając tylko dostępnych komend, nie możemy dodać formatowania pogrubienia do kodu wielolinijkowego, albo dodać listy do tabelki - mogłoby to doprowadzić do uszkodzenia składni.

W pewnych odosobnionych przypadkach brak nowej linii przed elementami markdown również mógłby uszkodzić składnie, dlatego edytor dodaje brakujące nowe linie. Dla przykładu, dodanie formatowania pochylenia zaraz po tabelce, mogłoby zostać błędne zinterpretowane, więc edytor doda oddzielającą nową linię pomiędzy tabelką, a pochyleniem.

Skróty klawiszowe

Skróty formatujące, kiedy w edytorze znajduje się pojedynczy kursor, wstawiają sformatowany tekst przykładowy. Jeśli w edytorze znajduje się zaznaczenie (słowo, linijka, paragraf), wtedy zaznaczenie zostaje sformatowane.

  • Ctrl+B - dodaj pogrubienie lub pogrub zaznaczenie
  • Ctrl+I - dodaj pochylenie lub pochyl zaznaczenie
  • Ctrl+U - dodaj podkreślenie lub podkreśl zaznaczenie
  • Ctrl+S - dodaj przekreślenie lub przekreśl zaznaczenie

Notacja Klawiszy

  • Alt+K - dodaj notację klawiszy

Fragment kodu bez oznacznika

  • Alt+C - dodaj pusty fragment kodu

Skróty operujące na kodzie i linijkach:

  • Alt+L - zaznaczenie całej linii
  • Alt+, Alt+ - przeniesienie linijki w której znajduje się kursor w górę/dół.
  • Tab/⌘+] - dodaj wcięcie (wcięcie w prawo)
  • Shit+Tab/⌘+[ - usunięcie wcięcia (wycięcie w lewo)

Dodawanie postów:

  • Ctrl+Enter - dodaj post
  • ⌘+Enter - dodaj post (MacOS)