今日无事,水篇教程
阅览了很多道江苏单招的C语言编程题,又看了看各校同学们的编程情况,突觉很多同学编程时候都没有一个完整的思路,特此写此文献给有需要的同学
算法
编程最重要的就是算法,这关系到你的代码是否清晰明了,当然我们单招班的同学不需要在意那么多,能解题的算法就是好算法,看了看,单招的学习范围与试题,其实内容是非常少的,理论上来说应该能挺轻松的学习与掌握
在此我就提出几个我认为较合适的算法:
一、赋值法(进阶)
曾经看到有同学直接将答案的值赋值给相应的数组或变量并返回一个具体的值来获取满分,很显然,这方法不可取,因为你技能高考的时候批卷老师会手动点开看你是不是直接赋值,虽然该方法不能用,但是我们能借用该方法的思想来进行一些取巧,即:面向结果编程,你知道答案,你也知道题目具体要输入数组 的格式,那么我们不一定需要做一些不必要的判断,而可以选择直接赋值(仅适用于题目数组或数值格式固定的情况),我们直接看例子
赋值法(例一)
字符串str中存放了一串表格数据,其中字母表示列,数字表示行
str=“ A5:D13 E23:G26 B6:D7 R1:T10”;
函数hl(int a[][2],char str[])的作用是:把表格行列数量存入a数组中,其中行数存入第0列,
列数存入第1列,函数返回表格数量
思路:因题目格式固定,第一个固定为列坐标,列坐标后固定为行坐标,之后为‘:’,列坐标,行坐标,由此格式可一次完成赋值操作,具体如下,可以先自己思考一下该怎么写
int hl(int a[][2],char str[])
{
int i,j,h1,h2,l1,l2,n=0;
for(i=0;str[i];i++)
{
if(isalpha(s[i])/*判断s[i]是否为英文字母
该处也可写isupper()判断是否为大写字母
如果禁用函数,可写(s[i]>='A'&&s[i]<='Z')*/
{
l1=s[i];//确定列1的坐标,注意这边l1存放的是第一个英文字母的ascll码
i++;//由题可知,字母后是数字
h1=0;
while(isdigit(s[i]))
h1=h1*10+s[i++]-48;//h1存放第一个行坐标,运行完成后s[i]值指向‘:’
i++;//使i的值指向第二个英文字母
l2=s[i++];//将第二列的值放入l2中,并使i指向第二行所对应的数字
h2=0;
while(isdigit(s[i]))
h2=h2*10+s[i++]-48;//h2存放第二个行坐标
//现在数值取完了,那就进行赋值
a[n][0]=l2-l1+1;
a[n++][1]=h2-h1+1;//n是用来计数的变量
}
}
return n;//返回表格数量
}
赋值法(例二)
上文说过,赋值法只能用于固定格式的题目中,那么什么是固定的格式呢,是只能像例一那样一板一眼的格式吗,其实不然,视角不能狭隘,思想需要开阔,我们来看这么一道题
函数 int fun(char s[],double a[])功能为:将字符串s中提取所有的正负号、
数字和小数点等组成的子串转换为实数存储到数组a中,函数返回提取的实数个数。
字符串s为"abc34.5y-3.8-.03hh-a125-0.55ASgf-3#"
程序需要提取的实数为:
-0.5500 -0.0300 -3.8000 -3.0000 34.5000 125.0000
大家认为,这东西的格式固定吗,其实也是固定的,这是所谓的多格式结构
由此图可以看出,这其中的数值只需做三种判定
负号
小数点+数字
数字
负号决定数值的正负,小数点+数字决定小数部分,数字决定整数部分
将之赋值给要求数组,这称为赋值法
具体如下:
int fun(char s[],double a[]) {
/**********Program**********/
int i,j=0,k,f=1;
double s1=0,s2=0;//f为符号部分,s1是整数部分,s2是小数部分
for(i=0; s[i]; i++) {
if(s[i]=='-'&&(s[i+1]=='.'||isdigit(s[i+1])))//第一种情况:s[i]是负号且后面跟着的是数字或小数点
f=-1;
if(isdigit(s[i])) { //第二种情况:s[i]是数字
s1=0;
while(isdigit(s[i]))
s1=s1*10+s[i++]-48;
i--;//上面的循环i++会多加一次,将之减去
}
if(s[i]=='.'&&isdigit(s[i+1])) { //第三种情况:s[i]是小数点且后面是数字
s2=0;
k=1;
i++;
while(isdigit(s[i]))
s2=s2+(s[i++]-48)*pow(0.1,k++);
i--;
}
if(isdigit(s[i])&&((s[i+1]!='.'&&s1!=0)||s2!=0)) { //数值提取完成的情况,将之赋值给数组,自己数值带进去试试就懂了
a[j++]=f*(s1+s2);
s1=0;
s2=0;
f=1;
}
}
return j;
/********** End **********/
}
二、分解法
所谓分解法,顾名思义,就是把题目拆分,使之成为我们所熟悉的各种程序段,我们把这些程序段拼起来,那么一段程序也就写好了
我研究了几套试题,得出了以下几个常用程序段:
矩阵转置
进制转换
在字符串中读取数据
数值查询
左移右移
计数
排序