c语言题,图灵机模拟程序,求!

描述:
写一个图灵机模拟程序,该程序输入专用图灵机指令集及用户输入,模拟执行
图灵机程序,产生输出。
输入说明:
输入第一行为一个整数 n,表示专用图灵机指令集有 n 条指令。
接下来是 n+1 行
1)前 n 行为 n 条指令,每条指令由 5 个部分构成,每个部分用空格分隔,如下
所示:
当前状态 输入符号 输出符号 纸带移动方向 新状态
例如:ADD 0 1 L RETURN
其中,
 “当前状态”和“新状态”为一个长度不超过 20 个字符的字符串
 “输入符号”和“输出符号”各是一个字符,输入和输出符号有‘’,
‘0’,‘1’三种,其中‘
’表示分界符,两个‘’之内的部分是有效
输入/输出。纸带其余部分填充‘#’表示空白
 “纸带移动方向”也是一个字符,有三种可能:‘L’表示左移,‘R’表
示右移,‘N’表示不动
2)最后一行为一个长度不超过 100 的字符串,表示图灵机输入
该字符串由若干‘#’,两个‘
’和若干‘0’,‘1’字符构成,‘#’表示纸
带上的空白,‘’表示输入分界符,‘0’和‘1’表示有效输入,如下所示:
#####101####
注意:有两种状态是固定字符串:“INIT”表示初始状态,“STOP”表示停机
状态,图灵机一开始处于初始状态(INIT),纸带的读写头位于输入字符串的
得个'
'位置(右分界符)。
输出说明:
根据输入数据执行图灵机程序,在一行上打印出执行后的输出,只输出有效部
分,不输出‘#’,‘*’。
输入样例:
12
INIT * * N START
START * * R ADD
ADD 0 1 L RETURN
ADD 1 0 R CARRY
ADD * * L STOP
CARRY 0 1 L RETURN
CARRY 1 0 R CARRY
CARRY * 1 R OVERFLOW
OVERFLOW # * L RETURN
RETURN 1 1 L RETURN
RETURN 0 0 L RETURN
RETURN * * N STOP
##########101##########
输出样例:
110
样例说明:
该样例为执行二进制加 1 操作 y=x+1 的专用图灵机程序,输入为 101,输出为
110。

下面是一个 C++ 程序的示例,实现了上述图灵机的模拟功能:

#include <iostream>
#include <string>
#include <map>
#include <vector>

using namespace std;

// 定义图灵机指令结构体
struct Instruction
{
string currentState; // 当前状态
char inputSymbol; // 输入符号
char outputSymbol; // 输出符号
char tapeMove; // 纸带移动方向
string newState; // 新状态
};
// 图灵机类
class TuringMachine
{
private:
// 用 map 存储指令集
map<pair<string, char>, Instruction> instructions;
// 当前状态
string currentState;
// 纸带
string tape;
// 当前位置
int position;

public:
TuringMachine(vector<Instruction> instrs);
void run();
};

// 构造函数,将指指令集转存到 map 中
TuringMachine::TuringMachine(vector<Instruction> instrs)
{
for (auto i : instrs)
{
instructions[make_pair(i.currentState, i.inputSymbol)] = i;
}
currentState = "INIT";
tape = "#####";
position = 2;
}

// 运行图灵机
void TuringMachine::run()
{
// 循环执行,直到进入终止状态
while (currentState != "ACCEPT" && currentState != "REJECT")
{
// 获取当前状态和当前位置的输入符号
char inputSymbol = tape[position];
// 根据当前状态和输入符号获取对应的指令
Instruction instr = instructions[make_pair(currentState, inputSymbol)];
// 修改当前状态
currentState = instr.newState;
// 修改当前位置的输出符号
tape[position] = instr.outputSymbol;
// 移动纸带
if (instr.tapeMove == 'L')
{
position--;
}
else if (instr.tapeMove == 'R')
{
position++;
}
}
// 输出最终状态
cout << currentState << endl;
// 输出纸带内容
cout << tape << endl;
}

int main()
{
// 输入指令数量
int n;
cin >> n;
// 输入指令集
vector<Instruction> instrs;
for (int i = 0; i < n; i++)
{
    Instruction instr;
    cin >> instr.currentState >> instr.inputSymbol >> instr.outputSymbol >> instr.tapeMove >> instr.newState;
    instrs.push_back(instr);
}

// 输入图灵机输入
string input;
cin >> input;

// 初始化图灵机
TuringMachine tm(instrs);
// 设置纸带内容
tm.tape = "#####" + input + "#####";
// 运行图灵机
tm.run();

return 0;
}

为了实现图灵机的模拟,你需要定义一些数据结构来表示图灵机指令集,并实现按照指令执行的函数。

具体来说,你需要定义一个结构体表示一条指令,其中包含五个字段:当前状态,输入符号,输出符号,纸带移动方向,新状态。你可以使用字符数组来存储字符串字段,使用字符变量来存储字符字段。

然后,你需要定义一个数组,其中包含所有指令。接下来,你需要实现一个函数,该函数接受图灵机的当前状态,当前纸带上的字符以及图灵机指令集作为参数,并执行相应的指令。

在这个函数中,你可以遍历指令集,找到与当前状态和输入符号相匹配的指令,然后执行指令。执行指令的过程包括更新当前状态,写入输出符号,移动纸带指针以及输出当前纸带的字符串。

下面是一个示例代码,它实现了以上功能:

#include <stdio.h>
#include <string.h>

#define MAX_INSTRUCTIONS 100
#define MAX_STATE_NAME_LENGTH 20
#define MAX_TAPE_LENGTH 100

// 定义图灵机指令结构体
typedef struct {
  char current_state[MAX_STATE_NAME_LENGTH + 1];
  char input_symbol;
  char output_symbol;
  char move_direction;
  char new_state[MAX_STATE_NAME_LENGTH + 1];
} instruction;

// 定义图灵机结构体
typedef struct {
  instruction instructions[MAX_INSTRUCTIONS];
  int num_instructions;
  char tape[MAX_TAPE_LENGTH + 1];
  int tape_index;
  char current_state[MAX_STATE_NAME_LENGTH + 1];
} turing_machine;

// 执行图灵机指令
void execute_instruction(turing_machine *tm) {
  // 遍历指令集,找到与当前状态和输入符号相匹配的指令
  for (int i = 0; i < tm->num_instructions; i++) {
    instruction inst = tm->instructions[i];
    if (strcmp(inst.current_state, tm->current_state) == 0 &&
        inst.input_symbol == tm->tape[tm->tape_index]) {
      // 执行指令
      strcpy(tm->current_state, inst.new_state);
      tm->tape[tm->tape_index] = inst.output_symbol;
      if (inst.move_direction == 'L') {
        tm->tape_index--;
      } else if (inst.move_direction == 'R') {
        tm->tape_index++;
      }
      break;
    }
  }
}

int main() {
  // 读入图灵机指令集
  turing_machine tm;
  scanf("%d", &tm.num_instructions);
  for (int i = 0; i < tm.num_instructions; i++) {
    scanf("%s %c %c %c %s", tm.instructions[i].current_state,
          &tm.instructions[i].input_symbol, &tm.instructions[i].output_symbol,
          &tm.instructions[i].move_direction, tm.instructions[i].new_state);
  }
  // 读入图灵机输入
  scanf("%s", tm.tape);
  // 初始化图灵机状态
  strcpy(tm.current_state, "INIT");
  tm.tape_index = 0;
// 执行图灵机程序
  while (strcmp(tm.current_state, "HALT") != 0) {
    execute_instruction(&tm);
  }
  // 输出图灵机输出
  printf("%s\n", tm.tape);
  return 0;
}

上述代码实现了图灵机的模拟。在 main 函数中,首先读入图灵机指令集和图灵机输入,然后初始化图灵机状态。接下来,进入循环执行图灵机程序。在循环内部,调用 execute_instruction 函数执行指令。循环结束后,输出图灵机输出。

仅供参考的实例【c++模拟图灵机】,链接:https://www.codenong.com/cs106479935/

以下是用 C 语言描述图灵机模拟程序的示例代码:

Copy code
#include <stdio.h>
#include <string.h>

#define MAX_INSTRUCTIONS 100  // 最大指令数
#define MAX_INPUT_LENGTH 100  // 最大输入长度

// 图灵机指令
typedef struct {
  char current_state[20];  // 当前状态
  char input_symbol;  // 输入符号
  char output_symbol;  // 输出符号
  char move_direction;  // 纸带移动方向
  char new_state[20];  // 新状态
} Instruction;

int main() {
  int n;
  scanf("%d", &n);  // 读入指令数

  Instruction instructions[MAX_INSTRUCTIONS];  // 图灵机指令集

  // 读入指令
  for (int i = 0; i < n; i++) {
    scanf("%s %c %c %c %s", instructions[i].current_state, &instructions[i].input_symbol, &instructions[i].output_symbol, &instructions[i].move_direction, instructions[i].new_state);
  }

  char input[MAX_INPUT_LENGTH];  // 图灵机输入
  scanf("%s", input);

  int tape_head = 0;  // 纸带头位置
  char current_state[20] = "INIT";  // 当前状态

  // 执行图灵机程序
  while (strcmp(current_state, "STOP") != 0) {
    // 在指令集中查找匹配的指令
    Instruction *inst = NULL;
    for (int i = 0; i < n; i++) {
      if (strcmp(instructions[i].current_state, current_state) == 0 && instructions[i].input_symbol == input[tape_head]) {
        inst = &instructions[i];
        break;
      }
    }

    // 如果找到了匹配的指令,则执行指令
    if (inst != NULL) {
      input[tape_head] = inst->output_symbol;  // 更新纸带上的符号
      strcpy(current_state, inst->new_state);  // 更新当前

  // 根据指令移动纸带头
  if (inst->move_direction == 'L') {
    tape_head--;
  } else if (inst->move_direction == 'R') {
    tape_head++;
  }
} else {
  // 如果没有找到匹配的指令,则停机
  strcpy(current_state, "STOP");
}
}

printf("%s\n", input); // 输出纸带内容

return 0;
}

首先我们需要一个字典,来存储每个状态的所有指令。然后根据给定的输入符号和输出符号来执行指令。如果当前状态是“INIT”,那么我们将从第一个字符开始执行指令。如果当前状态是“STOP”,则停止执行指令。如果当前状态不是“INIT”也不是“STOP”,则根据纸带移动方向来移动纸带,并将新状态设为当前状态。最后,输出结果。


#include <stdio.h>
#include <math.h>
 
int size1 = 0;    // size1存储二进制数的长度
int size2 = 0;    // size2存储扩展二进制的长度
int size3 = 0;    // size3存储按指令操作后的二进制长度
int size4 = 0;    // size4存储收缩二进制的长度
 
// 通过transform()函数实现十进制转二进制 
int* transform(int x)
{
    int rem;    // 存储x2取余后的余数
    int i = 0, j = 0;
    int r;
    int a[100];    // 数组a[]倒序存储十进制转换后的二进制
    static int b[100];    // 数组b[]正序存储十进制转换后的二进制
 
    while(x!=0)    // 十进制转二进制
    {
        rem = x%2;
        a[i] = rem;
        i++;
        x/=2;
    }
 
    for(r=i-1; r>=0; r--)    // 通过for循环将二进制数正序存入数组b[]中
    {
        b[j] = a[r];
        j++;
    }
 
    size1 = j;
 
    return b;
    
}
 
// 通过extend()函数实现二进制的扩展 
int* extend(int p[])
{
    int i = 0, j, k;
    static int c[100];    // 数组c[]存储扩展二进制
 
    c[i] = 0;    // 数组首位存入0
    i++;
 
    for(j=0; j<size1; j++)
    {
        k = p[j];
 
        if(k==0)    // 若从二进制数组中扫描到0,则将一个0存入扩展二进制数组c[]中
        {
            c[i] = 0;
            i++;
        }
        else if(k==1)    // 若从二进制数组中扫描到1,则将一个1、一个0依次存入扩展二进制数组c[]中
        {
            c[i] = 1;   
            i++;
            c[i] = 0;
            i++;
        }
    }
 
    c[i] = 1;
    i++;
    c[i] = 1;
    i++;
    c[i] = 0;
 
    size2 = i+1;
 
    return c;
}
 
// 通过realize()函数实现对扩展二进制的按指令操作
int* realize(int q[])
{
    int i, j = 0, k = 0;
    int inner = 0;    // inner为内态
    
    for(i=0; i<size2+2; i++)
    {
        k = q[i];
        
        if(k==0 && inner==0)    // 输入为0,内态为0
        {
            q[i] = 0;
            inner = 0;
        }
        else if(k==0 && inner==1)    // 输入为0,内态为1
        {
            q[i] = 1;
            inner = 0;
        }
        else if(k==0 && inner==10)    // 输入为0,内态为10
        {
            q[i] = 1;
            inner = 11;            
        }
        else if(k==0 && inner==11)    // 输入为0,内态为11
        {
            q[i] = 1;
            inner = 0;    
        }
        else if(k==1 && inner==0)    // 输入为1,内态为0
        {
            q[i] = 0;
            inner = 1;
        }
        else if(k==1 && inner==1)    // 输入为1,内态为1
        {
            q[i] = 0;
            inner = 10;
        }
        else if(k==1 && inner==10)    // 输入为1,内态为10
        {
            q[i] = 0;
            inner = 0;
        }
    }
 
    size3 = i;
    printf("%d", size3);
 
    return q;
}
 
// 通过shrink()函数实现对操作结果的收缩
int* shrink(int r[])
{
    int i, j = 0;
    static int d[100];
 
    for(i=1; i<size3-3; i++)
    {
        if(r[i]==0 && r[i+1]==0 )
        {
            d[j] = 0;
            j++;
            continue;
        }
        if(r[i]==0 && r[i+1]==1 && r[i+2]==0)
        {
            d[j] = 1;
            j++;
            continue;
        }
    }
 
    size4 = j;
 
    return d;
}
 
// 通过reverse()函数实现二进制转十进制
int reverse(int s[])
{
    int sum = 0;
    int i;
 
    for(i=0; i<size4; i++)
    {
        sum += s[i] * (int)pow(2,(size4-1-i));
    }
 
    return sum;
}
 
void main()
{
    int x;    // 存放用户键入的整数
    int i = 0;
    printf("请输入一个十进制整数:\n");
    scanf("%d", &x);
    
    int*p;
    p = transform(x);
    printf("十进制数转换成二进制数为:\n");
    for(i=0; i<size1; i++)
        printf("%d", p[i]);
    printf("\n");
 
 
    int*q;
    q = extend(p);
    printf("扩展二进制数为:\n");
    for(i=0; i<size2; i++)
        printf("%d", q[i]);
    printf("\n");
 
    int*r;
    r = realize(q);
    printf("指令执行结束生成的二进制数:\n");
    for(i=0; i<size3; i++)
        printf("%d", r[i]);
    printf("\n");
 
    int*s;
    s = shrink(r);
    printf("图灵机计算结果的二进制数:\n");
    for(i=0; i<size4; i++)
        printf("%d", s[i]);
    printf("\n");
 
    int y;
    y = reverse(s);
    printf("图灵机计算结果的十进制数:\n");
    printf("%d", y);
    printf("\n");
}