Random Sayı

Delphi'de kod yazma ile ilgili sorularınızı bu foruma yazabilirsiniz.
Cevapla
n0nex
Üye
Mesajlar: 9
Kayıt: 07 Şub 2016 11:37

Random Sayı

Mesaj gönderen n0nex »

Merhaba arkadaşlar
Öncelikle belirtmek isterim ki konuyu forumda araştırdım, birçok konuya baktım ancak tam anlamıyla istediğim çözümü bulamadım.
Konu şu ki, 11 haneli random sayılar oluşturmak istiyorum. Bu sayıların unique olması lazım, yani bir defa bile tekrar etmemesi lazım.
Diğer dillerde zamana göre tetikleme yapabiliyoruz, bunu Delphi'de nasıl yaparız? Yaparsak unique olmasını sağlar mıyız?
Konu ile ilgili detaylı çözümleriniz beni sevindirecektir.
Teşekkürler
Kullanıcı avatarı
sabanakman
Kıdemli Üye
Mesajlar: 3081
Kayıt: 17 Nis 2006 08:11
Konum: Ah bi Antalya olaydı keşke (Ankara)

Re: Random Sayı

Mesaj gönderen sabanakman »

Böyle özel konuları, nokta atışı cevaplanmış olarak bulma olasılığınız pek yoktur. Bu gibi durumlarda kendiniz adım adım mantık geliştirmelisiniz. Mesela böyle bir iş için ilk olarak Int64 tam sayı tipinde boyutu dinamik olarak genişletilebilen bir dizi kullanmak gerekmektedir. Tabi bir de bu tiple koşullara uygun bir değer üretmek gerekmektedir. Daha sonra üretilen bu değeri, oluşturduğumuz dizi içerisinde var mı kontrol edip, eğer varsa yeniden değer ürettirmek gerekir. Listede olmayan geçerli bir değer ise , bunu diziye ekleyip bir sonraki rastgele sayıya geçilir.

Kod: Tümünü seç

type
  TRasgeleSayi=Int64;

function RasgeleSayiUret:TRasgeleSayi;
{11 basamaklı 99.999.999 sayısının binary karşılığı
0001.0111.0100.1000.0111.0110.1110.0111.1111.1111'dir ve
5 byte boyutundadır}
const EnBuyukDeger:Int64=99999999999; EnKucukDeger:Int64=10000000000;
begin
  repeat
    Result:=Random(23); //11 basamaklı en büyük sayı için en soldaki 5. byte değeri maksimum 23 olur
    Result:=(Result shl 32) or Random(MaxInt); //bir byte lık değer 4 byte sola kaydırılıp maksimum 4 byte lık bir değer ile birleştirilir
  until (Result>=EnKucukDeger) and (Result<=EnBuyukDeger); //üretilen sayı istenen aralıkta değilse tekrar rasgele üretime geçilir
end;

var
  RasgeleSayilar:array of TRasgeleSayi=nil;
  RasgeleSayilar_DiziYeri:Integer=-1;
  RasgeleSayilar_DiziBoyutu:Integer=0;

const
  RasgeleSayilar_YeniGenislik=250;//her lazım olduğunda bu kadar elemanlık yeni yer ayrılır

function RasgeSayilar_Next:Integer;
begin
  Inc(RasgeleSayilar_DiziYeri);
  if RasgeleSayilar_DiziYeri>=RasgeleSayilar_DiziBoyutu then begin
   Inc(RasgeleSayilar_DiziBoyutu, RasgeleSayilar_YeniGenislik); //dizi sayılarla dolduğu zaman
   SetLength(RasgeleSayilar, RasgeleSayilar_DiziBoyutu);  //bellekte yeni yer ayrılır
  end;
  Result:=RasgeleSayilar_DiziYeri;  //yeni değeri alacak boş elemanın dizideki yeri
end;

function RasgeleDegerVarmi(const Deger:TRasgeleSayi):Integer;
//rasgele sayılar içinde o değer var mı
var i:Integer;
begin
  Result:=-1;
  i:=0;
  while (Result<0) and (i<=RasgeleSayilar_DiziYeri) do begin
    if RasgeleSayilar[i]=Deger then Result:=i else Inc(i);
  end;
end;

function YeniRasgeleDeger:TRasgeleSayi; //dizide tutulan değere göre kontrollü yeni rasgele sayı hesaplar
var i,p:Integer;
begin
  repeat
    Result:=RasgeleSayiUret;
    i:=RasgeleDegerVarmi(Result);
    if i<0 then begin //üretilen değer dizi içinde yok, bu değer diziye eklenir
      p:=RasgeSayilar_Next;//yeni değer için dizideki uygun sıradaki değer
      RasgeleSayilar[p]:=Result;
    end;
  until i<0;
end;

initialization
  Randomize;
end.
Mesela yukarıdaki kodlar, size bu konuda yol gösterecektir. Burada ilk aşamada RasgeleSayiUret fonksiyonu istenilen 11 basamaklı değeri üretmektedir. Tabi bu tek başına yeterli olmayacaktır. Her üretilen değeri bünyesinde tutan bir de RasgeleSayilar:array of TRasgeleSayi dizisi bulunmaktadır. Artık YeniRasgeleDeger fonksiyonu içinde, bir değer üretip bu dizi içinde var mı diye kontrol edilmektedir. Eğer değeri dizi içinde bulursa tekrar başka değer üretilir. Üretilen değer dizi içinde yoksa bu diziye üretilen son değer eklenir. Tabi eklerken dizi boyutu gerektiği takdirde genişletilmektedir.

Kod: Tümünü seç

procedure TForm1.Button1Click(Sender: TObject);
var i:TRasgeleSayi;
begin
  i:=YeniRasgeleDeger;
  ListBox1.Items.Add(Format('%d=%s',[Length(IntToStr(i)),IntToStr(i)]));
end;
İyi çalışmalar.
Şaban Şahin AKMAN
_________________
Derin olan kuyu değil kısa olan iptir. - .
Cevapla