教授谭浩强C程序设计(第五版)中汉诺塔的第二种答案
原题
古代的一座梵塔内,含三个相邻座A、B、C,初始时A座上摆了64个盘子 ,小盘子摆大盘子 上面,一位老和尚欲将 这64个盘子从A座向C座移动,规定每次只许移动一个盘子,且三个座上始终保持小盘摆放大盘上的顺序,允许跨座摆放盘子。移动时可将盘子摆放B座上,请编程打印移动盘子的顺序。
提示:可跨座移动盘子
拿一款汉诺塔类似物试玩,亲身体验移动盘子的细节,接着,或许会碰上第一个大坑。
设 A 座上两片盘子,下列两组移动步骤均达标
//第一组
A -> B
A -> C
B -> C
//第二组
A -> C
A -> B
C -> A
B -> C
A -> C
第一组步骤精简,第二组步骤臃肿。
坑点一 如何精简移动盘子的步骤
将倒数第二片盘子至第一片盘子移至 B 座,倒数第一片盘子移至 C 座,朝这个"结构"努力,步骤数会精简些。
三片盘子组成汉诺塔,经步骤
A -> C
A -> B
C -> B
符合上述"结构",再经步骤
A -> C
B -> A
B -> C
A -> C
盘子悉数移动至 C 座,移动终止。共七步,是精简步骤。
规律归纳
编写代码前,先归纳如何精简移动盘子步骤数的规律
规律1
A 座上盘子数量是奇数状态下,移动步骤是
A -> C
A -> B
C -> B
否则
A -> B
A -> C
B -> C
规律2
起初盘子从 A 座向另外两座移动,B 座是终止点,C 座是中间点,将倒数第二片盘子至第一片盘子移至 B 座后,移动一步
A -> C
接着 B 座向另外两座移动,这种情形里,C 座是终止点,A 座是中间点,末尾 C 座上从下至上、从大至小摆着全部盘子,程序终止。
参考上面两条规律编写的代码不能计算三片盘子之上的情况。
从头归纳,察觉移动盘子的步骤对称,中间的一步
A -> C
是对称轴

一个步骤图绘制技巧诞生:画至

这一步骤,剩下一半步骤图水平翻转,底座不变。
随着汉诺塔盘子数量和步骤图的增加,结合规律 1 和规律 2,提出规律 3,即某座上盘子数量满足偶数条件,后续三步骤是
起初点 -> 中间点
起初点 -> 终止点
中间点 -> 终止点
否则
起初点 -> 终止点
起初点 -> 中间点
终止点 -> 中间点
再者,大数量盘子的移动步骤能分解,等于若干小数量盘子的移动步骤和连接步骤,直至两个盘子的移动步骤和一堆移动步骤,设两个盘子的移动步骤是一个单元,这些单元的 起初点和终止点呈周期分布。像这样

继续调优上述规律,察觉逐层分解产生的新步骤是周期性的,三步一周期,且周期随层次序的奇偶性变化,且能向下分解至一个盘子步骤,像这样

归纳后,f(n) = f(n-a) + f(a) + f(n-a),a = 0,1,2,3... 且 a <= n-1,
- 令 a % 2 == 1,周期是
A -> C
C -> B
B -> A
- 令 a % 2 == 0,周期是
A -> B
B -> C
C -> A
程序设计
立足上文,设计程序
- 接收键盘输入数据
- 动态创建二维字符数组
- 动态创建一维步骤次序数组
- 由层数奇偶性,分别取周期步骤,并由步骤次序数组的次序决定存入二维字符数组的一维次序
- 输出格式化的二维字符数组
编写设计的程序前先填坑点二和坑点三。
坑点二,动态创建二维数组的的方法是什么?
教材配套程序开发软件是 C-Free 5.0 Professional,不支持类似 Java 的代入变量创建数组,采取构建指向一维字符数组的指针数组也失败,其仅能代入常量创建指针数组。经研究,定义二重指针和 malloc 方法能动态创建二维数组。
坑点三,逐层构建一维次序数组的方法是什么?
这一方法的抽象流程是一个数组不断二分寻找下一个二分点的流程。随着层数的加深,每层新建的、存储着每层端点的数组随之加长,其中的元素每两个参与计算新一层的二分点,将每层新增的二分点朝一维数组内添加,重复上述步骤,终止条件是已添加倒数第二层的二分点。最后一层的次序数组,元素来自下标元素数组隔一取一。
开源代码
# include<stdio.h>
# include<string.h>
int main()
{
/*
int dishes;
int calSteps(int n);
printf("请输入盘子数量\n");
scanf("%d",&dishes);
//计算步数
int steps = calSteps(dishes);
printf("%d",steps);
char *c = (char*)malloc(steps*2*sizeof(char));
dishes = dishes + 2;
//分层求解步数并存入数组
*char calMove(char* c,int dishes);
*/
/*
printf("请输入字符数量\n");
int i,dishes;
char ctemp;
scanf("%d",&dishes);
scanf("%c",&ctemp);
char *temp,*c;
c = (char*)malloc(dishes*sizeof(char));
temp = c;
for(i=0;i<dishes;i++)
{
gets(c)
c++;
}
c = temp;
for(i=0;i<dishes;i++)
{
puts(c);
}
*/
//printf()
/*
void test(int i);
int i = 0;
test(++i);
*/
/*
int sqr(int n);
printf("%d\n",sqr(3));
return 0;
*/
/*
int i,arr[10],*p = arr;
for(i=0;i<10;i++)
{
printf("请输入第%d个数",i+1);
scanf("%d",p++);
}
p = arr;
printf("10个数:\n");
for(i=0;i<10;i++)
{
printf("%d",*p++);
}
printf("\n");
int a[3][3] = {
{
1,2,3
},
{
4,5,6
},
{
7,8,9
},
{
10,11,12
}
};
*/
//方式一:拿元素指针遍历元素
/*
int *p;
for(p = a[0];p < a[0]+9;p++)
{
printf("%d",*p);
}
*/
//方式二:拿一维数组指针遍历元素
/*
int i,j,(*p)[3]=a;
for(i = 0;i < 3;i++)
{
for(j = 0;j < 3;j++)
{
printf("%d",*(*(a+i)+j));
}
}
*/
//委派 malloc 函数动态创建一维不定长数组
/*
int *p,i,j;
printf("请输入数组长度");
scanf("%d",&i);
p = (int *)malloc(i*sizeof(int));
//printf("%d",p);
for(j=0;j<i;j++)
{
printf("请输入第%d个数",j+1);
scanf("%d",p++);
}
p = p - i;
for(j=0;j<i;j++)
{
printf("%d",*p++);
}
*/
/*
//定义指针数组
//char *arr,*p,*p2,temp;
//char *p,*p2,temp;
//int *arr;
int cLength,i,j,rLength;
printf("请输入指针数组行长度和数组列长度,格式:X,X");
scanf("%d,%d",&cLength,&rLength);
scanf("%c",&temp);
//printf("请输入指针数组行长度");
//scanf("%d",&rLength);
//arr = malloc(cLength*sizeof(char*));
//arr = (int*)malloc(length*sizeof(int));
//printf("%d",sizeof(char *));
//printf("%d",arr);
//p2 = arr;
//p2 = p;
for(i=0;i<cLength;i++)
{
//p = malloc(rLength*sizeof(char));
for(j=0;j<rLength;j++)
{
printf("请输入第%d行第%d列字符",i+1,j+1);
scanf("%c",p++);
scanf("%c",&temp);
}
//arr = p;
//arr++;
}
*/
//p = arr-cLength;
//p = arr;
//p = p2;
/*for(i=0;i<cLength;i++)
{
for(j=0;j<rLength;j++)
{
printf("%c",*p++);
}
printf("\n");
}
*/
/*
printf("arr=%d",arr);
printf("arr=%c",arr);
printf("arr=%d",--arr);
printf("arr=%c",*arr);
*/
//printf("p=%d",p);
//printf("p=%c",p);
//printf("p=%d",*--p);
//printf("p=%c",*p);
/*
for(i=cLength*rLength;i>0;i--)
{
printf("%c",*(p-i));
}
*/
/*
char *p;//1字节
2行*3列 字符,一行3字节
{
{
a,b,c
},
{
d,e,f
}
}
*/
/*
char c[] = {
"abc"
};
printf("%c",*c);
*/
/*
int length,i;
char a[5],b[5];
gets(a);
gets(b);
puts(a);
puts(b);
*/
/*
char arrForOdds[3][2] = {
{"AC"},{"CB"},{"BA"}
};
char arrForEven[3][2] = {
{"AC"},{"BC"},{"CA"}
};
printf("%c",arrForOdds[0][0]);
printf("%c",**arrForOdds);
*/
/*
//printf("%c\n",arrForOdds[0][1]);
//char *p = arrForOdds;
//printf("%c\n",*(p+5));
/*
char arrForTest[3][2] = {
{"AB"},{"CD"},{"EF"}
};
printf("**arrForTest=%c\n",**arrForTest);//**arrForTest=A
printf("**(arrForTest+1)=%c\n",**(arrForTest+1));//**(arrForTest+1)=C
printf("**(arrForTest+1)=%c\n",**(arrForTest+2));//**(arrForTest+2)=E
printf("*(*arrForTest+1)=%c\n",*(*arrForTest+1));//*(*arrForTest+1)=B
printf("*(*(arrForTest+2)+1)=%c\n",*(*(arrForTest+2)+1));//*(*(arrForTest+2)+1)=F
printf("*(*(arrForTest+x)+y),内部加 X,步长等于一维数组长度,外部加y,步长等于一个元素长度");
*/
//printf("%c",arrForEven[0][0]);
//printf("%c",arrForEven[0][1]);
/*
void f(int s,int e,int level);
f(0,14,1);
*/
//void f2(int s,int e,int n);
///*
void f2(int s,int e,int n,int* p);
int sqr(int n);
void literate(int *p,int len);
void log(char str[],int i);
int calDengBiSum(int i);
int calDengBiSum2(int i);
printf("请输入盘子数:\n");
int discs;
scanf("%d",&discs);
//4个盘子示例
//int length = sqr(3)-2;//2的3次方 - 2 ,{3,11,1,5,9,13}
// 除去第一层和最后一层的步骤数和,参数:盘子数 - 1
int length = calDengBiSum2(discs - 1);//2的3次方 - 2 ,{3,11,1,5,9,13}
int *p = malloc(length*sizeof(int));
/*
char arrForOdds[3][2] = {
{"AC"},{"CB"},{"BA"}
};
char arrForEven[3][2] = {
{"AC"},{"BC"},{"CA"}
};
*/
//参数1:开始下标
//参数2:结束下标
//参数3: 盘子数量
//参数4:除去第一层和最后一层长度的数组指针
int end = calDengBiSum2(discs);
printf("结束下标:%d\n",end);
f2(0,end,discs,p);
printf("f2 结束\n");
//printf("calDengBiSum2=%d",calDengBiSum2(4));
//扩展原数组,扩展最后一层步骤的长度数组
p = realloc(p,calDengBiSum2(discs)*sizeof(int));
//int *pArr2 = malloc((14+1)*sizeof(int));
//int *tempArr = malloc(sqr(3)*sizeof(int));
//从第二层开始算至倒数第二层的总步骤数
int beforeLength = calDengBiSum2(discs - 1);
printf("beforeLength=%d",beforeLength);
//将最后一层步骤数放进大数组中
int i = 0,j = 0;
for(;i < end + 1;i++)
{
//*(pArr2+i) = i;
if(i % 2 != 0)
continue;
//*(tempArr+j) = i;
*(p + beforeLength + j) = i;
j++;
}
//literate(p,length);
int *tempPointer = p + 1;
printf("\ntempPointer[0]=%d",tempPointer[0]);
printf("\n");
//printf("%d",sqr(3));
//literate(tempArr,sqr(3));
//遍历步骤大数组
literate(p,end);
//*/
/*
void quickSort(int *p,int len);
int length = 10;
int *p = malloc(length*sizeof(int));
int i = 0;
for(;i<length;i++)
{
printf("请输入第%d/%d个数字\n",i,length);
scanf("%d",p+i);
}
quickSort(p,length);
i = 0;
printf("after quickSort\n");
for(;i<length;i++)
{
printf("arr[%d]=%d\n",i,*(p+i));
}
void halfSearch(int* p,int len,int n);
*/
/*
int p[5] = {
1,2,3,4,6
};
printf("*p=%d",*p);
int length = 5;
*/
/*
printf("请输入预设的查询元素\n");
int n;
scanf("%d",&n);
halfSearch(p,length,n);
*/
/*
void literate(int *p,int len);
int *pArr1 = malloc(sizeof(int)*3);
int *pArr2 = malloc(sizeof(int)*5);
int k = 0,i = 0;
for(;i < 3;i++)
{
*(pArr1+i) = i*2;
}
for(i = 0;i < 3;i++)
{
//pArr2[k] = pArr1[i];
pArr2[k++] = pArr1[i];
if(i < 2)
{
//k++;
pArr2[k++] = (pArr1[i] + pArr1[i+1])/2;
//k++;
}
}
//literate(pArr1,3);
free(pArr1);
pArr1 = pArr2;
literate(pArr1,5);
*/
/*
int i,len;
scanf("%d",&len);
int *p = malloc(len*sizeof(int));
int *p2 = malloc(len*sizeof(int));
for(i=0;i<len;i++)
{
*(p+i) = i;
p2[i] = len - i;
printf("arr[%d]=%d",i,*(p+i));
}
printf("before free\n");
free(p);
p = p2;
for(i=0;i<len;i++)
{
printf("arr[%d]=%d",i,*(p+i));
}
printf("after free\n");
*/
return 0;
}
/*
int calSteps(int n)
{
if(n == 1)
return 1;
return calSteps(--n)*2+1;
}
*/
int sqr(int n)
{
if(n==1)
return 2;
return sqr(--n)*2;
}
//回调构建树形式数据,而我计划的数据形式是分层的
/*
void f(int s,int e,int level)
{
if(e - s < 2) return;
int m = (s+e)/2;
printf("level=%d,%d\n",level,m);
level++;
f(s,m-1,level);
f(m+1,e,level);
}
*/
/*
void f(int s,int e)
{
printf("e=%d",e);
if(e - s == 1)
return;
e--;
f(s,e);
}
*/
void f2(int s,int e,int n,int* p)
{
int sqr(int n);
void literate(int *p,int len);
void log(char str[],int i);
int pArrLength = 3;
int *pArr = malloc(pArrLength*sizeof(int));
//全局游标顺序保存同层数据
int cursor = 0;
*pArr = s;
*++pArr = (s + e)/2;
*++pArr = e;
pArr = pArr - pArrLength + 1;
literate(pArr,pArrLength);
/*
printf("*pArr=%d",*pArr);
printf("*pArr=%d",pArr[0]);
printf("*--pArr=%d",*--pArr);
printf("*--pArr=%d",pArr[1]);
printf("*--pArr=%d",*--pArr);
printf("*--pArr=%d",pArr[2]);
*/
int i = 1;
log("n",n);
while(i < n - 1)
{
i++;
log("i",i);
int k,j;
int pArrLength2 = sqr(i)+1;
log("pArrLength2",pArrLength2);
int *tempArr2 = malloc(pArrLength2*sizeof(int));
for(k = 0,j = 0;j < pArrLength;j++)
{
tempArr2[k++] = pArr[j];
//log("tempArr2[k]",tempArr2[k]);
//k++;
//log("j",j);
//log("k",k);
if(j + 1 < pArrLength)
{
if(k < pArrLength2/2)
{
tempArr2[k] = (pArr[j] + pArr[j+1])/2;
//k++;
//log("保存tempArr[k]",tempArr2[k]);
}
else
{
tempArr2[k] = (pArr[j]+ 1 + pArr[j+1])/2;
//k++
//log("保存tempArr[k]",tempArr2[k]);
}
log("保存tempArr[k]",tempArr2[k]);
*(p+cursor++) = tempArr2[k];
k++;
//log("tempArr2[k]",tempArr2[k]);
//k++;
//tempArr2[k++] = pArr[j + 1];
//log("tempArr2[k]",tempArr2[k]);
//k++;
//j++;
}
}
// log("before free,pArr[1]",pArr[1]);
free(pArr);
pArrLength = pArrLength2;
log("after free,pArrLength",pArrLength);
pArr = tempArr2;
log("after free,pArr[1]",pArr[1]);
// literate(pArr,pArrLength);
}
}
void literate(int *p,int len)
{
int i = 0;
for(;i < len;i++)
{
printf("*(p+i)=%d",*(p+i));
}
}
void log(char str[],int i)
{
printf("%s = %d\n",str,i);
}
//快速排序
void quickSort(int *p,int len)
{
void log(char str[],int i);
int i;
int *head = p;
int *tail = head + len - 1;
int std = *head;
//log("*head",*head);
//log("*tail",*tail);
if(len < 2)
return;
printf("len=%d",len);
while(head != tail)
{
while(*tail > std)
{
tail--;
if(head == tail)
break;
}
if(head == tail)
break;
*head = *tail;
head++;
printf("after head++\n");
///*
for(i=0;i<len;i++)
{
printf("arr[%d]=%d\n",i,*(p+i));
}
printf("\n");
//*/
if(head == tail)
break;
while(*head < std)
{
head++;
if(head == tail)
break;
}
if(head == tail)
break;
*tail = *head;
tail++;
///*
printf("after tail++\n");
for(i=0;i<len;i++)
{
printf("arr[%d]=%d\n",i,*(p+i));
}
printf("\n");
//*/
}//while(head != tail)
//这里 head == tail
*head = std;
//if(head == p || head == p + len - 1)
// return;
//printf("before quickSort1,head-p=%d",head - p);
//quickSort(head - 1,head - p);
quickSort(p,head - p);
quickSort(head + 1,p + len - 1 - head);
}
//二分查找
void halfSearch(int* p,int len,int n)
{
int head = 0;
int tail = len - 1;
int mid;
while(tail >= head)
{
mid = (head + tail)/2;
printf("mid=%d\n",mid);
if(*(p + mid) < n)
head = mid + 1;
else if(*(p + mid) > n)
tail = mid - 1;
else
{
printf("arr[%d]=%d\n",mid,p[mid]);
return;
}
}
printf("未查询出该元素\n");
}
int calDengBiSum(int i)
{
// i = 盘子数
// return 分别挪动第 1 片至第 i 片盘子的步骤总数
int sqr(int n);
return sqr(i+1)-2-i;
}
int calDengBiSum2(int i)
{
// i = 盘子数
// return 挪动前 i 片盘子的每层步骤数的和减第一步
int sqr(int n);
return sqr(i) - 1 - 1;
}
#include "stdio.h"
#include "string.h"
#include <stdlib.h>
int main()
{
//void test();
//test();
//int calSteps(int n);//无碍
int calStepsReduceOne(int i);
//void calMove(int n,int steps,char **p);
void calMove(int n,int steps,char **p,int* stepsArr);
int sqr(int n);//无碍
void literate2(char** p,int len,int cols);//无碍
void fillArr(int len,int cols,char **p);//无碍
//int calDengBiSum(int i);无碍
//生成除第一层和最后一层步骤的方法
void f2(int s,int e,int n,int* p);
void literate(int *p,int len);
void log(char str[],int i);
int n,steps;
//char **tp;
printf("请输入盘子个数");
scanf("%d",&n);
//从第一层至最后一层步骤总数
steps = calStepsReduceOne(n) + 1;
printf("steps = %d\n",steps);
//定义指向字符指针的指针
if(n == 1)
{
char **p2 = malloc(steps*sizeof(char*));
n = n+2;
calMove(n,steps,p2,p2);
literate2(p2,steps,2);
return 0;
}
//创建步骤数组
// 除去第一层和最后一层的步骤数和,参数:盘子数 - 1
int steps2 = calStepsReduceOne(n-1);
log("steps2",steps2);
//开辟空间保存 除去第一层和最后一层的步骤
int *p = malloc(steps2*sizeof(int));
//除第一层步骤数,其他层步骤数的和
int steps3 = calStepsReduceOne(n);
log("steps3",steps3);
//生成除第一层和最后一层步骤的方法
f2(0,steps3,n,p);
printf("f2已终止\n");
//扩展原数组,扩展最后一层步骤的长度数组
p = realloc(p,steps3*sizeof(int));
//从第二层开始算至倒数第二层的总步骤数
//steps2
//将最后一层步骤数放进大数组中
int i = 0,j = 0;
for(;i < steps3 + 1;i++)
{
//*(pArr2+i) = i;
if(i % 2 != 0)
continue;
//*(tempArr+j) = i;
*(p + steps2 + j) = i;
j++;
}
//遍历步骤大数组
literate(p,steps3);
printf("\n上面是步骤大数组遍历\n下面是二维数组遍历\n");
///*
char **p2 = malloc(steps*sizeof(char*));
//tp = p;
//填充二维数组结构
fillArr(steps,2,p2);
//增补 盘子数量
n = n+2;
//calMove(n,steps,p);
calMove(n,steps,p2,p);
free(p);
//遍历二维数组
literate2(p2,steps,2);
//*/
return 0;
}
/*
int calSteps(int n)
{
if(n == 1)
return 1;
return calSteps(--n)*2+1;
}
*/
int calStepsReduceOne(int i)
{
// i = 盘子数
// return 挪动前 i 片盘子的每层步骤数的和减第一步
int sqr(int n);
return sqr(i) - 1 - 1;
}
int sqr(int n)
{
if(n == 0)
return 1;
if(n == 1)
return 2;
return sqr(--n)*2;
}
///* n 盘子数量 + 2,steps 步骤总数,**p 步骤字符数组, stepsArr 步骤次序数组
void calMove(int n,int steps,char **p,int* stepsArr)
{
void log(char str[],int i);
int sqr(int n);//无碍
int calDengBiSum(int i);
char arrForOdds[3][2] = {
{"AC"},{"CB"},{"BA"}
};
char arrForEven[3][2] = {
//{"AC"},{"BC"},{"CA"}
{"AB"},{"BC"},{"CA"}
};
//count: 当前层待补充的步骤数量
///*
int i,count,count2,j=0;
//*/
//printf("n=%d",n);
//printf("**arrForOdds=%c",**arrForOdds);
//log("calMove已执行",0);
///*
for(i=1;i<=n-2;i++)
{
count = sqr(i-1);
//count2 = count;
//printf("count=%d",count);
log("count",count);
if(count == 1)//无碍
{
*(*(p+steps/2)) = **arrForOdds;//arrForOdds[0][0];
*(*(p+steps/2)+1) = *(*arrForOdds+1);
//printf("*(*(p+steps/2))=%c\n",*(*(p+steps/2)));
//printf("*(*(p+steps/2)+1)%c\n",*(*(p+steps/2)+1));
//log("count==1执行",0);
continue;
}
if(i % 2 == 1)
{
int j,k;
log("stpesArr[0]",stepsArr[0]);
for(j = 0;j < count;j++)
{
for(k = 0;k < 2;k++)
{
*(*(p+stepsArr[0])+k) = *(*(arrForOdds+j%3)+k);
//printf("*(*(arrForOdds+j%3)+k)=%c",*(*(arrForOdds+j%3)+k));
}
stepsArr++;
}
//*/
/*
while(count > count2/2)
{
int temp = 0;
*(*(p+steps/2-calDengBiSum(i)/2-count/2)) = **(arrForOdds+temp%3);
*(*(p+steps/2-calDengBiSum(i)/2-count/2)+1) = *(*(arrForOdds+temp%3)+1);
temp++;
*(*(p+steps/2+calDengBiSum(i)/2-count/2)) = **(arrForOdds+temp%3);
*(*(p+steps/2+calDengBiSum(i)/2-count/2)+1) = *(*(arrForOdds+temp%3)+1);
count--;
}
*/
///*
}
else
{
int j,k;
for(j = 0;j < count;j++)
{
log("stpesArr[0]",stepsArr[0]);
log("j",j);
log("count",count);
for(k = 0;k < 2;k++)
{
*(*(p+stepsArr[0])+k) = *(*(arrForEven+j%3)+k);
//log("j",j);
//printf("*(*(arrForEven+j%3)+k)=%c\n",*(*(arrForEven+j%3)+k));
}
stepsArr++;
}
//*/
/*
while(count > count2/2)
{
int temp = 0;
printf("steps/2=%d,calDengBiSum(i)/2=%d,count/2=%d\n",steps/2,calDengBiSum(i)/2,count/2);
//*/
/*
printf("**(arrForEven+temp%3)=%c",**(arrForEven+temp%3));
printf("*(*(arrForEven+temp%3)+1)=%c",*(*(arrForEven+temp%3)+1));
*(*(p+steps/2-calDengBiSum(i)/2-count/2)) = **(arrForEven+temp%3);
*(*(p+steps/2-calDengBiSum(i)/2-count/2)+1) = *(*(arrForEven+temp%3)+1);
*/
//temp++;
/*
printf("**(arrForEven+temp%3)=%c",**(arrForEven+temp%3));
printf(" *(*(arrForEven+temp%3)+1)=%c", *(*(arrForEven+temp%3)+1));
*(*(p+steps/2+calDengBiSum(i)/2-count/2)) = **(arrForEven+temp%3);
*(*(p+steps/2+calDengBiSum(i)/2-count/2)+1) = *(*(arrForEven+temp%3)+1);
*/
/*
count--;
}
*/
///*
}
}
}
//*/
///*
void literate2(char** p,int len,int cols)
{
int i,j;
for(i=0;i<len;i++)
{
for(j=0;j<cols;j++)
{
//printf("*(*(p+i)+j)=%c\n",*(*(p+i)+j));
if(j == cols - 1)
printf("%c",*(*(p+i)+j));
else
printf("%c -> ",*(*(p+i)+j));
}
printf("\n");
}
}
//*/
void fillArr(int len,int cols,char **p)
{
int i,j;
char *p2;
for(i=0;i<len;i++)
{
p2 = malloc(cols*sizeof(char));
*p = p2;
//printf("after p=--p2 ,p2 address = %d,p address = %d\n",p2,p);
for(j=0;j<cols;j++)
{
*p2 = 'Y';
p2++;
}
p++;
}
// return p;
}
int calDengBiSum(int i)
{
int sqr(int n);
return sqr(i-1)+1;
}
/*
void test()
{
//printf("sizeof char* = %d\n",sizeof(char*));
//printf("sizeof char = %d\n",sizeof(char));
//printf("sizeof int = %d\n",sizeof(int));
int len,i,cols,j;
char ctemp,**tp,*p2;
printf("请输入数组行长度");
scanf("%d",&len);
//定义字符指针,初始地址等于一维数组初始地址
//char *p = malloc(2*len*sizeof(char)+1);
char **p = malloc(len*sizeof(char*));
//printf("%d\n",p++);
printf("**p=%d",p);
printf("请输入数组列长度");
scanf("%d",&cols);
scanf("%c",&ctemp);
//printf("i=%d,j=%d",len,cols);
tp = p;
for(i=0;i<len;i++)
{
p2 = malloc(cols*sizeof(char));
printf("p2 malloc address = %d\n",p2);
*p = p2;
//printf("after p=--p2 ,p2 address = %d,p address = %d\n",p2,p);
for(j=0;j<cols;j++)
{
printf("请输入第%d行第%d列字符",i+1,j+1);
scanf("%c",p2++);
printf("after p2++ address = %d\n",p2);
scanf("%c",&ctemp);
}
//*p2 = '\0';
//p2++;
//*p = --p2;
//printf("after p=--p2 ,p2 address = %d,p address = %d\n",p2,p);
p++;
printf("after p++,p address = %d\n",p);
}
p = tp;
printf("after p=tp,p address = %d\n",p);
for(i=0;i<len;i++)
{
for(j=0;j<cols;j++)
{
printf("*(*(p+i)+j)=%c\n",*(*(p+i)+j));
//printf("p=%d\n",p);
//printf("*(p+i)=%d\n",*(p+i));
//printf("*(p+i)+j=%d\n",*(p+i)+j);
}
//printf("*(*(p+i)+j)=%c\n",*(*(p+i)+j));
}
//char *p3 = *p;
//printf("*p3=%c\n",*p3);
//printf("*++p3=%c\n",*++p3);
//char *p4 = *++p;
//printf("p4=%c\n",*p4);
//printf("*++p4=%c\n",*++p4);
//printf("*p=%d\n",*p);
//printf("**p=%c\n",**p);
//printf("\n");
}
*/
void f2(int s,int e,int n,int* p)
{
int sqr(int n);
void literate(int *p,int len);
void log(char str[],int i);
int pArrLength = 3;
int *pArr = malloc(pArrLength*sizeof(int));
//全局游标顺序保存同层数据
int cursor = 0;
*pArr = s;
*++pArr = (s + e)/2;
*++pArr = e;
pArr = pArr - pArrLength + 1;
literate(pArr,pArrLength);
/*
printf("*pArr=%d",*pArr);
printf("*pArr=%d",pArr[0]);
printf("*--pArr=%d",*--pArr);
printf("*--pArr=%d",pArr[1]);
printf("*--pArr=%d",*--pArr);
printf("*--pArr=%d",pArr[2]);
*/
int i = 1;
//log("n",n);
while(i < n - 1)
{
i++;
//log("i",i);
int k,j;
int pArrLength2 = sqr(i)+1;
//log("pArrLength2",pArrLength2);
int *tempArr2 = malloc(pArrLength2*sizeof(int));
for(k = 0,j = 0;j < pArrLength;j++)
{
tempArr2[k++] = pArr[j];
//log("tempArr2[k]",tempArr2[k]);
//k++;
//log("j",j);
//log("k",k);
if(j + 1 < pArrLength)
{
if(k < pArrLength2/2)
{
tempArr2[k] = (pArr[j] + pArr[j+1])/2;
//k++;
//log("保存tempArr[k]",tempArr2[k]);
}
else
{
tempArr2[k] = (pArr[j]+ 1 + pArr[j+1])/2;
//k++
//log("保存tempArr[k]",tempArr2[k]);
}
//log("保存tempArr[k]",tempArr2[k]);
*(p+cursor++) = tempArr2[k];
k++;
//log("tempArr2[k]",tempArr2[k]);
//k++;
//tempArr2[k++] = pArr[j + 1];
//log("tempArr2[k]",tempArr2[k]);
//k++;
//j++;
}
}
// log("before free,pArr[1]",pArr[1]);
free(pArr);
pArrLength = pArrLength2;
//log("after free,pArrLength",pArrLength);
pArr = tempArr2;
//log("after free,pArr[1]",pArr[1]);
// literate(pArr,pArrLength);
}
}
void log(char str[],int i)
{
printf("%s = %d\n",str,i);
}
void literate(int *p,int len)
{
int i = 0;
for(;i < len;i++)
{
printf("*(p+i)=%d",*(p+i));
}
}
教材源码
/*汉诺塔:
古代的一座梵塔内,含三个相邻座A、B、C,初始时A座上摆了64个盘子 ,小盘子摆大盘子 上面,
一位老和尚欲将 这64个盘子从A座向C座移动,规定每次只许移动一个盘子,且三个座上始终
保持小盘摆放大盘上的顺序,允许跨座摆放盘子。移动时可将盘子摆放B座上,请编程打印移动盘子的顺序
*/
#include <stdio.h>
int main()
{
/*
int a = 1;
printf("数量%d\n",a);
*/
void hannuo(int n,char one,char two,char three);
int m;
printf("input the number of diskes");
scanf("%d",&m);
hannuo(m,'A','B','C');
return 0;
}
///*
void hannuo(int n,char one,char two,char three)
{
void move(char x,char y);
if(n == 1)
move(one,three);
else
{
hannuo(n-1,one,three,two);
move(one,three);
hannuo(n-1,two,one,three);
}
}
void move(char x,char y)
{
printf("%c -> %c \n",x,y);
}
//*/
浙公网安备 33010602011771号