2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




Начать новую тему Ответить на тему
 
 Прохождение по циклу с произвольным числом счётчиков
Сообщение20.11.2008, 23:48 
Аватара пользователя


17/05/08
358
Анк-Морпорк
В ходе написания появилась постребность проводить перебор по количеству параметров, заранее неизвестному. Для этих целей построил такой алгоритм (описан на Паскале), может кому ещё пригодится:

Динамические массивы a – массив счётчиков m – максимальных значения для каждого из счётчиков. Минимальные значения каждого из счётчиков равны 0. Всего счётчиков maxI+1: от a[0] до a[MaxI].

В алгоритме используются две метки – похоже этот тот случай, когда их использование оправдано

Вначале все счётчики – нули.

i:=maxI;

lb0: While i<maxI do inc(i);
///////////////
Собственно тело цикла
///////////////

lb1: inc(a[i]);
if a[i]>m[i] then
begin
a[i]:=0;
dec(i);
if i<0 then exit;
goto lb1;
end
else
goto lb0;

 Профиль  
                  
 
 
Сообщение21.11.2008, 05:10 
Аватара пользователя


31/10/08
1244
While i<maxI do inc(i); Ужас заменяется на i:=maxI;
Отметок можно избавиться
Код:
i:=maxI;
repeat
inc(a[i]);
if a[i]>m[i] then
  begin
  a[i]:=0;
  dec(i);
  end else  i:=maxI;
until i<0


Только по моему, тут у тебя еще и ошибка в коде.

 Профиль  
                  
 
 
Сообщение21.11.2008, 13:04 
Аватара пользователя


17/05/08
358
Анк-Морпорк
Pavia писал(а):
While i<maxI do inc(i); Ужас заменяется на i:=maxI;


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

Pavia писал(а):
While i<maxI do inc(i); Ужас заменяется на i:=maxI;


По поводу реализации без goto – в твоём варианте надо бы что-то под корректировать, вот попробуй повесить на кнопочку в форме с компонентом Memo такой код:

Код:
procedure TForm1.Button1Click(Sender: TObject);
var i,j:integer;
s:string;
label lb0;
label lb1;

begin
Memo1.clear;
maxI:=4; //Инициализируем массивы, пусть переменных будет 5
setlength(a,maxI+1);
setlength(m,maxI+1);
for j:=0 to maxI do
m[j]:=j+2;
for j:=0 to maxI do
a[j]:=0;
i:=maxI;

lb0: While i<maxI do inc(i);
/////////////// Собственно тело цикла
  s:='';
  for j:=0 to maxI do
   s:=s+inttostr(a[j]);
  memo1.Lines.Add(s);
///////////////

lb1: inc(a[i]);
     if a[i]>m[i] then
      begin
        a[i]:=0;
        dec(i);
        if i<0 then exit;
        goto lb1;
      end
     else
      goto lb0;
end;


Он должен в Мемо1 вывести список всех 5-ти значных чисел, у которых первая цифра от 0 до 2, вторая – от 0 до 3, и т.д., пятая – от 0 до 6.

И такой:
Код:
procedure TForm1.Button2Click(Sender: TObject);
var i,j:integer;
s:string;
begin
Memo1.clear;
maxI:=4;
setlength(a,maxI+1);
setlength(m,maxI+1);
for j:=0 to maxI do
m[j]:=j+2;
for j:=0 to maxI do
a[j]:=0;
i:=maxI;

repeat
/////////////// Тело цикла должно быть здесь ведь, до первого изменения счётчика?
  s:='';
  for j:=0 to maxI do
   s:=s+inttostr(a[j]);
  memo1.Lines.Add(s);
///////////////

inc(a[i]);
if a[i]>m[i] then
  begin
  a[i]:=0;
  dec(i);
  end else  i:=maxI;
until i<0;

end;

Здесь будут выдаваться лишние числа.

Добавлено спустя 13 минут 15 секунд:

Похоже, понял как надо подправить код, чтобы обойтись без меток:

Код:
while true do
begin
  i:=maxI;
///////////////Тело цикла
  s:='';
  for j:=0 to maxI do
   s:=s+inttostr(a[j]);
  memo1.Lines.Add(s);
///////////////
inc(a[i]);
  while a[i]>m[i] do
  begin
    a[i]:=0;
    dec(i);
    inc(a[i]);
    if i<0 then exit;
  end;

end;

 Профиль  
                  
 
 
Сообщение21.11.2008, 15:37 
Аватара пользователя


31/10/08
1244
Цитата:
Здесь будут выдаваться лишние числа.

Я конечно понимаю в чужом коде труднее разбираться.

Код:
procedure TForm1.Button2Click(Sender: TObject);
var i,j:integer;
s:string;
begin
Memo1.clear;
maxI:=4;
setlength(a,maxI+1);
setlength(m,maxI+1);
for j:=0 to maxI do
m[j]:=j+2;
for j:=0 to maxI do
a[j]:=0;
i:=maxI;


/////////////// Тело цикла должно быть здесь ведь, до первого изменения счётчика?
  s:='';
  for j:=0 to maxI do
   s:=s+inttostr(a[j]);
  memo1.Lines.Add(s);
///////////////

repeat

inc(a[i]);
if a[i]>m[i] then
  begin
  a[i]:=0;
  dec(i);
  end else begin
  i:=maxI;
/////////////// Тело цикла должно быть здесь ведь, до первого изменения счётчика?
  s:='';
  for j:=0 to maxI do
   s:=s+inttostr(a[j]);
  memo1.Lines.Add(s);
///////////////

  end;
until i<0;

end;

 Профиль  
                  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 4 ] 

Модераторы: Karan, Toucan, PAV, maxal, Супермодераторы



Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group