Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Одномерный массив. Как заполнить числами от 1 до 10? [D4, WinME]


Страницы:   1 2

UDS ©   (2002-04-03 23:07:00) 

Я уже задавал этот вопрос, но его куда-то ушли... Или такие ламерские вопросы вообще тут не рассматриваются. Как тогда,господа, учиться нам начинающим?
Проблема вот в чем: я заполняю массив A[i]: integer числами от 1 до 10 в произвольном порядке (for i:=1 to 10 do A[i]:=(random(10)+1). КАК СДЕЛАТЬ ЧТОБЫ ВЫПАДАЮЩИЕ ЧИСЛА НЕ ПОВТОРЯЛИСЬ. Помогите пожалуйста! Это нужно для дальнейшей работы над программой. Ни в FAQе, ни во всем форуме я ответа не нашёл! Заранее спасибо.


Anatoly Podgoretsky   (2002-04-04 13:41:00) [1]

Гарантированая перестановка всех элементов, за минимально короткий цикл


eSKey   (2002-04-04 13:26:00) [2]

Я для тасовки использую это:
//qn - массив nq - число эл-тов

For i := 1 To nq do begin
j := qn[i];
t := Random(nq)+1;
qn[i] := qn[t]; qn[t] := j;
end;


Stranger   (2002-04-04 11:11:00) [3]

Есть еще один вариантик проверки уникальности числа в массиве
все то же самое , randomize и прочее Random(10)+1 генерим претендента, но добавляем следующий код

var
s: Set of 1..10; // множество элементов из диапазона чисел 1..10
...
begin
s:=[];
...
if Not (<претендент> in s) then begin
s:=s+[<претендент>];
<элемент массива>:=<претендент>;
end
else попробовать другого претендента
end;
Все это довольно быстро работает при небольшом размере массива и хорошем генераторе случайных чисел,
на мой взгляд при длине 10 и 1-3 возможном повторении лишних итераций будет не много, в принципе,
при первом повторении можно опять сделать randomize


Anatoly Podgoretsky   (2002-04-04 09:18:00) [4]

SPeller © (04.04.02 02:51)
Ты их просто запутал отсутствием части else


Song   (2002-04-04 09:03:00) [5]

2SPeller © (04.04.02 08:57)
Да, я понял, что Вы хотели сказать и отреагировал в Song © (04.04.02 08:54).


SPeller   (2002-04-04 08:57:00) [6]

Song ©
Насколько я понимаю, в fl:=a[j]=k fl присваивается результат сравнения a[i] и k , т.е. равно - присвоили true, неравно - присвоили false. Тем более, что это аналог if a[i]=k then fl:=true else fl:=false, а у нас то if a[j]=k then fl:=true; ! Чуешь разницу ?? При ложности условия ничего не выполняется!


panov   (2002-04-04 08:55:00) [7]

>Song © (04.04.02 08:39)
...Это остаточные явления программирования на Паскале...

Абсолютно правильный подход - использование конструкций вида
if ... then ... else ...
лучше читается и логика программы, и ошибки видны.

fl:=a[j]=k
Такие конструкции ведут к труднонаходимым ошибкам в программах.
Это-то как раз наследие С.


Song   (2002-04-04 08:54:00) [8]

2SPeller © (04.04.02 08:47)
А ну да, Вы правы, а Вам надо не так?


Song   (2002-04-04 08:53:00) [9]

Запись Fl:=a[j]=k; будет интерпретироваться так: если a[j]=k то F будет True, если нет - Fl будет False т.е. аналог на Паскале - это развернутый IF ... then ... else
Fl будет изменяться в любом случае, а не только если условие истинно.


SPeller   (2002-04-04 08:48:00) [10]

И не надо считать меня за полного ламера.


SPeller   (2002-04-04 08:47:00) [11]

> ALL
Допустим такой массив: (1,2,3,4,5,6), проверяем на наличие цифры 5. Тогда при проходе записи if a[j]=k then fl:=true через пятый элемент, fl станет true, при проходе через 6-й, таким же и останется. А запись fl:=a[j]=k на пятом элементе станет true, а на шестом СНОВА FALSE !!!


Song   (2002-04-04 08:39:00) [12]

2Poirot © (04.04.02 07:17)
if a[j]=k then fl:=true;....
Это остаточные явления программирования на Паскале. Со временем проходит.
Я тоже когда-то долго писал что-то вроде того: :)))
IF Flag then AdminSet:=True else AdminSet:=False;


SPeller   (2002-04-04 08:35:00) [13]

Poirot ©
Нет, нам надо отловить хотябы одно сходство, а если последний проверяемый элемент неравен, то fl будет false и никакого сходства мы не обнаружим.


Poirot   (2002-04-04 07:17:00) [14]


> SPeller ©

Маленькое замечание... А вы приколно написали
if a[j]=k then fl:=true;.... Мне понравилась шутка
а так не пойдёт fl:=a[j]=k


MBo   (2002-04-04 07:09:00) [15]

без использования доп. массива или списка, но с замедлением
из-за коллизий

randomize;
fillchar(a[1],10*sizeof(integer),0);
i:=0;
while i<10 do begin
j:=random(10)+1;
if a[j]=0 then begin
inc(i);
a[j]:=i;
end;
end;


MBo   (2002-04-04 06:59:00) [16]

procedure TForm1.Button2Click(Sender: TObject);
var i,j:integer;
list:tlist;
a:array[1..10] of integer;
begin
list:=tlist.create;

for i:=1 to 10 do
List.add(pointer(i));
randomize;
for i:=1 to 10 do begin
j:=random(list.count);
a[i]:=integer(list[j]);
list.delete(j);
end;

list.free;
for i:=1 to 10 do
memo1.lines.add(inttostr(a[i]));
end;


Fantasist   (2002-04-04 06:48:00) [17]

Не, оба этих алгоритма неэффективны - они основаны на той же проверке от которой хотели уйти. Если диапазон большой, то количество повторно выпадающих элементов может стать довольно большим особенно ближе к полному заполнению массива.
Я бы предложил такой алгоритм:

var
a1: array [1..10] of integer=(1,2,3,4,5,6,7,8,9,10);
a: array [1..10] of integer;
k: integer;
i: integer;
begin
for i:=0 to 9 do
begin
k:=random(9-i)+1;
a[i+1]:=a1[k];
a1[k]:=a1[10-i];
end;
end;

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


EsKor   (2002-04-04 05:49:00) [18]

Для этого случая можно применить алгоритм подобный следующему:

const
dim = 10;
var
A: array [1..dim] of integer;
A1: array [1..dim] of boolean; //Массив контроля уникальности
N: integer;
i: word;
begin
randomize;
for i := 1 to dim do A1[i] := false; //Чисел в A еще нет
for i := 1 to dim do
begin
repeat
N := random(dim) + 1; //получить число
until not A1[N]; //если такое есть (A[N]:=true) - повторить
A[i] := N; //получ.уникальное число - заносим в массив
A1[N] := true; //и учитываем его
end; {for}
end;

В таком виде он конечно не будет работать в случае если ваш массив нужно заполнить значениями не совпадающими со значениями индекса массива. Например, нужно заполнить десятью значениями из диапазона от 10 до 100 с шагом 10, или без всякого шага от 32 до 812.


SPeller   (2002-04-04 02:52:00) [19]

Да, в var добавить a:array[1..10] of integer;


SPeller   (2002-04-04 02:51:00) [20]

var i,j,k:integer;
begin
randomize;
while i<=10 do begin
k:=round(random(9)+1);
for j:=1 to i-1 do
if a[j]=k then fl:=true;
if fl then dec(i) else a[i]:=k;
inc(i);
fl:=false;
end;


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо