C语言实现图灵机(XN*2)运算过程。
程序设计上机作业
题目:C语言实现图灵机(XN*2)运算过程。
要求:输入十进制数,转换成图灵机进行运算的二进制形式,然后根据语句命令进行运算,输出每一步的运算结果,最终输出计算结果(十进制)。
分析:
(1)首先将十进制数转换成二进制数保存在数组b[]中
(2)然后将二进制数转换成图灵机进行运算的二进制数,保存在数组c[]中
(3)通过命令进行运算后输出得到的图灵机二进制
(4)然后将图灵机二进制有转换成二进制,最后将二进制转换成十进制输出。
流程图:
调试过程:
十进制转化为二进制:
运算结果(图灵机二进制):
结果(十进制):
运行结果:
测试代码:
测试运行结果:
源代码:
#include <stdio.h>
#include <math.h>
//将十进制转化为二进制,保存在数组b[]中,不过顺序是反着的
void transfor1(int x, int b[],int size)
{
int i = 0;
while (x)
{
b[i] = x % 2;
x /= 2;
++i;
}
size = i;
}
//将二进制转化为图灵机二进制
void transfor2(int b[],int c[],int size)
{
int m = 0;
c[m] = 0;
int i = 10;
while ( i >= 0) //倒序将二进制数组b[]的数字进行判断
{
if (b[i]==1)
{
if (i == size-1) //最前面的1左右加0
{
c[m] = 0;
c[++m] = b[i];
c[++m] = 0;
}
else //其余的1后面为0
{
c[++m] = b[i];
c[++m] = 0;
}
}
else if (b[i] == 0)
{
c[++m] = b[i];
}
++m;
--i;
}
int stop[5]={1,1,0,0,0};//110代表逗号,其余0是为了计算需要添加的
for(i=0;i<5;i++)
{
c[++m]=stop[i];
}
}
int size; //二进制数字的长度
//用命令进行计算,最终输出计算结果(输出的数是图灵机二进制)
void transfor3(int c[],int size)
{
int d[1]={0};
int i;
for(i=0;i<=30;++i)
{
if(d[0]==0&&c[i]==0)
{
c[i]=0;
d[0]=0;
for(int j=0;j<30;j++)
{
if (c[j] == 0 || c[j] == 1){
printf("%d",c[j]);
}
}
printf("\n");
continue;
}
if(d[0]==0&&c[i]==1)
{
d[0]=1;
c[i]=0;
for(int j=0;j<30;j++)
{
if (c[j] == 0 || c[j] == 1){
printf("%d",c[j]);
}
}
printf("\n");
continue;
}
if(d[0]==1&&c[i]==0)
{
d[0]=0;
c[i]=1;
for(int j=0;j<30;j++)
{
if (c[j] == 0 || c[j] == 1){
printf("%d",c[j]);
}
}
printf("\n");
continue;
}
if(d[0]==1&&c[i]==1)
{
d[0]=10;
c[i]=0;
for(int j=0;j<30;j++)
{
if (c[j] == 0 || c[j] == 1){
printf("%d",c[j]);
}
}
printf("\n");
continue;
}
if(d[0]==10&&c[i]==0)
{
d[0]=11;
c[i]=1;
for(int j=0;j<30;j++)
{
if (c[j] == 0 || c[j] == 1){
printf("%d",c[j]);
}
}
printf("\n");
continue;
}
if(d[0]==11&&c[i]==0)
{
d[0]=0;
c[i]=1;
for(int j=0;j<30;j++)
{
if (c[j] == 0 || c[j] == 1){
printf("%d",c[j]);
}
}
printf("\n");
break;
}
}
}
//将结果由图灵机二进制转换为十进制
void transfor4(int c[],int e[],int size)
{
int l=0;
for(int i=0;i<30;i++)
{
if(c[i]==0||c[i]==1)
{
e[l]=c[i];
++l;
}
}
for( i=0;i<l;i++)
{
if(e[i]==1&&e[i+1]==1&&e[i+2]==0)
l=l-3;
}
printf("将图灵机二进制转换成二进制:\n");
int f[10]; //临时数组用来保存图灵机二进制转换的二进制数
int a=0; //用来保存二进制数组的长度
for( i=0;i<l;i++)
{
if(e[i]==0&&e[i+1]==0)//图灵机二进制数组中如果两个数连续是0,二进制数组中保存一个0
{
f[a]=0;
++a;
continue;
}
if(e[i]==0&&e[i+1]==1&&e[i+2]==0)//图灵机二进制数组中连续三个数是010,二进制数组中保存一个1
{
f[a]=1;
++a;
continue;
}
}
for(i=0;i<a;i++)//输出结果的二进制形式
{
printf("%d",f[i]);
}
printf("\n");
printf("最终计算结果(十进制形式)为:\n");
double s=0; //保存结果的十进制形式
for(i=0;i<a;i++)
{
s=s+f[i]*pow(2,a-1-i);
}
printf("%f",s);//输出结果(十进制)
}
void main()
{
int x; //输入的十进制数
int b[10]; //存二进制数
int c[30]; //存图灵二进制数
printf("请输入一个十进制数:");
scanf("%d", &x);
transfor1(x, b,size); //转换为二进制存到数组b中
printf("转换成二进制数是:\n");
for (int i = 10; i >= 0; i--) //倒序输出就是二进制数组b[]
{
if (b[i] == 0 || b[i] == 1){
printf("%d", b[i]);
}
}
transfor2(b, c,size);
printf("\n");
printf("转换成图灵二进制数是:\n");
for (i = 0; i <30; i++) //输出图灵二进制数c[]
{
if (c[i] == 0 || c[i] == 1){
printf("%d", c[i]);
}
}
printf("\n");
printf("图灵机的分步计算过程:\n");
transfor3(c,size);
printf("最终图灵机得出的结果:\n");
for (i = 0; i <30; i++) //输出图灵机的计算结果
{
if (c[i] == 0 || c[i] == 1){
printf("%d", c[i]);
}
}
printf("\n");
int e[10];
transfor4(c,e,size);
printf("\n");
}
总结:
首先对于这次作业,我觉得我的思路很清晰,我第一反应就是用数组,这个比较容易理解,在写代码的过程花费了大量时间将二进制转化为图灵机二进制,主要问题是再把自己的思想转化为代码时转换有点失误。其接下来都比较顺利。
对于这次的不足就是,我对指针不熟悉,所以再用数组进行各种操作时都是用的比较笨的方法。因此,我将重新学习指针,希望我可以掌握。
还有这次我发现,在修改代码时应该让别人来帮你看,这样改正的比较快,而且很容易发现问题所在。