Jak wylosować 4 liczby bez powtórzeń?

Odpowiedz Nowy wątek
2011-07-22 11:03
RandomProblem
0

Jak wylosować 4 liczby bez powtórzeń? Napisałem taki kod:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace LosowanieBezPowtorzen
{
    class Program
    {
        static void Main(string[] args)
        {
            Random losuj = new Random();
            int[] Liczby = new int[4];
            int wylosowana;
 
            List<string> listaSlow = new List<string>();
            listaSlow.Add("A");
            listaSlow.Add("B");
            listaSlow.Add("C");
            listaSlow.Add("D");
            listaSlow.Add("E");
            listaSlow.Add("F");
            listaSlow.Add("G");
 
            int maxPrzedzial = listaSlow.Count;
 
            for (int i = 0; i < 4; i++)
            {
                do
                {
                    wylosowana = losuj.Next(0, maxPrzedzial);
                    Liczby[i] = wylosowana;
                }
                while (Liczby[i] == wylosowana);
            }
 
            for (int i = 0; i < Liczby.Length; i++)
            {
                Console.WriteLine(Liczby[i]);
            }
            Console.ReadLine();
        }
    }
}
 

Program chyba nie losuje tych liczb, ponieważ jak włączę program to na oknie konsoli nic się nie pojawia.

W konsoli nic się nie pojawia, bo program wpada w nieskończoną pętlę do-while. ;) - rincewind 2011-07-25 13:14

Pozostało 580 znaków

2011-07-22 11:12
fgh454564
0

to ja nnn

Ja to chyba bym to robił tak że mam jakąś długą pętlę for( może nieskończoną) w której robię random() liczb i wrzucam je do kontenera Set<integer>.
W zbiorze - Set<integer> - liczby nie mogą się powtarzać wiec wszystkie powtórzenia zostaną automatycznie wyrzucone. Kontener Set należy w tym przypadku napełnić do rozmiaru 4.

dobra praktyka z python :p ?!? - marcio 2011-07-22 20:53

Pozostało 580 znaków

2011-07-22 11:26
tret56454
0

to ja nnn

 
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace LiczbyBezPowtorek
{
    class Program
    {
        static void Main(string[] args)
        {
            int liczba = 0;
            int przedzial = 50;
            Random r = new Random();
            ISet<Int32> iset = new SortedSet<Int32>();
            while (true)
            {
                liczba = r.Next(1, przedzial);
                iset.Add(liczba);
                if (iset.Count == 4)
                {
                    break;
                }
            }
            foreach( Int32 i in iset )
            {
                Console.WriteLine(i);
            }
        }
    }
}
Nie lepiej w nazwie pisać 'nnn' zamiast "to ja ..."? Każdy wie ocb. - szypxx 2011-07-22 15:53

Pozostało 580 znaków

2011-07-22 11:28
0
  • zapełnić jakiś kontener losowymi liczbami
  • w pętli (u Ciebie 4 razy) wylosować liczbę z przedziału (0;kontener.size())
  • zapamiętać do jakiejś tablicy liczbę spod wylosowanego indeksu tego kontenera
  • usunąć wylosowaną liczbę z kontenera

W skrócie - losować indeksy a nie liczby, bo inaczej może losować w nieskończoność

edytowany 1x, ostatnio: cysiej, 2011-07-22 11:29

Pozostało 580 znaków

2011-07-22 11:37
bo
0

@up,
A jak zrealizować pierwszy punkt? tzn. jak wypełnić kontener losowymi niepowtarzającymi się liczbami? Wygląda, że Twój algorytm, to nieskończona rekurencja.

Pozostało 580 znaków

2011-07-22 11:37
0

Najpierw dlaczego nic się nie działo:

 do
                {
                    wylosowana = losuj.Next(0, maxPrzedzial);
                    Liczby[i] = wylosowana;
                }
                while (Liczby[i] == wylosowana);

Ponieważ wpisywałeś do Liczby[i] jakąś liczbę, a następnie sprawdzałeś czy taka liczba jest w Liczby[i], co oznacza, że warunek był zawsze prawdziwy i pętla zrobiła się nieskończona.

Praktycznie każda kolekcja w .NET 3.5 posiada metodę Contains, którą możesz sprawdzić czy dany element znajduje się w kolekcji (tablica może być) przed dodaniem nowego. Jest to najprostsze rozwiązanie.

Pozdrawiam.

edytowany 1x, ostatnio: Sarrus, 2011-07-22 11:38

Pozostało 580 znaków

2011-07-22 11:48
RandomProblem
0

Napisałem teraz tak, ale czasem 2 razy jest losowana liczba zero;/

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace Losowanie2
{
    class Program
    {
        static void Main(string[] args)
        {
            List<string> listaSlow = new List<string>();
            List<int> mozliweIndeksy = new List<int>();
            int[] Liczby = new int[4];
            Random losuj = new Random();
            int wylosowana;
 
            listaSlow.Add("A");
            listaSlow.Add("B");
            listaSlow.Add("C");
            listaSlow.Add("D");
            listaSlow.Add("E");
            listaSlow.Add("F");
            listaSlow.Add("G");
 
            int maxPrzedzial = listaSlow.Count;
            for (int i = 0; i < 4; i++)
            {
                wylosowana = losuj.Next(0, maxPrzedzial);
                if (!Liczby.Contains(wylosowana))
                {
                    Liczby[i] = wylosowana;
                }
            }
 
            for (int i = 0; i < Liczby.Length; i++)
            {
                Console.WriteLine(Liczby[i] + " ");
            }
            Console.ReadKey();
        }
    }
}
 

Pozostało 580 znaków

2011-07-22 11:56
RandomProblem
0

Poprawiłem.

 
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace Losowanie3
{
    class Program
    {
        static void Main(string[] args)
        {
            Random losuj = new Random();
            int[] Liczby = new int[4];
            int wylosowana;
 
            List<string> listaSlow = new List<string>();
            listaSlow.Add("A");
            listaSlow.Add("B");
            listaSlow.Add("C");
            listaSlow.Add("D");
            listaSlow.Add("E");
            listaSlow.Add("F");
            listaSlow.Add("G");
 
            int maxPrzedzial = listaSlow.Count;
 
            for (int i = 0; i < 4; i++)
            {
                do
                {
                    wylosowana = losuj.Next(0, maxPrzedzial);
                    if(!Liczby.Contains(wylosowana))
                        Liczby[i]=wylosowana;
                }
                while (Liczby[i] == wylosowana);
            }
 
            for (int i = 0; i < Liczby.Length; i++)
            {
                Console.WriteLine(Liczby[i]);
            }
            Console.ReadLine();
        }
    }
}
 

Czy ten kod jest poprawny?? Pytam, bo tutaj rzadziej się powtarzają dwa zera, ale jednak się powtarzają. Pytanie dlaczego.

Pozostało 580 znaków

2011-07-22 15:27
0

Nie. Poza tym, że robisz to jakoś dziwnie, to przemyśl warunek pętli do..while oraz pomyśl jakie wartości znajdują się w tablicy Liczby zaraz po utworzeniu.


Pozdro & poćwicz!

Pozostało 580 znaków

2011-07-24 18:30
0
cysiej napisał(a)
  • zapełnić jakiś kontener losowymi liczbami
  • w pętli (u Ciebie 4 razy) wylosować liczbę z przedziału (0;kontener.size())
  • zapamiętać do jakiejś tablicy liczbę spod wylosowanego indeksu tego kontenera
  • usunąć wylosowaną liczbę z kontenera

W skrócie - losować indeksy a nie liczby, bo inaczej może losować w nieskończoność

stosuję bardzo podobny algorytm:

  • mam zbiór "n" elementowy w jakiejsc kolekcji
  • losuje jeden element z tej kolekcji po indexach z obszaru od 0 do "n" tej kolekcji (nie po wartosciach tylko po indexach)
  • wylosowanay element zapamiętuje w innej zmiennej i zamieniam miejscami z ostatnim elementem kolekcji
  • losuje drugi raz z całej kolekcji ale tym razem z obaszru od 0 do "n-1" (na pozycji "n" w kolekcji ustawilem poprzednio, wczesniej wylosowany element takze losuje z tych samych elementow co ostatnio tylko bez ostatnio wylosowanego elementu)
  • po raz drugi zapamietuje wylosowany element i dodaje do zmiennej juz wylosowanych elementow i znow zamieniam go miejscami z elementem "n-1"
  • i tak dalej, nie ma pustych przebiegow i losowanie przebiega w tylku krokach ile liczb chcesz losowac

w przypadku gdy skupiasz się na tym ze najpierw losujesz cokolwiek i potem porownujesz czy juz wczesniej cos takiego wlosowales a jezeli tak to znow losujesz - tworza sie puste przebiegi petli, wlasnie dlatego na większych zbiorach np. 4500 losowych ze zbioru 5 000 elementów teoretycznie moze powstac petla nieskonczona, jezeli Twój obiekt "losuj" typu Random bedzie miał pecha i bedzie losowal non stop liczby ktore juz wczesniej wylosowal.


Sterczące kolce Pondijusa, ostre grzebienie Daktyloskopei, Trygla i latający Wieprzoryb są niczym wobec Bestii która nas gnębi...

Pozostało 580 znaków

2011-07-24 19:15
bo
0

np. 4500 losowych ze zbioru 5 000 elementów

Rozsądny programista nigdy tak nie losuje. Losuje te 500 elementów, które maja być pominięte.

Masz racje, starałem się tylko obrazowo coś wytłumaczyć, jak nowicjusz nowicjuszowi - mysle ze na tym przykladzie 4500 z 5000 "czuć" tą pętlę nieskończoną bardziej wyrażnie ;) - Varran 2011-07-24 20:11

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

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