17 апреля 2012 г.

Продолжаем обучаться программированию.


Продолжаем обучаться программированию.

Разберем нашу прошлую игру. Игра состояла в угадывании задуманного числа. В данной игре применяется дихотомический поиск ( двоичный ). 


Программа каждый раз при угадывании числа просто делит весь диапазон чисел пополам на двое отсюда и двоичный.
Предлагает число если не оно,тогда спрашивает ваше число меньше данного если да
то опять повторяется цикл-деление на двое-вопрос иначе меняет вершину массива.

const size=100000; // наш диапазон чисел

procedure TForm1.CheckBox1Click(Sender: TObject);

 var i,sred,niz,verh,n,obr:integer; found:boolean; // перемен. для цикла,середина низ верх массива
 a:array[1..size] of integer; // данный массив размерностью 100000
begin

// мотаем цикл длинной в размерность массива
for i:=1 to size do
a[i]:=i;

n:=0;
 verh:=1; // верх=первой ячейке массива
 niz:=size; // низ=100000
 found:=false; // переменная указывающая угадали число (true) или нет (false)

// еще один цикл повторяется до тех пор пока верх массива выше низа или пока не найдено число

repeat
 sred:=trunc((niz-verh)/2)+verh; // вычисляем средний элемент который и будем предлагать пользователю

 i:=a[sred]; // берем среднее число из массива
inc(n);
if MessageDlg('Это число'+' '+inttostr(i)+'?',mtConfirmation, [mbYes,mbNo],0)=mryes then
found:=true

else
if MessageDlg('Это число меньше'+' '+inttostr(i)+'?',mtConfirmation, [mbYes,mbNo],0)=mryes then
niz:=sred-1
else verh:=sred+1;

listbox1.Items.Add(inttostr(n)+'-'+inttostr(i));
until(verh>niz) or found;

MessageDlg('Ура!!! Ваше число '+' '+inttostr(i) ,mtInformation,[mbok],0);

end;

procedure TForm1.FormActivate(Sender: TObject);
begin
label1.Caption:='Загадайте любое число от 1'+ ' '+'до'+ ' '+inttostr(size);
end;

end.

 С консольным вариантом так же только различаются комманды и оформление

program Project1;

{$APPTYPE CONSOLE}

uses
SysUtils,
windows,
 classes;     // нужен модуль для использования списка строк

const size=100000;

var i,sred,niz,verh,n,obr:integer; found:boolean;
a:array[1..size] of integer;
s : string; rez : TstringList;
begin

rez:=TstringList.Create;

writeln('Make a number from 1 '+ ' '+'to'+ ' '+inttostr(size));
writeln('Enter Y if ready');
readln(s);
if (s='Y') or (s='y') then
for i:=1 to size do
a[i]:=i;

n:=0;
verh:=1;
niz:=size;
found:=false;

repeat
sred:=trunc((niz-verh)/2)+verh;
i:=a[sred];
inc(n);
writeln('Your number'+' '+inttostr(i)+'?'+ ' '+ 'Yes/No');
readln(s);
if (s='Y') or (s='y') then found:=true
else
writeln('This number is smaller'+' '+inttostr(i)+'?'+ ' '+ 'Yes/No');
readln(s);
if (s='Y') or (s='y') then niz:=sred-1
else verh:=sred+1;

rez.Add(inttostr(n)+'-'+inttostr(i));

until(verh>niz) or found;

writeln('Found your number '+' '+inttostr(i));

// выводим таблицу угадывания

for i:=0 to rez.Count-1 do
writeln(rez[i]);

rez.Free;
sleep(5000);

end.


Может как то сумбурно объяснил, но принцип думаю понятен.

Комментариев нет:

Отправить комментарий