Возможно, не помешал бы достаточно простой пример из области автоматного программирования,
демонстрирующий использование силуэта как альтернативной формы графа переходов автомата,
например (хотя надо было бы это оформить как-нибудь получше):
Код:
// пример из статьи "ПСИХОЛОГИЯ АВТОМАТНОГО ПРОГРАММИРОВАНИЯ"
// Кузнецов Б.П., Санкт-Петербург, НПО “Аврора”
Задача ставится следующим образом. Даны два массива. Каждый из них
содержит последовательность неповторяющихся чисел, завершающуюся нулем.
Второй массив содержит ту же, что и в первом, последовательность, но
включает вставки из чисел, отсутствующих в первом массиве. Например:
М1 = 2 4 5 7 8 9 12 13 0
М2 = 2 4 5 21 23 24 7 8 9 12 13 0
--------
(подчеркнута вставка).
Программа должна сравнить два массива и напечатать вставки, встречающиеся
во втором массиве.
Граф переходов процедуры-автомата collation приведен на рис.1.
// collation.cpp Сличение числовых массивов, завершающихся нулем.
// (Пример автоматного программирования)
// Copyright © Кузнецов Б.П. Санкт-Петербург 06.08.2000
// boris@actor.ru
#include <stdio.h>
#include <conio.h>
void insert(int s2, int c2, int *m2); // вывод на экран вставки
void collation(int *m1, int *m2) // подпрограмма сличения ==========
// m1, m2 - сличаемые масивы
{
static char state = 'A'; // символ состояния подпрограммы сличения
int cycle = 1; // 0 - признак окончания цикла
int s1, s2; // текущие номера элементов двух массивов
int c1, c2; // запоминаемые номера элементов двух массивов
while(cycle) // локальный цикл подпрограммы
switch(state) // распознавание текущего состояния графа переходов
{
case 'A': // исходное состояние
s1 = s2 = -1; // подготовка к счету элементов массивов
state = 'B'; // переход к состоянию В
break;
case 'B': // состояние ожидания неравенства элементов массивов
// (вставки)
s1++; s2 ++; // переход к очередной паре элементов массивов
if(!m2[s2] && m1[s1]) // конец второго массива
{
printf("\n Массив М1 надо сличать на удаление\n");
state = 'A'; // перевод подпрограммы в исходное состояние
cycle = 0; // обеспечение выхода из цикла
}
else if(m1[s1] == m2[s2] && !m1[s1]) // конец обоих массивов
{
state = 'A'; // перевод подпрограммы в исходное состояние
cycle = 0; // обеспечение выхода из цикла
}
else if(m1[s1] != m2[s2]) // достигли очередной вставки
{
c1 = s1;
c2 = s2; // запоминаем текущие номера элементов массивов
state = 'C'; // переход к состоянию С
}
else ; // элементы массивов равны и не нулевые
// продолжаем цикл в состоянии В
break;
case 'C': // состояние ожидания равенства элементов после вставки
c2++; // переход к очередной строке второго массива
if(!m2[c2]) // конец второго массива - вставка до его конца
{
insert(s2, c2 - 1, m2); // печать вставки
state = 'A'; // перевод подпрограммы в исходное состояние
cycle = 0; // обеспечение выхода из цикла
}
else if(m1[c1] == m2[c2]) // конец вставки
{
insert(s2, c2 - 1, m2); // печать вставки
s1 = c1;
s2 = c2; // подготовка к продолжению сравнения массивов
state = 'B'; // возврат к состоянию В
}
else ; // пока еще "продолжается" вставка
// продолжаем цикл в состоянии С
break;
}
} // collation 06.08.2000 =========================================
void insert(int s2, int c2, int *m2) // вывод на экран вставки ====
{
int i;
printf("\ninsert: ");
for(i = s2; i <= c2; i++)
printf("%d ",m2[i]);
} // insert 06.08.2000 =============================================
main() //=========================================================
{
static int M1[] = { 1, 2, 3, 4, 5, 6, 7, 0 };
static int M2[] = { 28, 1, 2, 3, 4, 5, 6, 7, 0 };
static int M3[] = { 38, 39, 30, 1, 2, 3, 4, 5, 6, 7, 0 };
static int M4[] = { 1, 2, 3, 4, 5, 6, 7, 48, 0 };
static int M5[] = { 1, 2, 3, 4, 5, 6, 7, 58, 59, 50, 0 };
static int M6[] = { 1, 2, 3, 68, 4, 5, 6, 7, 0 };
static int M7[] = { 1, 2, 3, 78, 79, 70, 4, 5, 6, 7, 0 };
static int M8[] =
{ 1, 2, 80, 81, 82, 3, 4, 5, 83, 84, 6, 7, 85, 86, 87,0 };
printf("\n\n collation M1 & M2");
collation(M1, M2);
printf("\n\n collation M1 & M3");
collation(M1, M3);
printf("\n\n collation M1 & M4");
collation(M1, M4);
printf("\n\n collation M1 & M5");
collation(M1, M5);
printf("\n\n collation M1 & M6");
collation(M1, M6);
printf("\n\n collation M1 & M7");
collation(M1, M7);
printf("\n\n collation M1 & M8");
collation(M1, M8);
getch();
} // main 05.08.2000 =============================================
collation M1 & M2
insert: 28
collation M1 & M3
insert: 38 39 30
collation M1 & M4
insert: 48
collation M1 & M5
insert: 58 59 50
collation M1 & M6
insert: 68
collation M1 & M7
insert: 78 79 70
collation M1 & M8
insert: 80 81 82
insert: 83 84
insert: 85 86 87
Вложение:
apris_1.JPG [ 39.72 КБ | Просмотров: 11705 ]
Силуэт (таблица-силуэт, если несколько строк логики) как альтернативная
форма графа переходов для процедуры-автомата collation приведен на рис.2.
Вложение:
apris_2.JPG [ 74.98 КБ | Просмотров: 11705 ]