Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

Восстановить пароль

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 26.03.2013, 23:19   #1
Solidera
Пользователь
 
Регистрация: 26.03.2013
Сообщений: 14
По умолчанию Рекурсивная функция

Задача: Для заданного одномерного массива X из N элементов найти произведение множителей, вычисляемых по формуле x[i]/(i+1). Рекурсивную функцию применять каждый раз отдельно для каждой из половин массива. Рекурсивные вызовы заканчивать, когда останется только один элемент.

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

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

Код:
type
  mas=array of integer;

procedure TForm1.FormCreate(Sender: TObject);
var i: byte;
  begin
    StringGrid1.Cells[0,0]:='#';
    StringGrid1.Cells[0,1]:='X';
    for i:=1 to StringGrid1.ColCount-1 do
      StringGrid1.Cells[i,0]:=IntToStr(i);
  end;

procedure TForm1.Edit1Change(Sender: TObject);
  begin
    StringGrid1.ColCount := UpDown1.Position+1;
    StringGrid1.Cells[UpDown1.Position,0]:=IntToStr(UpDown1.Position);
  end;

function Proizv(const X:mas; i:Byte; n:byte):real;
begin
  If i=n-1 then Result:=x[i]/(i+1)
  else Result:=(Proizv(x,i,(i+(n-i)div 2)))*(Proizv(x,(i+(n-i) div 2) +1,n));
end;


procedure TForm1.Button1Click(Sender: TObject);
  var
    x: mas;
    n,i: byte;
    flag: boolean;
  begin
    n:=UpDown1.Position;
    SetLength(x,n);
    flag:=true;
    try
     for i:=1 to n do
       x[i-1]:=StrToInt(StringGrid1.Cells[i,1]);
    except
    flag:false;
      ShowMessage('Некорректное значение '+IntToStr(i)+'-го элемента массива');
    end;

    if flag then 
    begin
      Label2.Caption:=FloatToStr(Proizv(X,0,n-1));
    end;
  end;

procedure TForm1.UpDown1Changing(Sender: TObject; var AllowChange: Boolean);
  var n,i:byte;
begin
n:=updown1.position;
for i:=1 to n+1 do
stringgrid1.Cells[i,1]:='0';
end;

end.
Изображения
Тип файла: png x.png (8.2 Кб, 180 просмотров)
Solidera вне форума Ответить с цитированием
Старый 27.03.2013, 05:11   #2
Larboss
Недо
Участник клуба
 
Регистрация: 11.08.2011
Сообщений: 1,394
По умолчанию

Код:
var n,i:byte;
...
n,i: byte;
...
var i: byte;
Зачем их каждый раз локально объявлять? Глобальными сделайте их

Код:
function Proizv(const X:mas; i:Byte; n:byte):real;
begin
  If i=n-1 then Result:=x[i]/(i+1)
  else Result:=(Proizv(x,i,(i+(n-i)div 2)))*(Proizv(x,(i+(n-i) div 2) +1,n));
end;
Ошибка скрывается где-то здесь.
С помощью программирования можно разбогатеть и изменить мир к лучшему (с) Бьерн Страуструп
Larboss вне форума Ответить с цитированием
Старый 30.03.2013, 21:26   #3
Solidera
Пользователь
 
Регистрация: 26.03.2013
Сообщений: 14
По умолчанию

Цитата:
Сообщение от Larboss Посмотреть сообщение
Ошибка скрывается где-то здесь.
Спасибо... Я, в принципе, это понимаю. Конкретный вопрос: что именно в "где-то здесь" может вызывать неверные результаты при n=2 и переполнение стека при n>=3 и n=1(!)? Дебаггер говорит, что при указанных значениях функция зацикливается.

Глаза у меня уже замыленные: умоляю, ткните носом в ошибку.
Solidera вне форума Ответить с цитированием
Старый 30.03.2013, 21:53   #4
Sciv
Старожил
 
Аватар для Sciv
 
Регистрация: 16.05.2012
Сообщений: 3,211
По умолчанию

Код:
(Proizv(x,(i+(n-i) div 2) +1,n)
Думаю, проблема тут
Начал решать проблему с помощью регулярных выражений. Теперь решаю две проблемы...

Последний раз редактировалось Sciv; 30.03.2013 в 21:56.
Sciv вне форума Ответить с цитированием
Старый 30.03.2013, 22:55   #5
Solidera
Пользователь
 
Регистрация: 26.03.2013
Сообщений: 14
По умолчанию

Эмм... Поправьте, если неправильно рассуждаю:
n - позиция UpDown1, показывает, сколько элементов в массиве.
Массив динамический, элементы считаются с нуля, значит, по-русски номер последнего элемента равен n-1.
Предположила, что дело в этом. Поменяла там, где Sciv указал, на n-1. Не помогло.

Я туплю сейчас отчаянно, не обессудьте.
Solidera вне форума Ответить с цитированием
Старый 01.04.2013, 21:57   #6
Solidera
Пользователь
 
Регистрация: 26.03.2013
Сообщений: 14
По умолчанию

Хм, я чуть поменяла код, теперь нет проблем с зацикливанием. Но когда в ответе должна получаться единица (и не только тогда!), вылазит число 2304772. Смешно, право слово.
Код:
function Proizv(const X:mas; n:byte):real;
  function Recurse(i,j: byte):double;
  begin
    If i=j then Result:=x[i]/(i+1)
    else Result:=(Recurse(i,(i+j)div 2))*(Recurse(((j+i) div 2)+1,j));
  end;
begin
  Result:=Recurse(1,n);
end;
Далее в программе функция вызывается так:
Код:
Label2.Caption:=FloatToStr(Proizv(X,n))
Когда поменяла там, где в коде красно, n на n-1, при трёх элементах массива результат (при ожидаемой в связи с введёнными исходными значениями единице) равнялся 1,5 (уже лучше). При двух элементах массива - снова переполнение стека, мать его за ногу.
Solidera вне форума Ответить с цитированием
Старый 02.04.2013, 09:45   #7
Solidera
Пользователь
 
Регистрация: 26.03.2013
Сообщений: 14
По умолчанию

Отбой тревоги. Я кретин.
Код:
If i=j then Result:=x[i]/(i+1)
- x[i] меняем на x[i-1].

Если в массиве один элемент - i=1; массив-то динамический, считаем с нуля...
Solidera вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Рекурсивная функция на C++ spam12 Помощь студентам 3 09.02.2012 16:22
Рекурсивная функция C++ Buryy_Mishka Помощь студентам 0 31.05.2010 00:27
Рекурсивная функция Bernuar Помощь студентам 2 06.04.2010 10:07
Си++. Рекурсивная функция. Diamond2107 Помощь студентам 6 02.12.2009 19:48