教授谭浩强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

程序设计

立足上文,设计程序

  1. 接收键盘输入数据
  2. 动态创建二维字符数组
  3. 动态创建一维步骤次序数组
  4. 由层数奇偶性,分别取周期步骤,并由步骤次序数组的次序决定存入二维字符数组的一维次序
  5. 输出格式化的二维字符数组

编写设计的程序前先填坑点二和坑点三。
坑点二,动态创建二维数组的的方法是什么?
教材配套程序开发软件是 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);
}
//*/
posted on 2025-03-17 13:35  技术小伙伴  阅读(44)  评论(0)    收藏  举报