Помощь - Поиск - Пользователи - Календарь
Полная версия: Метод индуктивной функции..часть 2
Форум «Всё о Паскале» > Разработка ПО, алгоритмы, общие вопросы > Алгоритмы
Olya
blink.gif У меня тоже проблемы с этим методом, только задание другое:

Дана последовательность вещественных чисел, заданная в типизированном файле. Методом индуктивной функции вычислить среднюю длину связных подпоследовательностей отрицательных чисел.

Что здесь можно сделать? wacko.gif smile.gif
Lapp
Если честно, непонятно..
Я бы не назвал функцию "средняя длина связных подпоследовательностей отрицательных чисел" индуктивной в данном случае..
Твои соображения? Или, может, преп на что-то намекал?..
Olya
Вот попытка написать подпрограмму, проверяйте:
blink.gif
{
Переменные, для вычисления значения функци
vi_Scet - общее количество отрицательных чисел в массиве,
vi_N - количество цепочек отрицательных символов;
vt_Text - дескриптор стандартного типа файлов;
vi_x - Буфферная переменая. Служит для обмена с файловыми данными;
vr_Long - Переменная фиксирующая значение функции;
vb_f0 – флаг принадлежности к цепочке;
(Индуктивное расширение имеет два решения
vb_f0=true - Данные верны, дополняем множество решений;
vb_f0=false -Данные не верны, обрыв цепочки)
}

type
v_Integer: integer;
v_Bool: boolean;
v_Text: text;
v_Real: real;
.
.
.

{
Функция inductiv Проверяет принадлежность входных данных к цепочке отрицательных элементов.
Входные параметры:
x: формальный параметр «входные данные»
побочный эффект: ТRUE данные принадлежат к цепочке, FALSE - нет
}

function inductiv(x:v_Integer):boolean;

begin
if x<0 then
inductiv:=true
else
inductiv:=false;
end;

{
Процедура расчёта средней длины связных подпоследовательностей отрицательных чисел. Входные данные хранятся в стандартном файле.
vr_Long - выходной параметр «Результат расчёта»
}

procedure Sr_Lenght(var: vr_Long: v_Real);

var
vt_Text: v_text;
vi_x,vi_Scet, vi_N: v_Integer;
vr_Long: v_Real;
f0: v_Bool;

begin
AssignFile(vt_Text,'Dan.txt');//Указавем путь к файлу данных
reset(vt_Text); //Устанавливаем готовность к чтению данных

//Инициализируем переменные
vi_Scet:=0; vi_N:=0; f0:=true;

repeat
readln(vt_Text,vi_x); //Считываем данные из файла

if inductiv(vi_x)=true then //если «цепочка», подсчитываем кол
begin
inc(vi_Scet); //Счётчик элементов=+1
f0:=true end //Сохраняем текущее значение функции
else // «Обрыв»
if f0=true then
begin
f0:=false; //Сохраняем текущее значение функции
inc(vi_N) end; //Счётчик «цепочек»=+1
until Eof(vt_Text); //Повторяем процесс, пока не достигнут конец файла.

{Обрабатываем ситуацию - отрицательных элементов нет}
if scet=0 then writeln('ОТРИЦАТЕЛЬНЫХ ЭЛЕМЕНТОВ НЕТ!')
else
srLong:=scet/n;//Вычисляем значения функции

end;
.
.
.
end.
no1.gif yes2.gif

М
Использование тегов - это требование Правил!
(Выделить текст программы блоком и выбрать нужный тип кода в меню CODE над окном ввода)
Lapp

Lapp
Ну, неплохо! smile.gif
Наворочено, конечно... ладно, разберемся, исправим! smile.gif

Единственное, что могу сказать сразу: твоя "индуктивная функция" совершенно, увы, не индуктивна.. Но в целом идея понятна, можно сделать ее и индуктивной.

Я отвечу немного позже - через часок. Если, конечно, никто не напишет раньше smile.gif
Lapp
Olya, давай договоримся: ты будешь сама пробовать компилировать свои программы.
Компилятор у тебя есть? По крайней мере выловишь очевидные ляпы (тип объявляется через равенство, всякие лишние символы - только в коментариях, аосле var двоеточие не нужно, переменные объявляются один раз, все переменные должны быть объявлены..). Ты согласна? Тогда двигаемся дальше..

Скажи, зачем ты переназвала стандартные типы? Вас так учат? Я бы все же делал это только там, где это осмысленно..

Формат такой, что программу читать трудно - отступы скачут без системы. Видно вроде, что ты хотела чего-то добиться этим - но чего?.. Правила простые:
1. блоки объявлений желательно сдвинуть (это у тебя есть)
2. После каждого begin (и repeat) все следующие строки получают дополнительный сдвиг на Таб (обычно Таб=2, но можно делать и 4 или даже 3, только выдерживать принятое значение на протяжении программы)
3. end (и until), если он не закрывает begin (repeat) на той же строке, должен стоять в начале строки. Эта строка и все после нее пишутся с отступом, уменьшенным на Таб.
Вот, практически, и все. Бегин двигает вправо, энд влево. Сложно? smile.gif
Еще одно: не надо так разрывать условный оператор. То, что стоит после then или else - должно стоять на той же строчке, если позволяет длина. Если не позволяет - желательно забрать в блок и сдвинуть уже по правилу бегин-энд.. При этом бегин должен стоять сразу за then (else).
Лишние (пустые) строки ставь только там, где это чем-то обусловлено (например, разделить процедуры друг от друга, выделить структурный блок, если нужно).
Вот так выглядит твоя программа, если ее причесать:
{
Переменные, для вычисления значения функци
vi_Scet - общее количество отрицательных чисел в массиве,
vi_N - количество цепочек отрицательных символов;
vt_Text - дескриптор стандартного типа файлов;
vi_x - Буфферная переменая. Служит для обмена с файловыми данными;
vr_Long - Переменная фиксирующая значение функции;
vb_f0 - флаг принадлежности к цепочке;
(Индуктивное расширение имеет два решения
vb_f0=true - Данные верны, дополняем множество решений;
vb_f0=false -Данные не верны, обрыв цепочки)
}

type
v_Integer = integer;
v_Bool = boolean;
v_Text = text;
v_Real = real;

{
Функция inductiv Проверяет принадлежность входных данных к цепочке отрицательных элементов.
Входные параметры:
x: формальный параметр <входные данные>
побочный эффект: ТRUE данные принадлежат к цепочке, FALSE - нет
}

function inductiv(x:v_Integer):boolean;
begin
if x<0 then inductiv:=true else inductiv:=false;
end;

{
Процедура расчёта средней длины связных подпоследовательностей отрицательных чисел.
Входные данные хранятся в стандартном файле.
vr_Long - выходной параметр <Результат расчёта>
}

procedure Sr_Lenght(var vr_Long: v_Real);
var
vt_Text: v_text;
vi_x,vi_Scet, vi_N: v_Integer;
f0: v_Bool;

begin
Assign(vt_Text,'Dan.txt');//Указавем путь к файлу данных
reset(vt_Text); //Устанавливаем готовность к чтению данных

//Инициализируем переменные
vi_Scet:=0; vi_N:=0; f0:=true;

repeat
readln(vt_Text,vi_x); //Считываем данные из файла
if inductiv(vi_x)=true then begin //если <цепочка>, подсчитываем кол
inc(vi_Scet); //Счётчик элементов=+1
f0:=true
end //Сохраняем текущее значение функции
else if f0=true then begin // <Обрыв>
f0:=false; //Сохраняем текущее значение функции
inc(vi_N)
end; //Счётчик <цепочек>=+1
until Eof(vt_Text); //Повторяем процесс, пока не достигнут конец файла.

{Обрабатываем ситуацию - отрицательных элементов нет}
{if scet=0 then writeln('ОТРИЦАТЕЛЬНЫХ ЭЛЕМЕНТОВ НЕТ!')
else srLong:=scet/n;//Вычисляем значения функции}
end;

begin
end.

Пожалуйста, разберись с этим, а я пока продолжу по существу..

Добавлено через 4 мин.
Последний блок я закомментировал, так как не стал разбираться, что такое scet и как его объявлять. Надеюсь, ты это исправишь сама.
Lapp
Короче, вот..
В твоей программе слишком много нужно было переделывать, и мне очень не хотелось тянуть твои громоздкие названия в такой простой программе. Выкладываю текст работающей программы в надежде, что ты разберешься сама, что к чему.

Поясню только основной момент, про индуктивную функцию. Индуктивной, грубо говоря, называется функция, которую можно посчитать через предыдущий результат. В нашем случае, перед считыванием очередного числа мы как бы уже имеем длину текущей цепочки. Считываемое число либо оборвет ее, либо увеличит на единицу. То есть предыдущий результат лтбо фиксируется, либо увеличивается и смотрится, что там дальше. Иначе говоря, на каждом этапе мы должны воспользоваться результатом предыдущего этапа. А это значит, что можно использовать то, что в программировании называется рекурсия: вызов функции из тела самой этой функции. Именно это и характеризует индуктивность функции (одного названия, увы, недостаточно smile.gif).

Посмотри внимательно на тело функции, особенно присвоение:
NegChainL:=NegChainL+1
В левой части стоит значение, которое возвратит функция по окончании своей работы, а в правой то же самое слово представляет собой последующий вызов этой же функции. Это и есть рекурсия (в переводе на русский - повторный вход). При этом в стеке создается еще одна копия всех данных этой функции, так что, например, переменная a в ней уже не равна переменной a в вызвавшей функции. Программный код же используется тот же самый. Вложенных вызовов может быть очень много - сколько позволит размер стека. Если стек переполнится, программа свалится, но в нашем случае такое вряд ли случится - несколько десятков вложений вполне нормально.

Данные читай из файла negchain.dat - по одному чилу на строке.

Я не написал никаких комментариев - добавь их, пожалуйста, сама. И покажи тут, что у тебя получилось.
Успехов! smile.gif
{Average negative chain length calculating}
{by Lapp}
var
f:text;
n,l,m:integer;

function NegChainL:integer;
var
a:real;
begin
ReadLn(f,a);
if EoF(f) or(a>0) then NegChainL:=0 else NegChainL:=NegChainL+1
end;

begin
Assign(f,'NegChain.dat');
Reset(f);
n:=0;
m:=0;
repeat
l:=NegChainL;
if l>0 then begin
Inc(n);
m:=m+l
end
until EoF(f);
Close(f);
if n=0 then WriteLn('No negative chains found')
else WriteLn('The average negative chain length is ',m/n:8:3);
end.
Olya
smile.gifАндрей, приветик, вот проверяй...а ты уверен, что функция NegChainL - индуктивная? У нас просто называют её рекурсивной...или я так поняла, это всё взаимосвязано? Ещё по заданию, эта подпрограмма должна написана в стиле защитного программирования, то есть должны быть предусмотрены всевозможные коды ошибок. Здесь я так понимаю, тоже это есть. Вот..мне ещё нужно описать необходимые типы данных и составить полную спецификацию, которая должна содержать задачу функции (самой подпрограммы)...входные, выходные данные..и вот те возможные значения функции, ей присваиваемые...Как это оформить..? wacko.gif yes2.gif

{Average negative chain length calculating}
{by Lapp}var
f:text;
n,l,m:integer;

{функция NegChainL
если значение считанного элемента отрицательно, значение функции увеличивается на 1
в противном случае обнуляется}
function NegChainL:integer;:

var
a:real;
begin
ReadLn(f,a); // чтение входных данных
if EoF(f) or(a>0) then NegChainL:=0 else NegChainL:=NegChainL+1//если конец файла или
//a>0 то значение функции=0, иначе значение функции+1;
end;

begin
Assign(f,'NegChain.dat');//связываемем имя файла с файловой переменной
Reset(f); //готовим файл к чтению
n:=0; //инициализируем переменные
m:=0;
repeat
// (*)
l:=NegChainL; //переменной l присваиваем значение функции
if l>0 then begin //Если l>0
Inc(n); //счётчик цепочек+1
m:=m+l //счётчик орицательных элементов+!
end
until EoF(f); //если не конец файла, повторяем процесс (*)
Close(f); //Закрываем файл
//Вывод результата
if n=0 then
WriteLn('No negative chains found')
else WriteLn('The average negative chain length is ',m/n:8:3);
end.
wub.gif
Lapp
Что проверять? комментарии? они программу не портят smile.gif.
Почему-то опять появилось несколько непонятных сдвигов.. почему ты их так любишь? Неправильные сдвиги - это так же плохо, как и отсутствие сдвигов..
Цитата(Olya @ 28.03.2007 9:50) *

а ты уверен, что функция NegChainL - индуктивная? У нас просто называют её рекурсивной...или я так поняла, это всё взаимосвязано?
Да, связано. Индуктивная - это название из математики, а рекурсивная - из программирования. Индуктивность означает вычисляемость через последний результат и новый элемент.
Цитата(Olya @ 28.03.2007 9:50) *

Ещё по заданию, эта подпрограмма должна написана в стиле защитного программирования, то есть должны быть предусмотрены всевозможные коды ошибок. Здесь я так понимаю, тоже это есть.
Нет, не учтено. Я так понял, что должна быть защита, например, от случая, когда во входном файле вместо числа вдруг появится буква.. Этот вариант программы на этом обломается - можешь попробовать. Вставить такую защиту - дело не самое тривиальное, если все учитывать.
Цитата(Olya @ 28.03.2007 9:50) *

Вот..мне ещё нужно описать необходимые типы данных и составить полную спецификацию,
...
Как это оформить..?
Как с вас требуют, так и оформляй smile.gif, я тут не помощник. Если посмотреть на твой начальный текст, так вас там так учат, что и не расхлебаешь.. Так что - я не хочу потом упреков, что все неправильно сказал. Программа работает - вот весь с меня спрос..
Если хочешь - можешь советоваться, конечно. Пиши тут, в чем сомневаешься, сли сможем - поможем..
Успехов!


Добавлено через 2 мин.
PS
Как тебе удалось навставлять столько пробелов в конце программы?.. blink.gif насилу вычистил..
how does plaquenil work for lupu
Amoxil Safe During Breastfeeding
prednisone without a prescriptio
Cialis 36 Heures
how long does gabapentin stay in
Priligy Nous
generic valtrex overnight delive
Isotretinoin For Sale Internet
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.