本次内容针对B站内C语言网课回顾
学习内容为while、for简单的循环语句与三道算法题目
首先直接列出这三道练习题:
1、在一个有序数组中找到某一个数;
2、编写代码,演示多个字符从两端移动,向中间汇聚
3、编写代码,模拟用户登录情景,并且只能登录三次,如果三次均错误,则退出程序
第一道题在学习中运用了多种解法,在老师进行优化之后,最终得出一种非常典型的“折半查找法”
#include<stdio.h>
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<right 循环才能一直执行,进行逐步逼近。
观察循环内的代码块不难发现,我们只需确定arr[mid]与k,也就是我们待找数的大小,逐次更改左或右下标的值,最终逼近,直至arr[mid] == k,这种情况出现,循环结束。
为了方便自己回顾本次文章,趁热对循环代码块内一侧进行分析:
if ( arr[mid] > k )
{
right = mid - 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<stdio.h>
#include<string.h>
#include<Windows.h>
#include<stdlib.h>
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: <string.h>
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<string.h>
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语言的学习上更上一层楼,各位也是