一.实验目的
1.掌握图灵机的概念和基本结构,理解图灵机的基本指令和编码方式;
2.掌握图灵机的编程方法。
二.实验内容
对于任意给定的一台Turing机和任意给定的字符串w ( w不含空格),编程模拟此Turing机的运行过程,要求输出从开始运行起的每一步骤的结果。
三.算法构造
1.将输入的十进制数转为二进制串
2.将二进制串转化为图灵机可识别的数字串(判断两0之间几个1而得出的字符串其实就是每个独立的1后面增加一个0)
3.进行Turing运算后的字符串
4.根据Turing运算的解释而得到的二进制串(同理,当初是在每个单独的1后面补充一个10,现在就是删去1个0)
5.根据二进制串得到十进制数
四.算法实现
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct node{
int data;
struct node *next;
}Node,*Link;
void Create_Link(Link * head);
void Create_node(Link* new_node);
void Insert_head(Link head,Link new_node);
void Insert_tail(Link head, Link new_node);
void output_link(Link head);
void make_empty_link(Link *head);
void release_link(Link * head);
int main()
{
Link head = NULL;
Link new_node = NULL;
Create_Link(&head);
printf("该图灵机模拟XN*2的过程,请输入一个数:");
int n;
scanf("%d",&n);
while(n!=0)
{
Create_node(&new_node);
new_node->data = n%2;
Insert_head(head,new_node);
n = n/2;
}
//补前置0
Create_node(&new_node);
new_node->data = 0;
Insert_head(head,new_node);
printf("二进制串为:\n");
output_link(head);
//将2进制串按Turing要求进行变化
Link p = head->next;
while(p!=NULL)
{
if(p->data == 1)
{
Create_node(&new_node);
new_node->data = 0;
new_node->next = p->next;
p->next = new_node;
}
p = p->next;
}
printf("对二进制串进行变换后的字符串:\n");
output_link(head);
//在最后补充标点符号','二进制以110表示
Create_node(&new_node);
new_node->data = 1;
Insert_tail(head,new_node);
Create_node(&new_node);
new_node->data = 1;
Insert_tail(head,new_node);
Create_node(&new_node);
new_node->data = 0;
Insert_tail(head,new_node);
printf("补充了结尾的逗号之后的字符串:\n");
output_link(head);
//按照Turing中XN*2的变换要求对2进制串改变
int temp = 0;
p = head->next;
while(1)
{
if(temp == 0&&p->data == 1)
{
temp = 1;
p->data = 0;
if(p->next == NULL)
{
Create_node(&new_node);
new_node->data = 0;
Insert_tail(head,new_node);
}
p = p->next;
}
else if(temp == 0&&p->data == 0)
{
if(p->next == NULL)
{
Create_node(&new_node);
new_node->data = 0;
Insert_tail(head,new_node);
}
p = p->next;
}
else if(temp == 1&&p->data == 0)
{
temp = 0;
p->data = 1;
if(p->next == NULL)
{
Create_node(&new_node);
new_node->data = 0;
Insert_tail(head,new_node);
}
p = p->next;
}
else if(temp == 1&&p->data == 1)
{
temp = 10;
p->data = 0;
if(p->next == NULL)
{
Create_node(&new_node);
new_node->data = 0;
Insert_tail(head,new_node);
}
p = p->next;
}
else if(temp == 10&&p->data == 0)
{
temp = 11;
p->data = 1;
if(p->next == NULL)
{
Create_node(&new_node);
new_node->data = 0;
Insert_tail(head,new_node);
}
p = p->next;
}
else if(temp == 11&&p->data == 0)
{
temp = 0;
p->data = 1;
if(p->next == NULL)
{
Create_node(&new_node);
new_node->data = 0;
Insert_tail(head,new_node);
}
break;
}
}
printf("进行Turing变换之后的字符串:\n");
output_link(head);
//进行变换之后的字符串反编译为二进制串
int str[100];
memset(str,0,sizeof(str));
p = head->next;
int i = 0;
while(1)
{
int count = 0;
if(p->data == 0)
{
Link q = p->next;
while(q->data!=0)
{
count++;
q = q->next;
}
if(count > 1)
{
str[i] = 2;
break;
}
else str[i++] = count;
}
p = p->next;
}
printf("进行XN*2后的二进制串为:");
for(i = 0;str[i]!=2;i++)
printf("%d",str[i]);
//输出十进制下的数字
int len = i,t = 1,sum = 0;
for(i = len -1;i >= 0;i--)
{
sum+=str[i]*t;
t*=2;
}
printf("\n最终结果为:%d",sum);
//释放链表
release_link(&head);
return 0;
}
//建立链表头节点
void Create_Link(Link * head){
(* head) = (Link)malloc(sizeof(Node));
(*head)->next = NULL;
}
//创建新节点
void Create_node(Link* new_node)
{
*new_node = (Link)malloc(sizeof(Node));
}
//头插法
void Insert_head(Link head,Link new_node)
{
Link p = NULL;
p = head;
new_node->next = p->next;
p->next = new_node;
}
/*插入节点尾插法*/
void Insert_tail(Link head, Link new_node)
{
Link p = NULL;
p = head;
while (p->next != NULL)
{
p = p->next;
}
p->next = new_node;
new_node->next = NULL;
}
//遍历输出链表数据
void output_link(Link head)
{
Link p = NULL;
if (head == NULL)
{
printf("link is empty!\n");
return;
}
p = head->next;
while (p != NULL)
{
printf("%d", p->data);
p = p->next;
}
printf("\n");
}
//置空链
void make_empty_link(Link *head)
{
Link p = NULL;
p = (*head)->next;
while ((*head)->next != NULL)
{
(*head)->next = (*head)->next->next;
free(p);
p = (*head)->next;
}
}
//释放链表
void release_link(Link * head)
{
make_empty_link(head);
free(*head);
*head = NULL;
}
五.运行结果
六.经验归纳
根据图灵机指令中,两个0之间有多少个1,观察发现,实际结果就是在非连续的单独1后面增加或减少一个0,所以这就确定了如何的得到Turing运算所要求的数字串,而且指令操作要对一连续数进行依次操作,而且还有反向,删除插入以及遍历操作,所以在选用数据结构的时候就考虑到了链表,正好满足本题的要求,故这道题目就变成一个链表的操作题目。
先把链表的一系列操作写好,复习了一下知识点,然后分步骤,构造链表,把十进制数转为二进制串存储,然后依次按照操作进行Turing运算即可。