C语言程序设计第五版谭浩强课后答案 第六章习题答案

C语言程序设计第五版谭浩强课后答案 第六章习题答案1.用筛选法求100之内的素数解析:这题的关键是要知道什么是筛选法。intmain(){ inti=0,j=0; intarr[100]; //录入数字 for(i=0;i<100;i++) { arr[i]=i+1; } //1不是素数,直接写0,或者在上一步就把0写进去。 arr[0]=0; //这一步是实现筛选法 //筛选法实际上就是用后面的数字整除当前数字 //如果后面的数字能够整除当前值,则将其排除 //..

大家好,欢迎来到IT知识分享网。

1. 用筛选法求100之内的素数

解析:这题的关键是要知道什么是筛选法,👉筛选法。

int main()
{
	int i = 0, j = 0;
	int arr[100];
	//录入数字
	for (i = 0; i < 100; i++)
	{
		arr[i] = i + 1;
	}
	//1不是素数,直接写0,或者在上一步就把0写进去。
	arr[0] = 0;
	//这一步是实现筛选法
	//筛选法实际上就是用后面的数字整除当前数字
	//如果后面的数字能够整除当前值,则将其排除
	//按照这样的步骤以次继续,直至到达范围边缘
	for (i = 0; i < 100; i++)
	{
		for (j = i + 1; j < 100; j++)
		{
			//这个if要注意,在第一轮筛选的时候已经把很多数字写0
			if (arr[j] != 0 && arr[i] != 0)
			{
				//如果后面的数字可以整除当前值
				//说明后面的数字肯定不是素数
				//我这里说的整除和取模是一样的,都是余数为0
				if (arr[j] % arr[i] == 0)
				{
					arr[j] = 0;
				}
			}
		}
	}
	//打印筛选后的数字
	for (i = 0; i < 100; i++)
	{

		if (arr[i] != 0)
		{
			printf("%d ", arr[i]);
		}
	}
	return 0;
}

运行结果: 

C语言程序设计第五版谭浩强课后答案 第六章习题答案

2. 用选择法对10个整数排序

解析:问题来了啥是选择法呢?👉选择排序法。

简单来说就是把最小值或者最大值标记出来,当比较结束后把标记值和首位(或者末位)做交换,通过多轮比较,排出想要的顺序。

//打印
void print(int* arr,int sz)
{
	for (int i = 0; i <= sz; i++)
	{
		printf("%d ", arr[i]);
	}
	printf("\n");

}

int main()
{
	int i, j, pos;
	int arr[] = { 2,8,3,9,5,7,1,4,0,6 };
	int sz = sizeof(arr) / sizeof(arr[0])-1;
	print(&arr,sz);//这是自定义的打印函数,不是printf!!!
	for (i = 0; i <= sz; i++)
	{
		pos = 0;//将标记置于第一位
		for (j = 1; j <= sz-i; j++)//比较位从第二位开始,sz-i是为了让范围缩小
		{
			if (arr[j] > arr[pos])
			{
				pos = j;//如果比较值比标记值大,便将比较值坐标赋值给标记坐标
			}
		}
		if (pos != sz-i)//比较完成后判断标记坐标是不是在边界
		{
			int temp = arr[pos];
			arr[pos] = arr[sz-i];
			arr[sz-i] = temp;
		}
	}
	print(&arr, sizeof(arr) / sizeof(arr[0]) - 1);//sz已经被改变了,要重新计算
	return 0;
}

既然可以把最大值筛选出来,就可以把最小值筛选出来,如果两个一起进行效率会大很多。

3. 求一个3 X 3的整形矩阵对角线元素之和

解析:创建矩阵和创建数组是一样的,像这一题要创建3×3的整形矩阵,可以这样操作int arr[3][3];先行后列很简单。

int main()
{
	int arr[3][3] = { {1,2,3},{4,5,6},{7,8,9} };
	int i, j;
	int right_sum = 0, left_sum = 0;
	
	for (i = 0; i <= 2; i++)
	{
		for (j = 0; j <= 2; j++)
		{
			if (i == j)
			{
				left_sum += arr[i][j];
			}
			if (i == 2 - j)
			{
				right_sum += arr[i][j];
			}
		}
	}
		printf("左对角线的数值为%d\n", left_sum);
		printf("右对角线的数值为%d\n", right_sum);
	return 0;
}

运行结果:

C语言程序设计第五版谭浩强课后答案 第六章习题答案

 4. 有一个已经排好序的数组,要求输入一个数后,按原来顺序的规律将它插入数组中

解析:这个题目有一种简单又粗暴的办法:把插入的数字放在数组末端,然后再做一次排序。

但是我觉得这个方法不好,我们应该换一个思路:首先我们将插入的数字和数组相比较,如果插入的数字比原来数组的数字小,就把数组数字的角标给定位下来,并把原来数组数字向后挪一位。

int main()
{
	int i, j;
	int arr[10] = {1,2,3,4,5,6,7,8,9};
	int input = 0;
	int end = 8;//数组最后一位数字的角标就是8
	printf("请输入要插入的数据:>");
	scanf("%d", &input);
	printf("当前排列情况:>");
	for (i = 0; i < 9; i++)
	{
		printf("%d ", arr[i]);
	}
	printf("\n");
	//如果插入的数字比原来数组的数字小
	//就把数组数字的角标给定位下来,并把原来数组数字向后挪一位。
	while (end >= 0 && input < arr[end])
	{
		arr[end + 1] = arr[end];
		end--;
	}
	arr[end + 1] = input;
	printf("插入排列情况:>");
	for (i = 0; i < 10; i++)
	{
		printf("%d ", arr[i]);
	}
	printf("\n ");
	return 0;
}

运行结果:

C语言程序设计第五版谭浩强课后答案 第六章习题答案

5. 将一个数组中的值按逆序重新存放。例如:原来顺序为8,6,5,4,1。要求改为1,4,5,6,8。

解析:这一题较上一题就简单多了,可以用简单的方法也可以用复杂的方法。

复杂的方法就是重新排序,十种排序方法你随便选择;

简单的方法就是数值交换:数组左右交换,当左坐标大于等于右坐标时停止;

int main()
{
	//vs用的时C99标准,数组的定义必须为常量
	//如果用支持C11标准的编译器,这里可以用变量定义,实现灵活定义数组
	int arr[] = { 8,6,5,4,1 };
	//这个sz随意,可以自己写数值,不一定要计算
	int sz = sizeof(arr) / sizeof(arr[0]);
	int left = 0, right = sz - 1;
	//打印
	printf("初始序列:>");
	for (int i = 0; i < sz ; i++)
	{
		printf("%d ",arr[i]);
	}
	printf("\n");
	//重新排序
	//数组左右交换,当左坐标大于等于右坐标时停止
	while (left < right)
	{
		int temp = arr[left];
		arr[left] = arr[right];
		arr[right] = temp;
		left++;
		right--;
	}
	//打印
	printf("重排序列:>");
	for (int i = 0; i < sz; i++)
	{
		printf("%d ", arr[i]);
	}
	printf("\n");
	return 0;
}

 运行结果:

C语言程序设计第五版谭浩强课后答案 第六章习题答案

6. 输出以下的杨辉三角(要求输出10行)

1   
1   1
1   2   1
1   3   3   1
1   4   6   4   1
1   5  10  10   5   1
……

 解析:这题的关键在于知道什么是杨辉三角,杨辉三角的规律是什么。不知道还不点👉杨辉三角?解杨辉三角有几种方法:

暴力解法:直接找规律挨个计算并打印出来。(不推荐,效率奇低)

创建数组:上面给的打印示例不好看出规律,我们把他排序看看,如下图。

C语言程序设计第五版谭浩强课后答案 第六章习题答案

从这幅图中我们可以得到一些信息:

  1. 每个数等于它上方两数之和。

  2. 每行数字左右对称,由1开始逐渐变大。

  3. 第n行的数字有n项。

  4. 前n行共[(1+n)n]/2 个数。

 好,根据以上信息我们可以开始写代码了。

#define N 10
int main()
{
	int i, j;
	int arr[N][N];
	printf("1\n");//第一行直接打印
	//把边界赋值为1
	for (i = 1; i < N; i++)
	{
		arr[i][0] = 1;
		j = i;
		arr[i][j] = 1;
	}
	int aim = N;
	for (i = 1; i < N; i++)
	{
		printf("1\t");//第一个1直接打印
		for (j = 1; j < i; j++)
		{
			arr[i][j] = arr[i - 1][j - 1] + arr[i - 1][j];
			
			printf("%d\t",arr[i][j]);
		}
		printf("1\n");//最后一个1直接打印并换行
	}
	return 0;
}

运行结果:

C语言程序设计第五版谭浩强课后答案 第六章习题答案

这种是简单粗暴的写法,只针对这一题,通用性不佳,而且打印出的结果没有空格美化。

我们可以做一些简单的美化工作让他好看点👉戳这里!

7. 输出”魔方阵”。所谓魔方阵是指这样的方阵,它的每一行、每一列和对角线之和均相等。

解析:找出一个二维数组中的鞍点,即该位置上的元素在该行上最大,在该列上最小,也可能没有鞍点。

鞍点是行上最大,列上最小的元素,因此对数组的第i元素进行如下操作:
1、找到该行上最大元素,用max标记,并标记该元素所在列colindex
2、找colindex列上最小的元素,用min标记,并标记该元素所在行号rowindex
3、如果max和min相等,并且最小的元素刚好是在第i行,则为鞍点
4、如果所有行找完了,没有输出则没有鞍点

#define ROW 3
#define COL 3
int main()
{
	int i, j,max,min,flag = 0;
	int arr[ROW][COL];
	int rowindex = 0, colindex = 0;//寻找最大值的坐标
	for (int i = 0; i <= ROW - 1; i++)
	{
		for (int j = 0; j <= COL - 1; j++)
		{
			scanf("%d", &arr[i][j]);
		}
	}

	for (i = 0; i <= ROW - 1; i++)
	{
		max = arr[i][0];
		for (j = 0; j <= COL - 1; j++)
		{
			if (max < arr[i][j])
			{
				max = arr[i][j];
				colindex = j;
			}
		}
		min = arr[0][colindex];
		for (int i = 0; i <= ROW - 1; i++)
		{
			if (arr[i][colindex] < min)
			{
				min = arr[i][colindex];
				rowindex = i;
			}
			
		}
		if (min == max && i == rowindex)
		{
			flag = 1;
			printf("鞍点的坐标为[%d,%d],值为%d", rowindex, colindex, arr[rowindex][colindex]);
			break;
		}
	}
	if (flag == 0)
	{
		printf("没有鞍点");
	}

	return 0;
}

运行结果:

C语言程序设计第五版谭浩强课后答案 第六章习题答案C语言程序设计第五版谭浩强课后答案 第六章习题答案

9. 有15个数按由大到小顺序存放在一个数组中,输入一个数,要求用折半查找法找出该数是数组中第几个元素的值。如果该数不在数组中,则输出”无此数”。

解析:二分查找是七大查找中的一个,这种查找方法比较简单快捷,但是这种方法面对频繁更新、删除操作、无序的表较为无力。

二分法原理:(举例的数组按由大到小排列)

1、标记出数组的左右边界和中间坐标;

2、比较中间值与查询值得大小关系,如果中间值大于查询值则把中间值+1赋值给左边界,同理则把中间值+1赋值给右边界;

3、当中间值等于查询值时终止比较并输出结果;

4、当左边界大于有边界时则认为数组种不存在查找值,输出不存在;

int binner_find(int* arr, int sz, int num)
{
	int left = 0, right = sz - 1;
	int i, j;
	while (left <= right)
	{
		int mid = (left + right) / 2;
		if (arr[mid] > num)
		{
			left = mid+1;
		}
		else if (arr[mid] < num)
		{
			right = mid-1;
		}
		else if (arr[mid] == num)
		{
			return mid+1;
		}

	}
	return -1;
}
int main()
{
	int arr[] = { 15,14,13,12,11,10,9,8,7,6,5,4,3,2,1 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	int num = 0;
	printf("请输入要查找的数值:>");
	scanf("%d", &num);
	int mod = binner_find(&arr, sz, num);
	if (mod == -1)
	{
		printf("无此数");
	}
	else
	{
		printf("找到了是第%d个元素",mod);
	}

	return 0;
}

注:最后返回的mid+1是因为这一题要求找到查询值是数组中的第几个元素,按照算数排列的话这里的坐标就是mid+1。

 运行结果:

C语言程序设计第五版谭浩强课后答案 第六章习题答案

10. 有一篇文章,共有3行文字,每行有80个字符。要求分别统计出其中英文大写字母、小写字母、数字、空格以及其他字符的个数。

解析:这题的难点在于如何遍历3X80的字符。

大概有两种方法:

1、getchar读取字符:利用getchar能够读取单一字符的特性,运用循环语句完成代码;

2、创建数组:创建数组,运用gets和循环遍历数组完成代码;

(1)运用getchar读取字符

/*
getchar做法,getchar有一个特性:一次只能吞吐一个字符。
基于这个特性我们就可以设计一个3X80的循环,一个一个逐字分析得出个字符的数量。
*/
int main()
{
	char c;//创建一个字符变量来接收getchar的信息
	int capital = 0, minuscules = 0, 
		numbe = 0, space = 0, other = 0;
	printf("请输入一篇文章(共3行文字,每行80个字符):>\n");
		for (int i = 0; i < 3; i++)
		{
			for (int j = 0; j < 80; j++)
			{
				c = getchar();
				if (c >= 'A' && c <= 'Z')
				{
					capital++;
				}
				else if (c >= 'a' && c <= 'z')
				{
					minuscules++;
				}
				else if (c >= '0' && c <= '9')
				{
					numbe++;
				}
				else if (c == ' ')
				{
					space++;
				}
				else
				{
					other++;
				}
			}
		}

	printf("大写字母的个数:%d\n", capital);
	printf("小写字母的个数:%d\n", minuscules);
	printf("数字的个数:%d\n", numbe);
	printf("空格的个数:%d\n", space);
	printf("其他字符的个数:%d\n", other);

	return 0;
}

(2)创建数组

int main()
{
	char c[3][3];
	int i, j;
	int capital = 0, minuscules = 0, 
		numbe = 0, space = 0, other = 0;
	
	for (i = 0; i < 3; i++)
	{
		printf("请输入第%d行:>\n", i + 1);
		gets(c[i]);
	
		for (j = 0; j < 3 && c[i][j] != '\0'; j++)
		{
			
			if (c[i][j] >= 'A' && c[i][j] <= 'Z')
			{
				capital++;
			}
			else if (c[i][j] >= 'a' && c[i][j] <= 'z')
			{
				minuscules++;
			}
			else if (c[i][j] >= '0' && c[i][j] <= '9')
			{
				numbe++;
			}
			else if (c[i][j] == ' ')
			{
				space++;
			}
			else
			{
				other++;
			}
		}
	}

	printf("大写字母的个数:%d\n", capital);
	printf("小写字母的个数:%d\n", minuscules);
	printf("数字的个数:%d\n", numbe);
	printf("空格的个数:%d\n", space);
	printf("其他字符的个数:%d\n", other);

	return 0;
}

注:这种方法在VS中会出现栈错误:Stack around the variable ‘XXX’ was corrupted.可能是编译器的问题。

👆这个图片就不放了,自己运行一下吧。

11. 输出以下图案:

* * * *
  * * * *
    * * * *
      * * * *
        * * * *

 解析:难题做多了,做一个简单的题目。这题比较简单,我们可以通过观察得到每一行打印多打印两个空格,用for就可以轻松解决。

int main()
{
	int i = 0, j = 0;
	for (i = 0; i < 5; i++)
	{
		for (j = 0; j < i; j++)
		{
			printf("  ");
		}
		printf("* * * *\n");
	}
	return 0;
}

运行结果:

C语言程序设计第五版谭浩强课后答案 第六章习题答案

12. 有一行电文,以按下面规律译成密码:

A--->Z   a--->z
B--->Y   b--->Y
C--->X   c--->x

即第1个字母编程第26个字母,第i个字母编程第(26-i+1)个字母,非字母字符不变,要求编程序将密码译回原文,并输出密码和原文。

解析:这一题解题的关键是合理运用ASCII码,我们只要知道当前要转换的字母是26个字母中的N个字母,再把26-N加到要起始字母上就可以了。

int main()
{
	char arr[9999] = { 0 };
	scanf("%s", &arr);
	int len = strlen(arr);
	for (int i = 0; i < len; i++)
	{
		if (arr[i] >= 'a' && arr[i] <= 'z')
		{
			arr[i] = 'a' + 'z' - arr[i];
		}
			
		else if (arr[i] >= 'A' && arr[i] <= 'Z')
		{
			arr[i] = 'A' + 'Z' - arr[i];
		}
			
	}
	printf("%s", arr);

	return 0;
}

运行结果:

C语言程序设计第五版谭浩强课后答案 第六章习题答案

 13. 编一程序,将两个字符串连接起来,不要用strcat函数

解析:字符串和数组不一样,不能使用 “ = ” 赋值。这里提供两个思路:

1、创建数组,遍历赋值法:顾名思义,就是创建一个新的字符串,把原来的两个字符串遍历读取挨个赋值到新字符串中。

int main()
{
	char arr1[9999] = { 0 };
	char arr2[9999] = { 0 };
	char arr3[9999] = { 0 };
	printf("请输入第一串字符:>");
	scanf("%s", &arr1);
	int len1 = strlen(arr1);
	printf("请输入第二串字符:>");
	scanf("%s", &arr2);
	int len2 = strlen(arr2);
	for (int i = 0; i < len1; i++)
	{
		arr3[i] = arr1[i];
	}
	for (int i = 0; i < len2; i++)
	{
		arr3[len1 + i] = arr2[i];
	}

	printf("拼接后的字符:>%s", arr3);

	return 0;
}

运行结果:

C语言程序设计第五版谭浩强课后答案 第六章习题答案

 2、指针拼接法:指针法和数组遍历原理基本相似,也是遍历两个字符串把不等于 ‘\0’ 的值的地址挨个赋值到新字符串的地址上。

void my_strcat(char* arr1, char* arr2, char* p)
{
	int i = 0;
	for (; *arr1 != '\0';)
	{
		*p = *arr1;
		arr1++;
		p++;
	}
	for (; *arr2 != '\0';)
	{
		*p = *arr2;
		arr2++;
		p++;
	}
	*p = '\0';
	
}


int main()
{
	char arr1[9999] = { 0 };
	char arr2[9999] = { 0 };
	char arr3[9999] = { 0 };
	char* p = 0;
	p = arr3;
	printf("请输入第一串字符:>");
	scanf("%s", &arr1);
	printf("请输入第二串字符:>");
	scanf("%s", &arr2);
	my_strcat(arr1, arr2, p);
	printf("拼接后的字符:>%s", p);
	return 0;
}

运行结果:

C语言程序设计第五版谭浩强课后答案 第六章习题答案

14. 编写一个程序,对两个字符串s1和s2进行比较,如果s1 > s2,输出一个整数;若s1 = s2,输出0;若s1 < s2,输出一个负数。不要用strcpy函数。两个字符串用gets函数读入。输出的正数或负数的绝对值应是相比较的两个字符串相对应字符的ASCII码的差值。例如,“A”和“C”相比,由于”A” < “C”,应输出负数,同时由于‘A’与‘C’的ASCII码差值为2,因此应输出”-2″。同理:“And”和”Aid”相比较,根据第2个字符比较结果,“n”比”i”大5,因此应输出”5”。

解析:这题题目看着很复杂也很长,但实际上这题只是运用了ASCII的知识。运用循环语句将字符串中的字符挨个对比,如果两个相等则继续比较,如果两个不相等则进行相减,并将ASCII导出。

int main()
{
	int index = 0,ret = 0;
	char s1[9999] = { 0 };
	char s2[9999] = { 0 };
	printf("请输入第一串字符:>");
	gets(s1);
	printf("请输入第二串字符:>");
	gets(s2);
	
    //这里当s1[index] = s2[index]时,两个的差值应该是0,这里为了保证继续运行则对结果取非
	while (!(ret = s1[index] - s2[index]) && ('\0' != s1[index]) && ('\0' != s2[index]))
	{

		++index;

	}
	printf("返回值:>%d", ret);
	return 0;
}

运行结果:

C语言程序设计第五版谭浩强课后答案 第六章习题答案

15. 编写一个程序,将字符数组s2中的全部字符复制到字符数组s1中,不用strcpy函数。复制时,‘\0’也要赋值过去。’\0’之后的字符不复制。

解析:这题只是一个简单的的字符串赋值问题,和前面的13题一样,分两种方法:

1、创建数组遍历赋值法:创建一个新数组,把原来的字符串赋值到新数组;

int main()
{
	char arr1[9999] = { 0 };
	char arr2[9999] = { 0 };
	printf("请输入第一串字符:>");
	scanf("%s", &arr1);
	int len1 = strlen(arr1);

	for (int i = 0; i < len1; i++)
	{
		arr2[i] = arr1[i];
	}

	printf("复制后的字符串:>%s", arr2);

	return 0;
}

 运行结果:

C语言程序设计第五版谭浩强课后答案 第六章习题答案

2、 指针法:遍历字符串把不等于 ‘\0’ 的值的地址挨个赋值到新字符串的地址上。

void my_strcat(char* arr1, char* p)
{
	int i = 0;
	for (; *arr1 != '\0';)
	{
		*p = *arr1;
		arr1++;
		p++;
	}

	*p = '\0';
	
}

int main()
{
	char arr1[9999] = { 0 };
	char arr2[9999] = { 0 };
	char* p = 0;
	p = arr1;
	printf("请输入第一串字符:>");
	scanf("%s", &arr1);
	my_strcat(arr1, p);
	printf("复制后的字符串:>%s", p);
	return 0;
}

运行结果:

C语言程序设计第五版谭浩强课后答案 第六章习题答案

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/12325.html

(0)
上一篇 2024-03-14 16:45
下一篇 2024-03-15 19:00

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注

关注微信