Форум: "Основная";
Текущий архив: 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]Гарантированая перестановка всех элементов, за минимально короткий цикл
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2002.04.15;
Скачать: [xml.tar.bz2];
Память: 0.52 MB
Время: 0.004 c