C语言学习回顾(1)

本次内容针对B站内C语言网课回顾

学习内容为while、for简单的循环语句与三道算法题目

首先直接列出这三道练习题:

1、在一个有序数组中找到某一个数;

2、编写代码,演示多个字符从两端移动,向中间汇聚

3、编写代码,模拟用户登录情景,并且只能登录三次,如果三次均错误,则退出程序


第一道题在学习中运用了多种解法,在老师进行优化之后,最终得出一种非常典型的“折半查找法”

#include

int main()
{
	int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
	int k = 7;
	int sz = sizeof(arr) / sizeof(arr[0]);
	int left = 0;
	int right = sz - 1;
	//此处注意一点,若将mid设置在while循环外,则会出现死循环
	//int mid =(left + right ) /2 ;
	while (left < right)
	{
		int mid = (left + right) / 2;
		if (arr[mid] < k)
		{
			left = mid + 1;
		}
		else if (arr[mid) > k)
	   {
	   right = mid - 1;
	   }
		else
		{
			printf("find it ,the number is :%d"\n",mid);
				break;
		}
	}
	if (left > right)
	{
		printf("can not find your aim number in here!\n");
	}
	return 0;
}

这是数据结构中经典的二分法算法,算是我们初学者学习C语言之后可以接触到的第一个“可能较高级”(不知道这样用词是否准确)的算法。

通过引入左右下标left\right的概念,在一个有序数列中逐步逼近查找值,值得一提的是,正如while语句中的判断条件一样:left

观察循环内的代码块不难发现,我们只需确定arr[mid]与k,也就是我们待找数的大小,逐次更改左或右下标的值,最终逼近,直至arr[mid] == k,这种情况出现,循环结束。

 为了方便自己回顾本次文章,趁热对循环代码块内一侧进行分析:

if ( arr[mid] > k )
{
   right = mid - 1 ;
}

如果中间标所指的数字比待找数字大,将中间值减去一,赋值给新的右下标。

C语言学习回顾(1)_第1张图片

通过这个图可以更直观的明白上述三行代码的含义,那么如此 当arr[mid] < k 也可以推出。在此便不赘述了。

另外在这里介绍我对于此题的第一印象解法,这也许叫“冒泡排序”?我不太明白专业名称:

int main()
{
	int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
	int k = 17;
	int i = 0;
	// 写一个代码,在arr数组中(有序的),找到7
	int sz = sizeof(arr) / sizeof(arr[0]); // sz就是数组的长度
	for (i = 0; i < sz; i++)
	{
		if (k == arr[i])
		{
			printf("find it , the number is :%d\n", i);
			break;
		}
	}
	if (i == sz)
	{
		printf("can't find it ");
	}
	return 0;
}

 这种一一比对最终确定待找数的方法思路非常简单,对于我们这样的初学者可能困难的只是如何将思路翻译成代码,希望自己多学多敲,共勉之!


第二道题是一种动画演示,利用循环进行一次游戏:

#include
#include
#include
#include
int main()
{
	//welcome to here!!!!!!!!!!
	//#########################
	//w#######################!
	//we#####################!!
	//wel###################!!!
	//....
	//....
	//welcome to here!!!!!!!!!!
	char arr1[] = "welcome to here !!!!!!!";
	char arr2[] = "#######################";
	int left = 0;
	// error:
	// int right = sizeof(arr1)/sizeof(arr1[0]) -1
	// for example here:
	// char arr[] = " abc ";
	// [a b c \0 ]
	//  1 2 3  4
	// 4-1 only can catch the wrong number
	// we should use 4-2 instead of 4-1
	int right = strlen(arr1) - 1; // or use the strlen 
	// tips: if you want to use the function "strlen" you should include the function library: 
	while (left <= right)
	{
		arr2[left] = arr1[left];
		arr2[right] = arr1[right];
		printf("%s\n", arr2);
		//每打印一次休息一秒
		Sleep(1000);
		system("cls");// 执行系统命令的一个函数 -cls  ---- 清空屏幕
		left++;
		right--;
	}

	printf("%s\n", arr2);
	return 0;
}

大家可以将这段代码复制出去看看效果,非常有意思

简单介绍一下这种方法,同样运用了左右下标的处理,每一跳将最左(或最右)的未出现字符弹出,预期实现效果就如主函数里的前几段注释。

值得一提的是,我们如何确定字符串的右下标呢?

第一道题中的right通过确定数列的总长度,再减一完成,但是再字符串中,所有字符串天然自带'\0'这个内容,如果只是sizeof减一,无法确定真正的右下标,这里给出两种解决方法

1、sizeof - 2

2、strlen - 1

在代码中,我举了一个例子,[a, b, c],可以参考!

在while循环中,将每次的arr1的左右下标赋值给arr2,就像挂涂层一样慢慢刮开,在循环的最后面将左下标+1,右下标-1,循环刮下一次。

为了增加代码的趣味性,添加了Sleep(1000);和system("cls");含义为每一秒进行一次循环,并清屏。

请注意,使用这上述两行代码必须添加相应的函数库。


最后一个代码非常简单,不作回顾啦,如果有像我一样的初学者看到此题,可以尝试改变代码内容,进行自己的diy!

#include
int main()
{
	char password[20] = { 0 };
	int i = 0;
	for (i = 0; i < 3; i++)
	{
		printf("please input your password here:");
		scanf("%s", password);
		if (strcmp(password, "123456") == 0) // 无法用 == 来比较两个字符串,只能用库函数strcmp进行
		{
			printf("login in your account!\n");
			break;
		}
		else
			printf("your password is wrong!\n");
	}
	if (i == 3)
	{
		printf("you can not try to login this account anymore!now the exe will exit!\n");
	}
	return 0;
}

 最后祝自己在C语言的学习上更上一层楼,各位也是

你可能感兴趣的:(c语言,算法)