模拟图灵机运算

一.实验目的
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运算即可。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值