题目:对于任意给定的一台Turing机和任意给定的字符串w ( w不含空格),编程模拟此Turing机的运行过程,要求输出从开始运行起的每一步骤的结果。

  • 题目分析

  用C++模拟一个XN*2的图灵机,输入一个正整数,将其转化为它的二进制数,并将它转化为图灵机的二进制编码(其中0->0,1->10,逗号(,)->110)然后将运算指令编译上去会输出这个数乘以2之后的拓展二进制码,定义一个state变量用来存放内态,用if-else if-else判断内态和输入,然后进行输出和内态的改变,得到拓展二进制编码后进行收缩并转化为十进制,输出最终结果。
二、算法构造

  1. 输入一个正整数,通过调用transform()函数将其转化为二进制。
  2. 将二进制转化为图灵机二进制编码。其中用到int,string及字符串数组之间的互相转化,string_replace()字符串的替换等函数。
  3. 二进制数据扩展,在扩展的二进位上实现该图灵机的运算指令,指令如下:
         00→00R,01→10R选,10→01R,11→100R,100→111R,110→01STOP。将图灵机二进制编码收缩,并将其转化为十进制输出。  

三、算法实现源代码

#include<iostream>
#include<stdlib.h>
#include <cstring>
#include<math.h>
#include <sstream>
using namespace std;
 int transfrom(int x)   //将十进制转化为二进制
 {
 	int p=1,y=0,m;
 	while(1)
 	{
 		m=x%2;
 		x/=2;
 		y+=m*p;
 		p*=10;
 		if(x<2)
 		{
 			y+=x*p;
 			break;
		 }
	 }
	 return y;
 }
	void string_replace(std::string &strBig, const std::string &strsrc, const std::string &strdst)   //字符串替换函数,通过查资料得到
{
    std::string::size_type pos=0;
    std::string::size_type srclen=strsrc.size();
    std::string::size_type dstlen=strdst.size();
    while( (pos=strBig.find(strsrc, pos)) != std::string::npos)
    {
        strBig.replace(pos, srclen, strdst);
        pos += dstlen;
    }
}
    void main()
 {
	int m,t1;
	cout<<"请输入一个正整数:"<<endl;
    cin>>m;
	t1=transfrom(m);         //调用transform()函数
	ostringstream myos;   //将int型转化为字符串型
    myos<<t1;
	string s=myos.str();
	cout<<s<<endl;
	string b=",";   //定义字符串变量b
	s.append(b);   //在字符串末尾处添加","
	cout<<"该数字对应的二进制数为:"<<s<<endl;
	string_replace(s,"1","01");   //调用string_replace函数,用“01”代替“1”
	string_replace(s,",","0110");//调用string_replace函数,用“0110”代替“,”
	string_replace(s,"0","0");   //调用string_replace函数,用“0”代替“0”,此步骤可以省略
	cout<<"对应的二进制编码为:"<<s<<endl;
	string n="00";//为便于后面的运算,在得到的二进制编码末尾处添加00
	s.append(n);
	char a[20];   //定义字符串数组
    strcpy(a,s.c_str());//将字符串型转化为成字符数组
    int state=0;//表示最初的内态
    int i;
	string str;
	for(i=0;i<20;i++)   //对字符串数组进行循环遍历,实现运算指令
	{
		if(state==0&&a[i]=='0')     //实现0 0->0 0 R指令
		{
			state=0;
			a[i]='0';
		}
		else if(state==0&&a[i]=='1')   //实现0 1->1 0 R指令
		{
			state=1;
			a[i]='0';
		}
		else if(state==1&&a[i]=='0')   //实现1 0->0 1 R指令
		{
			state=0;
			a[i]='1';
		}
		else if(state==1&&a[i]=='1')     //实现1 1->10 0 R指令
		{
			state=10;
			a[i]='0';
			
		}
		else if(state==10&&a[i]=='0')    //实现1 0->11 1 R指令
		{
			state=11;
			a[i]='1';

		}
		
		else if(state==11&&a[i]=='0')   //实现11 0->0 1 STOP指令
		{
			state=0;
			a[i]='1';
			break;
		}
	}
	   str = a;           //将字符数组转化为string类型
	   cout<<"扩展后得到的字符串为为"<<":"<<str<<endl;
       string_replace(str,"0110",",");   //调用string_replace函数,用“,”代替“0110”
	   string_replace(str,"01","1");   //调用string_replace函数,用“1”代替“01”
	   string_replace(str,"0","0");   //调用string_replace函数,用“0”代替“0”
	   cout<<"收缩后得到的字符串为为"<<str<<endl;
	   int x;
	   x= atoi(str.c_str());   //将字符型转化为int型
	   cout<<"图灵机(XN*2)收缩扩展完成后得到的二进制数为:"<<x<<endl;
	   char d[20];
       strcpy(d,str.c_str());//将字符串型转化为成字符数组
 }

 

四、调试、测试及运行结果

  1. 调试结果:

1.调试过程发现if-else语句中出现错误,经过调试发现其中的0和1是单个字符,需要加上单引号,否则会提示错误

模拟图灵机的运算

 2.调用transform()函数时,输入12,发现t1结果如下图所示。经过检查发现是函数括号里面没有写参数,所以出现了错误。

模拟图灵机的运算

 

2)测试结果:

1.测试十进制数转化为二进制数

​
#include<iostream>

using namespace std;

 int transfrom(int x)   //将十进制转化为二进制

 {

  int p=1,y=0,m;

  while(1)

  {

  m=x%2;

  x/=2;

  y+=m*p;

  p*=10;

  if(x<2)

  {

  y+=x*p;

  break;

 }

 }

 return y;

 }

void main()

 {

int m,t1;

cout<<"请输入一个正整数:"<<endl;

    cin>>m;

t1=transfrom(m);         //调用transform()函数

cout<<"二进制数为:"<<t1<<endl;

}

​

截图如下所示:

 

模拟图灵机的运算

 测试得到的二进制编码

 

#include<iostream>
#include<stdlib.h>
#include <cstring>
#include <sstream>
using namespace std;
 int transfrom(int x)   //将十进制转化为二进制
 {
 	int p=1,y=0,m;
 	while(1)
 	{
 		m=x%2;
 		x/=2;
 		y+=m*p;
 		p*=10;
 		if(x<2)
 		{
 			y+=x*p;
 			break;
		 }
	 }
	 return y;
 }
	void main()
 {
	int m,t1;
	cout<<"请输入一个正整数:"<<endl;
    cin>>m;
	t1=transfrom(m);         //调用transform()函数
	ostringstream myos;   //将int型转化为字符串型
    myos<<t1;
	string s=myos.str();
	cout<<s<<endl;
	string b=",";   //定义字符串变量b
	s.append(b);   //在字符串末尾处添加","
	cout<<"该数字对应的二进制数为:"<<s<<endl;
}

截图如下所示: 

模拟图灵机的运算

 

  1. 测试图灵机的二进制编码
    #include<iostream>
    #include<stdlib.h>
    #include <cstring>
    #include<math.h>
    #include <sstream>
    using namespace std;
     int transfrom(int x)   //将十进制转化为二进制
     {
     	int p=1,y=0,m;
     	while(1)
     	{
     		m=x%2;
     		x/=2;
     		y+=m*p;
     		p*=10;
     		if(x<2)
     		{
     			y+=x*p;
     			break;
    		 }
    	 }
    	 return y;
     }
    	void string_replace(std::string &strBig, const std::string &strsrc, const std::string &strdst)   //字符串替换函数,通过查资料得到
    {
        std::string::size_type pos=0;
        std::string::size_type srclen=strsrc.size();
        std::string::size_type dstlen=strdst.size();
        while( (pos=strBig.find(strsrc, pos)) != std::string::npos)
        {
            strBig.replace(pos, srclen, strdst);
            pos += dstlen;
        }
    }
        void main()
     {
    	int m,t1;
    	cout<<"请输入一个正整数:"<<endl;
        cin>>m;
    	t1=transfrom(m);         //调用transform()函数
    	ostringstream myos;   //将int型转化为字符串型
        myos<<t1;
    	string s=myos.str();
    	cout<<s<<endl;
    	string b=",";   //定义字符串变量b
    	s.append(b);   //在字符串末尾处添加","
    	cout<<"该数字对应的二进制数为:"<<s<<endl;
    	string_replace(s,"1","01");   //调用string_replace函数,用“01”代替“1”
    	string_replace(s,",","0110");//调用string_replace函数,用“0110”代替“,”
    	string_replace(s,"0","0");   //调用string_replace函数,用“0”代替“0”,此步骤可以省略
    	cout<<"对应的二进制编码为:"<<s<<endl;
    	string n="00";//为便于后面的运算,在得到的二进制编码末尾处添加00
    	s.append(n);
    	cout<<"图灵机对应的二进制编码为:"<<s<<endl;
    	}

    截图如下所示:

模拟图灵机的运算

 

(其他部分测试不再说明)

(3)运行结果:

模拟图灵机的运算

五、经验归纳

  1. 不足:此次图灵机的实验对我来说还是相当有难度的,虽然开始理解了图灵机的思想,但是真正上机实践的时候还是有很多问题。例如十进制和二进制之间的转化,整型,字符型和字符数组之间的转化,字符连接、替换等过程都有或多或少的问题。
  2. 收获:此次实验我也学到了许多。如:C++中ostringstream myos将int型转化为字符串,s.append(b)连接两个字符串,strcpy(a,s.c_str())将字符串型转化为成字符数组,string_replace(str,"0110",",")实现字符串的替换,atoi(str.c_str())将字符型转化为int型,strcpy(d,str.c_str())将字符串型转化为成字符数组。同样细心还是非常重要的,“==”刚开始写成了“=”出现了错误,经过检查才发现,还有0,1要加单引号等等,只要学习就会有收获,以后还是要多动手,多练习!

相关文章:

  • 2021-07-21
  • 2021-12-29
  • 2022-03-03
  • 2021-09-10
  • 2021-10-15
  • 2021-10-21
  • 2021-12-26
  • 2022-01-10
猜你喜欢
  • 2021-07-19
  • 2021-08-20
  • 2021-09-14
  • 2021-05-22
  • 2021-11-01
  • 2022-01-13
相关资源
相似解决方案