ОК, сначала спасибо, что нашли время прочитать мой пост !! (^ О ^) /
И прежде чем я поставлю всю проблему немного контекста:
Я изучаю «C» и нашел книгу «Иллюстрируя C», над которой я работаю. В своей книге Дональд Алкок использовал таблицу состояний символов для логики в программе, которая просит изменить римскую цифру на арабском.
Это код:
#include <stdio.h>
char Symbol [] = { 'M', 'D', 'C', 'L', 'X', 'V', 'I' };
long Table [16] [8] =
{
{ 100000, 50001, 10003, 5007, 1006, 512, 111, 0 },
{ 0, 0, 10002, 5007, 1006, 512, 111, 0 },
{ 0, 0, 10004, 5007, 1006, 512, 111, 0 },
{ 80005, 30005, 10004, 5007, 1006, 512, 111, 0 },
{ 0, 0, 10005, 5007, 1006, 512, 111, 0 },
{ 0, 0, 0, 5007, 1006, 512, 111, 0 },
{ 0, 0, 8010, 3010, 1009, 512, 111, 0 },
{ 0, 0, 0, 0, 1008, 512, 111, 0 },
{ 0, 0, 0, 0, 1009, 512, 111, 0 },
{ 0, 0, 0, 0, 1010, 512, 111, 0 },
{ 0, 0, 0, 0, 0, 512, 111, 0 },
{ 0, 0, 0, 0, 815, 315, 114, 0 },
{ 0, 0, 0, 0, 0, 0, 113, 0 },
{ 0, 0, 0, 0, 0, 0, 114, 0 },
{ 0, 0, 0, 0, 0, 0, 115, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0 }
};
int main ( void )
{
long Entry = 1, Number = 0;
int Column, Row = 0;
char Ch;
printf ("\nEnter a number\n");
while ( ((Ch = getchar()) != '\n') && Entry )
{
for ( Column=0; Column<7 && (Ch != Symbol[Column]); ++Column );
Entry = Table [Row][Column];
Number += Entry / 100;
Row = Entry % 100;
printf(" %li ", Number);
}
//printf("%c,%c ", Ch,'\n' && Entry);
if (Entry)
printf ("= %ld in Arabics", Number);
else
printf ("\nError");
printf("\nEnd of run");
return 0;
}
Вот ссылка на фото книги:
roman_2
Ну, там он объясняет логику таблицы.
Позже он написал это о переключателях и таблицах состояний символов:
Вложенные операторы switch полезны для реализации логики
содержится в таблицах состояний символов. Внешний выключатель предназначен для
каждое состояние (строка) таблицы. Логика в каждом из этих случаев
содержит внутренний переключатель, имеющий регистр для каждого символа (столбца)
стол.
Используя то, что он говорит, этот код можно заменить
while ( ((Ch = getchar()) != '\n') && Entry )
{
for ( Column=0; Column<7 && (Ch != Symbol[Column]); ++Column );
Entry = Table [Row][Column];
Number += Entry / 100;
Row = Entry % 100;
printf(" %li ", Number);
}
для этого
while ( ((Ch = getchar()) != '\n') && Entry )
{
switch (Row)
{
case 0:
switch (Column)
{
case 'M':
case 'D':
...
}
...
}
}
Я думаю, вы поняли идею сейчас.
Ну, наконец, когда все развалилось. (T.T)
В главе 4.2 упражнения произнесите следующее:
Напишите функцию, используя таблицу состояний символов, для чтения восьмеричного числа.
с клавиатуры, преобразовав его в десятичное целое число (типа long)
. Разрешить предшествующий знак + или -. Например, программа должна прочитать
-74 и получите результат -60. Ваша таблица состояний должна иметь четыре столбца.
Это: [0], чтобы иметь дело с ведущими + или -, [1], чтобы иметь дело с любым
цифры от 0 до 7, 2 для обозначения пробела, [3] для обозначения
с любым другим символом (ошибка). Значение в каждой ячейке должно
содержать метку (для использования в соответствующем операторе switch) и
номер следующего «состояния» или строки. «Случай», связанный с
действительные цифры должны умножить накопленный результат на число
base, 8, затем добавьте текущую цифру. Напишите программу тестового стенда для чтения
восьмеричные цифры с клавиатуры и отображение их десятичных эквивалентов
на экране.
и это то, что я имею до этого:
#include <stdio.h>
char Simbol [] = {'0', '1', '2', '3', '4', '5', '6', '7'};
char Sign [] = {'+', '-'};
long Table [8] [4] =
{
{ 143, 100, 132, 0},
{ 145, 101, 0, 0},
{ 0, 102, 0, 0},
{ 0, 103, 0, 0},
{ 0, 104, 0, 0},
{ 0, 105, 0, 0},
{ 0, 106, 0, 0},
{ 0, 107, 0, 0}
};
int main ( void )
{
long Entry = 1, Number = 0, Simbo;
int Column=0, Row;
int base = 8;
char Ch;
printf ("\nEnter a number in base 8 (Octal)\n");
while ( ((Ch = getchar()) != '\n') && Entry )
{
if( (Ch == '+') || ( Ch == '-') )
{
for ( Row=0; Row<2 && (Ch != Sign[Row]); ++Row );
}
else
{
for ( Row=0; Row<8 && (Ch != Simbol[Row]); ++Row );
Column = 1;
}
Entry = Table [Row][Column];
Simbo = Entry % 100;
printf("Number %li Simbo %li Column %i \n", Number, Simbo, Column);
switch (Row)
{
case 0:
switch (Simbo)
{
case 43:{
printf("In and is a +\n");
Entry = Table [Row][Column];
Column = Entry / 100;
Number= (+1)*Number;
break;}
case 0: {
Number = ((Number*base) +Simbo);
Entry = Table [Row][Column];
Column = Entry / 100;
break;
}
case 2: break;
case 3: break;
default: printf("case 0\n");
}
break;
case 1:
switch (Simbo)
{
case 45:{
printf("In and is a -\n");
Entry = Table [Row][Column];
Column = Entry / 100;
Number= (-1)*Number;
break;
}
case 1: {
Number = ((Number*base) +Simbo);
Entry = Table [Row][Column];
Column = Entry / 100;
break;
}
case 2: break;
case 3: break;
default: printf("case 1\n");
}
break;
case 2:
switch (Simbo)
{
case 0: break;
case 2:{
Number = ((Number*base) +Simbo);
Entry = Table [Row][Column];
Column = Entry / 100;
break;
}
default: printf("case 2\n");
}
break;
case 3:
switch (Simbo)
{
case 0: break;
case 3:{
Number = ((Number*base) +Simbo);
Entry = Table [Row][Column];
Column = Entry / 100;
break;
}
default: printf("case 3\n");
}
break;
case 4:
switch (Simbo)
{
case 0: break;
case 4:{
Number = ((Number*base) +Simbo);
Entry = Table [Row][Column];
Column = Entry / 100;
break;
}
default: printf("case 4\n");
}
break;
case 5:
switch (Simbo)
{
case 0: break;
case 5:{
Number = ((Number*base) +Simbo);
Entry = Table [Row][Column];
Column = Entry / 100;
break;
}
default: printf("case 5\n");
}
break;
case 6:
switch (Simbo)
{
case 0: break;
case 6:{
Number = ((Number*base) +Simbo);
Entry = Table [Row][Column];
Column = Entry / 100;
break;
}
default: printf("case 6\n");
}
break;
case 7:
switch (Simbo)
{
case 0: break;
case 7:{
Number = ((Number*base) + Simbo);
Entry = Table [Row][Column];
Column = Entry / 100;
break;
}
default: printf("case 7\n");
}
break;
default: printf("\ndefault\n");
}
printf("\n---Number %li\n\n", Number);
}
if (Entry)
printf ("\n\n= %ld Decimal", Number);
else
printf ("\nError");
return 0;
}
Хорошо работает с небольшими проблемами, но преобразует восьмеричное в десятичное.
Проблема в том, что я не могу понять, как использовать таблицу с переключателем и удалить здесь if и for:
while ( ((Ch = getchar()) != '\n') && Entry )
{
if( (Ch == '+') || ( Ch == '-') )
{
for ( Row=0; Row<2 && (Ch != Sign[Row]); ++Row );
}
else
{
for ( Row=0; Row<8 && (Ch != Simbol[Row]); ++Row );
Column = 1;
}
Entry = Table [Row][Column];
Simbo = Entry % 100;
...
}
И символ пробела ... Я просто не знаю, что с этим делать !!!!.
В двух словах:
Как использовать таблицу с переключателями, чтобы избежать if и for, когда таблица содержит символы в разных столбцах и строках (в отличие от римских чисел, каждый символ с столбцом ...), где каждая ячейка имеет метку и следующее состояние.
Извините, что сделал это слишком долго, и за любую ошибку, найденную в грамматике, английский не мой родной язык.
Еще раз спасибо!