优化反思

昨天的练习任务三,跟着老师重新敲了一遍,使用二分法来遍历数组,代码如下:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>

//在一个有序数组中查找具体的某个数字n。编写int binsearch(int x,int v[],int n);
//功能:在v[0]<=v[1]<=v[2]<=...<=v[n-1]的数组中查找x。
int main()
{
	int arr[] = {1,2,3, 4,5,6,7,8,9,10};
	int k = 20;
	int sz = sizeof(arr)/sizeof(arr[0]);
	int right = sz -1;
	int left = 0;
	while(left <= right)
	{
		int mid = (right+left)/2;
		if(arr[mid] < k)
		{
			left = mid +1;
		}
		else if(arr[mid] > k )
		{
			right = mid -1;
		}
		else if(arr[mid ==k])
		{
			printf("找到目标元素,下标为%d\n",mid);
			break;
		}
	}
	if(left > right)
		printf("没有找到该元素\n");
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.

二分法用于遍历查询有序数组比根据下标逐个遍历效率要高,逐个完全遍历时间复杂度为O(n),二分法的时间复杂度为O(log2n)。

二分法的思路是,设置分别在数组的两端设置左下标和右下标,取两个下标的平均值作为中间下标,比较中间下标对应的数组元素与我们所要查找的元素的大小关系,若中间下标对应的数组元素大于我们所要查找的元素,说明目标元素在中间下标的左侧,此时将右下标更新为中间下标减一,反之若中间下标对应的数组元素小于我们所要查找的元素,说明目标元素在中间下标的右侧,此时将左下标更新为中间下标加一。如此循环判断,逐渐向目标元素逼近,当查找到目标元素时,中间下标此时对应的就是目标元素,即可跳出循环。若整个数组中压根没有目标元素,左右下标逼迫到相邻位置,下一步二者就会由于判断不到相等发生位置交换,这时左下标会大于右下标,我们可以借此现象来判断是否数组中没有目标元素。

任务4:编写代码,演示多个字符从两端移动,向中间汇聚。

唯一需要注意的就是字符型数组在长度上要注意甄别是否算了\0,代码如下:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>

int main()
{
	char arr1[] = "welcome to China!!!!!";
	char arr2[] = "#####################";
	int left = 0;
	int right = strlen(arr1)-1;
	while(left <= right)
	{
		arr2[left] = arr1[left];
		arr2[right] = arr1[right];
		printf("%s\n",arr2);
		left++;
		right--;
	}
	return 0;
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.

运行结果:

8.1C语言学习日志_练习

任务5:编写代码实现,模拟用户登录情景,并且只能登录三次。(只允许输入三次密码,如果密码正确显示登录成功,如果三次均输入错误,则退出程序)。

根据老师实现的代码:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>

int main()
{
	int i = 0;
	char pwd[20]={0};
	for(i=0;i<3;i++)
	{
		printf("请输入密码:");
		scanf("%s",pwd);
		if(strcmp(pwd,"123456")==0)//==不能用来比较两个字符串是否相等,要用库函数strcmp(字符串1,字符串2)
		{
			printf("登录成功!\n");
			break;
		}
		else
		{
			printf("密码错误!\n");
		}
	}
	if(i == 3)
	{
		printf("密码错误3次,退出程序\n");
	}
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.

运行结果:

8.1C语言学习日志_练习_02

在实际操作的过程中,我尝试在定义数组pwd的时候不指定长度,此时无法达到题目要求,当我输入错误的密码的时候循环只会执行一次就直接跳出循环结束程序,明明i的值并没有达到跳出循环的要求,百思不得其解,可能是字符型数组定义的规定吗