gpt4 book ai didi

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

转载 作者:太空狗 更新时间:2023-10-29 17:04:11 34 4
gpt4 key购买 nike

好的,首先感谢您抽空阅读我的帖子!! (^o^)/在我对整个问题进行一些背景介绍之前:我正在自学“C”并找到了我正在工作的“Illustration 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;
}

本书图片链接如下: roman_2

好吧,他在那里解释了表格的逻辑。

后来他写了这篇关于开关和符号状态表的文章:

Nested switch statements are useful for implementing the logic contained in symbol-state tables. The outer switch is given a case for each state (row) of the table. The logic in each of these cases comprises an inner switch having a case for each symbol (column) of the table.

用他说的这个代码可以替换

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 章节中,这样说:

Write a function, using a symbol-state table, to read an octal number from the keyboard, converting it to a decimal integer (of type long) .Allow a preceding + or - sign. For example, the program should read -74 and get the result -60. Your state table should have four columns. These are: [0] to deal with the leading + or - , [1] to deal with any digit from 0 to 7, 2 to deal with a space character, [3] to deal with any other character (an error). The value in each cell should comprise a label (for use in an associated 'switch' statement) and the number of the next 'state', or row. The 'case' associated with valid digits should multiply the accumulating result by the number base, 8, then add the current digit. Write a test-bed program to read octal numbers from the keyboard and display their decimal equivalents on the screen.

这就是我到目前为止所拥有的:

#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;
...
}

还有空格字符...我只是不知道如何处理它!!!!

简而言之:

当表格在不同的列和行中有符号时(不像罗马数字,每个符号有一列......),每个单元格都有标签和下一个状态。

很抱歉让这太长了,对于您在语法中发现的任何错误,英语不是我的母语。

再次感谢!

最佳答案

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

        Number += Entry / 100;
Row = Entry % 100;

存储在表中的值有 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 },
};

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

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

#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) },
};

稍后 ... 我最近将相同的数据结构和算法用于 APL 样式编程语言 ( posted for review ) 的扫描器。

关于你能帮我一个符号状态表和嵌套开关吗?来自 Illustrationing C- Donald Alcock 的练习,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6811298/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com