Форум: "Основная";
Поиск по всему сайту: delphimaster.net;
Текущий архив: 2002.04.15;
Скачать: [xml.tar.bz2];




Вниз

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


UDS   (2002-04-03 23:07) [0]

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



VID   (2002-04-03 23:13) [1]

перед циклом напищи

RANDOMIZE;



Song   (2002-04-03 23:21) [2]

Random не может гарантировать Вам, что не выпадут повторяющиеся ранее числа. Чтобы ограничить совпадение, Вам нужно после каждого Random, проверять на совпадение всю цепочку.



UDS   (2002-04-03 23:21) [3]

Да RANDOMIZE стественно написан, но это не спасает от случайного повторного выпадения какого-либо числа. Получается что-то типа-
4 5 2 1 2 8 6 9 4 7 . Видим что числа 4 и 2 повторяются и присутствие RANDOMIZE не спасает.



Song   (2002-04-03 23:31) [4]

2UDS © (03.04.02 23:21)
VID © (03.04.02 23:13) просто пошутил, у него 1-ое Апреля запоздалое.



UDS   (2002-04-03 23:42) [5]

Проверять всю цепочку IFами это не выход. Что будет если значений в массиве будет гораздо больше, или это будет вообще 2-мерный массив? Кто-то мне говорил что эта проблема решаема с помощью обмена между двумя(?) значениями с помощью SWAP. Но я толком не понял как это сдулать. Я ваще не знаю пока еще что такое SWAP и с чем его едят. Думал что тут мне разжуют это дело.
Я UDS...Прием...



Anatoly Podgoretsky   (2002-04-03 23:48) [6]

Сначало заполни массив последовательно цифрами от 1 до 10, а зптем перетасуй ч помощью random



UDS   (2002-04-03 23:49) [7]

КАК ПЕРЕТАСОВАТЬ????????????



UDS   (2002-04-03 23:51) [8]

Заполняю for i:=1 to 10 do A[i]:=i; а дальше Как смешать?



UDS   (2002-04-04 00:15) [9]

1 2 3 4 5 6 7 8 9 10 КАК ПЕРЕМЕШАТЬ? А-У! Ну ответьте, плиз!!!!!!!!!!!!!!!!



Chepel   (2002-04-04 00:30) [10]

тупой, но проверенный способ =)

для массива A[1..10] of Integer;
будет:

var
i, n: Integer;
r1, r2: Integer;
st: string;
begin
for i:=1 to 10 do
begin
r1 := Random(10)+1;
r2 := Random(10)+1;
n := a[r1];
a[r1] := a[r2];
a[r2] := n;
end;



Chepel   (2002-04-04 00:33) [11]

в догонку...
st: string; в предыдущем примере не нужно =) сорри...



UDS   (2002-04-04 00:50) [12]

Chepel Проверил-работает!!!!! На досуге разберусь поглубже. Пиво за мной!!!!!
P.S. Тема не закрывается. Кто придумает способ лучше- с удовольствием рассмотрим!



Fantasist   (2002-04-04 01:01) [13]

Ага. Я когда-то решал такую вещь только надо было заполнить случайными числами 1..n. Такой вариант(тут он не нужен но...):

1. Создаем пустой список S каждый элемент которого содержит 2 поля:
number
meaning
2. Берем случайное число k от 1..n,
3. Ищем k в списке S по полю number; ecли оно не находиться - присваиваем текущему элементу массива значение k, и в S добавляем запись:
number=k;
meaning=n;
ежели находиться, то текущему элементу массива присваеваим значение meaning, а meaning меняем на значение n.
4. Уменьшаем n на один и переходим к шагу 2.



SPeller   (2002-04-04 02:51) [14]

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;



SPeller   (2002-04-04 02:52) [15]

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



EsKor   (2002-04-04 05:49) [16]

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

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.



Fantasist   (2002-04-04 06:48) [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;

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



MBo   (2002-04-04 06:59) [18]

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;



MBo   (2002-04-04 07:09) [19]

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

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;



Poirot   (2002-04-04 07:17) [20]


> SPeller ©

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



SPeller   (2002-04-04 08:35) [21]

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



Song   (2002-04-04 08:39) [22]

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:47) [23]

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



SPeller   (2002-04-04 08:48) [24]

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



Song   (2002-04-04 08:53) [25]

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



Song   (2002-04-04 08:54) [26]

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



panov   (2002-04-04 08:55) [27]

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

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

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



SPeller   (2002-04-04 08:57) [28]

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; ! Чуешь разницу ?? При ложности условия ничего не выполняется!



Song   (2002-04-04 09:03) [29]

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



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

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



Stranger   (2002-04-04 11:11) [31]

Есть еще один вариантик проверки уникальности числа в массиве
все то же самое , 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



eSKey   (2002-04-04 13:26) [32]

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

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



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

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




Форум: "Основная";
Поиск по всему сайту: delphimaster.net;
Текущий архив: 2002.04.15;
Скачать: [xml.tar.bz2];




Наверх





Память: 0.78 MB
Время: 0.025 c
1-46407           Beginner              2002-03-30 15:44  2002.04.15  
Не знаю технологии


3-46258           B_A_V                 2002-03-25 09:31  2002.04.15  
что выьрать: Seagate Crystal Reports или XL Report G2?


3-46235           Rammst                2002-03-25 07:59  2002.04.15  
Определение ... (HELP!!!)


14-46495          Slava                 2002-03-07 12:33  2002.04.15  
Opera & cgi.exe


1-46340           Muzzy                 2002-04-04 09:33  2002.04.15  
Цвета в столбцах TStringGird