你能帮我一个符号状态表和嵌套开关吗?来自插图C-Donald Alcock的练习

Inc*_*ide 8 c nested nested-loops switch-statement

好的,先谢谢你花时间阅读我的帖子!(^ o ^)/在我把整个问题放在一个上下文之前:我正在自己学习'C'并找到了我正在工作的"Illustrating C"这本书.唐纳德·阿尔科克(Donald Alcock)在他的书中使用符号状态表来表示程序中的逻辑,该程序要求用阿拉伯数字改变罗马数字.

这是代码:

#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;
}
Run Code Online (Sandbox Code Playgroud)

这里有一本书的图片链接: 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);
        }
Run Code Online (Sandbox Code Playgroud)

对于这个

while ( ((Ch = getchar()) != '\n') && Entry )
     {
       switch (Row)
        {
          case 0:
                switch (Column)
                {
                   case 'M':
                   case 'D':
                   ...
                }
          ...
         }
     }
Run Code Online (Sandbox Code Playgroud)

我猜你现在明白了.

好吧,最后当一切都崩溃了.(TT)

在练习4.2章中,这样说:

使用符号状态表编写一个函数,从键盘读取八进制数,将其转换为十进制整数(long类型).允许前面的+或 - 符号.例如,程序应该读取-74并获得结果-60.您的状态表应该有四列.它们是:[0]处理前导+或 - ,[1]处理从0到7的任何数字,2处理空格字符,[3]处理任何其他字符(错误).每个单元格中的值应包含一个标签(用于关联的"switch"语句)和下一个"state"或行的编号.与有效数字相关联的"大小写"应将累加结果乘以数字基数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;
}
Run Code Online (Sandbox Code Playgroud)

一些小问题可以正常工作,但将八进制转换为十进制.

问题是我无法理解如何将表与开关一起使用并删除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;
    ...
   }
Run Code Online (Sandbox Code Playgroud)

太空人物......我只是不知道该怎么办!!!!

简而言之:

如何使用带有开关的表来避免if和for当表中的符号位于不同的列和行中时(与罗马数字不同,每个符号都有一列......)每个单元格都有一个标签和下一个状态.

很抱歉让这个太久了,如果你在语法中发现任何错误,英语就不是我的母语.

再次感谢!

lus*_*oog 2

在我看来,理解表格使用的关键在于内部循环中的这两行。

        Number += Entry / 100;
        Row = Entry % 100;
Run Code Online (Sandbox Code Playgroud)

表中存储的值有 2 个采用压缩十进制表示形式的“字段”。有一个小循环来搜索 char 数组中的输入字符(strchr 是更常见的方法)。然后使用 / 和 % 分解表中的值,得到指示下一个状态的“十”位和“个”位(大循环下一次迭代的行值),以及“百”位和较高位除以 100 后,给出该字符对输出值的贡献量。

好吧,首先您需要执行示例中的小循环之类的操作。这就是字符分类功能。它允许您从代码中取出所有这些字符常量,并将它们放入它们所属的数据结构中。

也就是说,我要尝试自己编写这样一个程序。不确定您是在寻找完整的解决方案还是只是一点帮助。当我有更多的时候我会回来查看。

编辑:我认为问题陈述有点误导。每个有效字符都需要一列。看看这个版本的表格。

/* the state transition table: +-, 0-7, ' ', ERR */
              /* 01234567890 */
char symbol[] = "+-01234567 ";
int table[][] = {
        /*  0,   1,   2,   3,   4,   5,   6,   7,   8,   9,10,11 */
/* 0*/  {   2,   1, 002, 102, 202, 302, 402, 502, 602, 702, 0, 0 },
/* 1*/  {   0,   0,-001,-101,-201,-301,-401,-501,-601,-701, 0, 0 },
/* 2*/  {   0,   0, 002, 102, 202, 302, 402, 502, 602, 702, 0, 0 },
};
Run Code Online (Sandbox Code Playgroud)

我强烈建议您在桌子周围放置这样的评论,它们可以帮助您找到解决办法。顺便说一句,我也不知道这个空间应该做什么。

编辑:使用宏有助于使字段更容易查看。

#define T(x,y) ((x*100)+y)
/* the state transition table: +-, 0-7, ' ', ERR */
              /* 01234567890 */
char symbol[] = "+-01234567 ";
int table[][] = {
{ T(0,2), T(0,1), T(0,02), T(1,02), T(2,02), T(3,02), T(4,02), T(5,02), T(6,02), T(7,02), T(0,0), 
    T(0,0) },
{ T(0,0), T(0,0), T(0,01),T(-1,01),T(-2,01),T(-3,01),T(-4,01),T(-5,01),T(-6,01),T(-7,01), T(0,0), 
    T(0,0) },
{ T(0,0), T(0,0), T(0,02), T(1,02), T(2,02), T(3,02), T(4,02), T(5,02), T(6,02), T(7,02), T(0,0), 
    T(0,0) },
};
Run Code Online (Sandbox Code Playgroud)

后来......我最近在 APL 风格编程语言的扫描仪中使用了相同的数据结构和算法(发布以供审查)。