PDA

Просмотр полной версии : Pascal - Функциональная логическая схема



Hunto
01.05.2008, 22:09
Добрый день. Подскажите пожалуйста как решить следующую задачу :

" Нужно написать программу которая строит функциональную логическую схему за структурной формулой. "

Можете пожалуйста объяснить как это должно выглядеть? С чего начать? Я просто не представляю как ето должно выглядеть, возможно где-то есть похожие примеры.

насколько я понял задание мне нужно написать програму которая будет рисовать коньюкцию, дизьюкцию, вообщем елементарные логические операции.
например вводиш A&B&C а программа должо рисовать (с помощью graf) чтото типа етого :
http://infologos.narod.ru/234.htm


заранее большое спасибо за помощь

Хыиуду
02.05.2008, 00:16
Во-первых, спасибо вам, Hunto, за первую за уже долгое время интересную задачу в этой ветке форума! Честное слово, задачки типа "найти максимум в массиве", присылаемые школьниками и студентами-халявщиками, навязли в зубах.
Во-вторых, дайте по голове вашему преподавателю за криво поставленную задачу. Если бы такая задача ставилась не перед учеником, а перед программистом некоей конторы как проект за деньги, такой огрызок задания никто бы не принял. Постановка задачи растянулась бы страницы на 3 минимум, и все должно быть разжевано: начиная от того, как именно задавалась бы структурная формула, кончая тем, на каких же структурных элементах строить эту радость: на ключах, как показано на верхних рисунках по ссылке, или на логических элементах, как показано там же внизу.
В-третьих, скажите, пожалуйста, где находятся такие преподаватели, которые столь старательно учат студентов забивать гвозди микроскопом? Для решения этой задачи Паскаль с его библиотекой graph подходит едва ли не наихудшим образом. На том же Delphi все было бы гораздо симпатичнее. А если это задание дано для изучения упомянутой библиотеки, спросите своего преподавателя, если он водит машину, где он сдавал экзамен на права - в городе и на площадке, или на треках Формулы-1 и ралли Париж-Дакар? Более-менее такое задание оправдано только в качестве курсовой. И то - бред.
В-четвертых, непосредственно по самому заданию. Необходимо все же выяснить, на чем строить эту функциональную схему. Без этого дальнейшее обсуждение хода решения бессмысленно.

Hunto
02.05.2008, 12:11
Да преподаватель и сам, по-моему, не понимает как оно должно выглядеть, по крайней мере, объяснить конкретно он мне не смог.
Я думаю нужно делать так - как будет проще. Нижний вариант (по ссылке) по-моему выглядит более привлекательно
По поводу языка, задание нужно выполнять на Pascal или Cи , объектно-ориентированные языки запрещены, поэтому модуль graf будет использоваться в любом случае..
Только как это сделать я мало представляю.

p.s. Спасибо что откликнулись.

MOTOCoder
02.05.2008, 20:01
Такое впечатление, что препод воспроизвел когда-то где-то услышанную задачу, и сам не понимает, что нужно сделать и как. При такой постановке задачи сложно даже понять, с какой стороны подступиться. Во-первых, как уже сказал Хыиуду, нужно описание формата входных данных, но даже зная формат, придется писать не хилый анализатор выражений. Если, конечно, сложность вводимой формулы ограничена чем-то в роде A&B^C, тогда еще можно обойтись несложным алгоритмом, а так придется писать что-то довольно сложное и громоздкое. Но в таком случае действительно непонятно, почему запрещено использовать Delphi и прочие оъектные языки.

Hunto
02.05.2008, 20:36
мне кажется что будет достаточно формул вида A&B или A&B|C
а программа должна строить чтото вроде етого
http://www.imgstore.ru/files/OzTvMcGZtgvAxBedE4jFERHKiDr1K6dsHsIjfQoe.bmp

Хыиуду
03.05.2008, 00:34
Был бы еще Дельфи с нормальной работой с 1) изображениями, 2) классами - можно было бы делать так. А на Паскале, имхо, с плючами проще будет.
Имхо, один из вариантов делания - такой: находим последовательность выполнения логических операций (сначала, если не ошибаюсь, скобки, потом НЕ, И, ИЛИ. Каждое слагаемое будет иметь свой метод для рисования (например, одиночное слагаемое рисуется как __/ __), при этом в классе нужно хранить ширину и высоту получающегся рисунка. Потом описываются методы реализации операций. Например, для И - нарисовать первый компонент, справа от него второй. Или для ИЛИ - нарисовать первый компонент, снизу под ним второй, соединить их входы вертикальными линиями, от центра этих линий провести еще вход и выход налево и направо. Потом, проводя действия в известном порядке, заменяем, например А+В*С на А+D, где D=B*C, для него уже сформирована картинка и известна его ширина и высота.
Еще кстати, мнится мне, каждый кусок схемы, неважно, простой или сложный, должен иметь вход и выход (горизонтальные отрезки) посередине своей высоты. Чтобы потом не было торчащих отрезков проводов. Сумбурно разъяснил, но если что, могу расшифровать свое полуночное "несло" в аське.

Еще, если меня память не ошибает, все электронные логические схемы поголовно делаются только на элементах И-НЕ или (реже) ИЛИ-НЕ

И кстати, Turbo/Borland Pascal и C++ - вполне себе объектные языки, просто возможности графики там практически всегда ограничены режимом VGA - 640x480x16 цветов. Преподов-садистов, заставляющих использовать чистый Паскаль или чистый Си, я еще не видел. Хотя вру, видел - наш препод по Си в универе (с коих пор я Си и не люблю).

MOTOCoder
03.05.2008, 00:58
Да в принципе возможности графики здесь не принципиальны - можно хоть просто черным на белом фоне нарисовать с разрешением 320*200. А если мало 640*480*16 - можно VESA привинтить, там хоть 1024*768*256. Пусть препод удивится :) .

Hunto
03.05.2008, 18:44
теоретически я понял как это должно будет выглядеть.. а вот как это сделать программно ...

вы не встречали подобных исподников?

Хыиуду
04.05.2008, 11:47
Ну, к примеру, есть у нас выражение A+B*(C+D). Пишем какой-нибудь лексический анализатор, который нам зажевывает выражение и выдает, что сначала надо выполнить C+D, потом B*F1, где F1=C+D, потом A+F2, где F2=B*(C+D)
Пишем процедуру, которая вписывает нам в заданный прямоугольник изображение ключа и рисует над ним буковку.

Первое - C+D. Оба - элементарные выражения. Поэтому сначала тупо в центре экрана строим прямоугольник, скажем, 100х50 и врисовываем в него ключ С. Потом - раз уж у нас сложение - прямо под ним строим еще один такой же и врисовываем в него ключ D. Потом соединяем попарно их входы и выходы, и от линии, соединяющей входы, посредине ее отводим еще отрезок в 20 пикселей влево, а от линии выходов - 20 пикселей вправо. Потом заносим в массив: элемент F1, ширина 140 пикселей, высота 100 пикселей, координаты такие-то.
Следующее действие: B*F1. В у нас свободно гуляющий ключ, а вот F1 уже нарисован, и девать нам его совершенно некуда. Так что ставим слева от F1 еще один прямоугольник 100x50, пихаем туда ключ В, записываем уже F2, ширина 240 пикселей, высота 100 пикселй, координаты такие-то
Теперь A*F2, F2 уже нарисован, А еще нет. Кладем сверху на прямоугольник F2 вместо уже знакомого 100х50 240х50 (чтобы одинаковы по ширине были), рисуем в нем ключ А, соединяем входы и выходы - схема готова

Hunto
04.05.2008, 17:52
спасибо буду разбиратся, если все получится выложу ответ, может кому то пригодится

Hunto
24.05.2008, 20:46
добрый день. спасибо за то что помогли разобраться.
прошло достаточно времени задание немного изменилось (упростилось)
можно чтобы програма работала только с 3мя переменными и небыло скобок.

вот собственно что у меня получилось:


Program shem;
Uses Graph, Crt;
var gd,gm:integer; s,s1,s2,cr,inf,inf0:string;
f,n1,n2,n3,fn:string;
j,i:integer;
dx1,dx2,dy1,dy2,ly1,ly2,ly3,kx1,kx2,ky1,ky2,ey,k:i nteger;

procedure inv(k,ly1,ly2,ly3:integer);
begin
if k=1 then begin
rectangle (60,ly1,160,ly1+60);
line (160,ly1+30,220,ly1+30);
line (60,ly2,220,ly2);
line (60,ly3,220,ly3);
end else if k=2 then begin
rectangle (60,ly1,160,ly1+60);
line (160,ly1+30,220,ly1+30);
rectangle (60,ly2-30,160,ly2+30);
line (160,ly2,220,ly2);
line (60,ly3,220,ly3);
end else if k=3 then begin
rectangle (60,ly1,160,ly1+60);
line (160,ly1+30,220,ly1+30);
rectangle (60,ly2-30,160,ly2+30);
line (160,ly2,220,ly2);
rectangle (60,ly3-30,160,ly3+30);
line (160,ly3,220,ly3);
end; end;

procedure disj(dx1,dy1,dx2,dy2:integer);
begin
rectangle (dx1,dy1,dx1+100,dy1+200);
line (dx1+100,dy1+100,dx1+160,dy1+100);
line (dx2,dy2,dx2+160,dy2);
end;

procedure konj(dx1,dy1,dx2,dy2:integer);
begin
rectangle (kx1,ky1,kx1+100,ky1+200);
line (kx1+100,ky1+100,kx1+160,ky1+100);
line (kx2,ky2,kx2+160,dy2);
end;

procedure line1(n1,n2,n3:string);
begin
settextstyle(3,0,2);
line (0,140,60,140);
OutTextXY (5,110,n1);
line (0,260,60,260);
OutTextXY (5,230,n2);
line (0,380,60,380);
OutTextXY (5,350,n3);
end;
procedure endline(k,y:integer;f:string);
begin
settextstyle(3,0,1);
if (k>0) then
line (540,y,640,y)
else
line (380,y,640,y);
OutTextXY (545,y-30,f);
end;

begin
{VVOD FORMULU}
write (' ');
writeln ('| & - KONUNKCIYA ; v - DIZUNKCIYA ; ! - INVERSIYA |');
write (' ');
writeln ('| PRIMER: A&BvC |');
write (' ');
writeln ('|_______________________________________________ __|');
writeln; writeln ('Vvedite formulu:'); readln (f);
{end VVOD}

{Peremennue}
j:=1; for i:=1 to length(f)
do begin
if (f[i]<>'!')and(f[i]<>'V')and(f[i]<>'&')and(f[i]<>'v')
then begin
fn[j]:=f[i]; j:=j+1;
end;end;
n1:=fn[1]; n2:=fn[2]; n3:=fn[3];
{end peremennue}

{inversiya}
for i:=1 to length(f)
do begin
if (f[i]='!') then begin k:=k+1;
if (f[i+1]=n1) then begin
ly1:=110; ly2:=260; ly3:=380; end
else if (f[i+1]=n2) then begin
ly1:=230; ly2:=140; ly3:=380; end
else if (f[i+1]=n3) then begin
ly1:=350; ly2:=260; ly3:=140; end;
end;end;
{end inversiya}

{konjunkciya}
for i:=1 to length(f)
do begin
if (f[i]='&') then begin
if (f[i+1]=n2)or(f[i+2]=n2) then begin
ky1:=100; ky2:=380; end
else if (f[i+1]=n3)or(f[i+2]=n3) then begin
ky1:=220; ky2:=140 end;
if (k>0) then begin kx1:=220; kx2:=220; end
else begin kx1:=60; kx2:=60; end;
end;end;
{end konjunkciya}

{disjunkciya}
for i:=1 to length(f)
do begin
if (f[i]='v')or(F[i]='V') then begin
if (f[i+1]=n2)or(f[i+2]=n2) then begin
dy1:=130; dy2:=380; ey:=230; end
else if (f[i+1]=n3)or(f[i+2]=n3) then begin
dy1:=190; dy2:=140; ey:=290; end;
if (k>0) then begin dx1:=380; dx2:=-200; end
else begin dx1:=220; dx2:=-200; end;
end;end;

{GLAVNAYYA CHAST ANALIZATORA}

gd:=9; gm:=2;
InitGraph (gd,gm, 'C:\Apps\tp\bgi');
If GraphResult = 0 then begin
{interface}
cr:='Hunter'; inf0:='Uslovnie oboznacheniya:';
inf:='& - KONUNKCIYA ; V - DIZUNKCIYA ; ! - INVERSIYA';
settextstyle(2,0,0); setcolor (7); OutTextXY (518,470,cr);
setfillstyle(1,8); Bar (120,10,520,50);
settextstyle(0,0,0); setcolor (15);
OutTextXY (135,35,inf); OutTextXY (230,16,inf0);
{end of interface}

line1 (n1,n2,n3);
if k>0 then
inv (k,ly1,ly2,ly3);

disj (dx1,dy1,dx2,dy2);
konj (kx1,ky1,kx2,ky2);
endline (k,ey,f);

readkey;
closeGraph;
end else begin
writeln ('Oshibka pri inicializacii grafiki'); readln;
end; end.


осталось добавить знаки действия в квадратики, только проблема в том что она не работает с формулами A&B&C и AvBvC
не подскажите как исправить?

Хыиуду
25.05.2008, 13:05
ВСЕГО ТРИ ПЕРЕМЕННЫЕ БЕЗ СКОБОК???
Да это просто праздник какой-то!
Считываем в заданной схеме количество И и ИЛИ.
Два И - три ключа один за другим
Два ИЛИ - три ключа один над другим
И и ИЛИ - один ключ справа или слева, два других "этажеркой", потом расставить над ними буковки. Тут даже анализатор не нужен.

Hunto
25.05.2008, 20:32
я сделал немножко не так, ключ всегда один независемо, от операции и в ключе пишется знак операции, + идет растановка по приоритетам

1.инверсия 2. коньюнкция (и) 3.дизьюнкция (или)

можете пожалуйста посмотреть мою программу? может что исправить
(формулы & & и v v пока не работают)

Хыиуду
26.05.2008, 11:22
А если инверсия - в тот же прямоугольничек слева вписывать блок с инверсией. А остальное - на ваше усмотрение.

airyashov
26.05.2008, 11:54
не нашел где удалить :)

Hunto
26.05.2008, 14:14
?? что удалть ??

Hunto
26.05.2008, 20:21
OFFTOPIC:

Подскажите пожалуйста как сделать скриншот в графическом режиме ?! (режим вывода результатов graf)

MOTOCoder
26.05.2008, 20:33
OFFTOPIC:

Подскажите пожалуйста как сделать скриншот в графическом режиме ?! (режим вывода результатов graf)

Больная тема...
http://forum.developing.ru/showthread.php?t=14131

Hunto
26.05.2008, 21:16
спасибо с помощью модуля все получилось