习题3-2 单词的长度(word)
输入若干个单词,输出它们的平均长度。单词只包含大写字母和小写字母,用一个或多个空格隔开。
分析:本题核心在于如何把一个个单词区别出来,从题中信息可知,单词之间由空格隔开,因此使用scanf函数读入字符串刚好能把单词区分出来
代码:
#include "stdafx.h" #include "string.h" #define MAX 1024//单词最大长度姑且记为1024-1 int _tmain(int argc, _TCHAR* argv[]) { char buf[MAX]; int cnt=0,len=0,tlen=0; while(scanf("%s",buf)==1){ len=strlen(buf); // printf("len=%d\n",len); tlen+=len; cnt++; } printf("%d %d %.2lf\n",tlen,cnt,(double)tlen/cnt); return 0; }
while(cin>>a){ 处理a, 取a的末三位, product=product*a%1000; }
#include "stdafx.h" #include "string.h" int parseStrToInt(char *buf) { int a;//存储解析出来的整数 int len,base; int i,j; len=strlen(buf); j=0; for(i=0;i<len;i++){ if(!(buf[i]>='A' && buf[i]<='Z')){ buf[j++]=buf[i]; } } buf[j]='\0'; len=strlen(buf); a=0; for(i=0;i<len;i++){ base=1; for(j=0;j<len-i-1;j++){ base*=10; } a+=base*(buf[i]-'0'+0);//将相应字符转化为整数的方法:buf[i]-'0'+0 } //printf("a=%d\n",a); return a; } int _tmain(int argc, _TCHAR* argv[]) { char buf[12]; int a,product=1; while(scanf("%s",buf)==1){ a=parseStrToInt(buf); a%=1000; product=(product*a)%1000; } printf("%d\n",product); return 0; }
习题3-4 计算器(calculator)
编写程序,读入一行恰好包含一个加号、减号或乘号的表达式,输出它的值。这个运算符保证是二元运算符,且两个运算数均为不超过100的非负整数。运算数和运算符可以紧挨着,也可以用一个或多个空格、TAB隔开。行首末为均可以有空格。提示:选择合适的输入方法可以将问题简化。
分析:本题的核心是输入。题中已明确提出应该选择合适的输入方式,我们知道当使用scanf函数输入整数时,遇非整数则停止接受。因此我们使用scanf接受两个整数,对运算符做单独处理
代码:
#include "stdafx.h" int _tmain(int argc, _TCHAR* argv[]) { int x,y; double result; char op; scanf("%d",&x); while(scanf("%c",&op)==1){ if((op=='+') || (op=='-') || (op=='*') || (op=='/')) break; } scanf("%d",&y); switch(op){ case '+': result=x+y;break; case '-': result=x-y;break; case '/': result=(double)x/y;break;//题中表明x,y均为非负整数 case '*': result=x*y;break; } printf(op=='/' ? "%lf\n":"%.0lf\n",result); return 0; }
习题3-5 旋转(rotate)
输入一个n*n字符矩阵,把它左转90度后输出。
分析:本题核心是交换,即把矩阵的行列进行交换,但是注意交换的时候每行每列的开始为i,i,也就是说每行从第i行的第i列开始交换。算法也很简单,1.获得矩阵(我这里从文件中读取矩阵)。2.旋转。3.打印
代码
#include "stdafx.h" #include "stdio.h" #define MAX 10//假设每行最多10个字符 void print(char buf[][MAX],int size) {//输出 int i,j; int flag=0; for(i=0;i<size;i++){ for(j=0;j<size;j++){ printf(flag++ ? " %c":"%c",buf[i][j]); } flag=0; printf("\n"); } } int input(char (*buf)[MAX],const char *fileName) {//若成功返回每行字符的个数,失败返回0 char c; int i=0,j=0,cnt=0;//cnt表示每行有多少个字符 FILE *fin=fopen(fileName,"rb");//data.in文件每行最多10个字符,最多10行,行数与每行字符数相等 if(fin){ while(fscanf(fin,"%c",&c)==1){ if(c!='\n' && c!=' '){ buf[i][j++]=c; } if(c=='\n'){ i++; j=0; } } cnt=i+1; fclose(fin); return cnt; }else{ return 0; } } void rotate(char (*buf)[MAX],int size) {//旋转 int i,j; char tempC; for(i=0;i<size;i++){ for(j=i;j<size;j++){ tempC=buf[j][i]; buf[j][i]=buf[i][j]; buf[i][j]=tempC; } } } int _tmain(int argc, _TCHAR* argv[]) { char buf[MAX][MAX]; char c,tempC; int i=0,j=0,cnt=0;//cnt表示每行有多少个字符 cnt=input(buf,"data.in"); if(cnt){ print(buf,cnt); printf("------------------------\n"); rotate(buf,cnt); print(buf,cnt); }else{ printf("请准备好data.in文件!\n"); } return 0; }
习题3-6 进制转换1(base1)
输入基数b(2<=b<=10)和正整数n(十进制),输出n的b进制表示。
分析:除k取余法
代码:
#include "stdafx.h" int _tmain(int argc, _TCHAR* argv[]) { int b,n,x; int i=0; int buf[sizeof(int)*8];//整数最多的bit数 scanf("%d%d",&b,&n); while(n!=0){ x=n%b; buf[i++]=x; n/=b; } while((--i)>=0){//逆序输出 printf("%d",buf[i]); } printf("\n"); return 0; }
习题3-7 进制转换2(base2)
输入基数b(2<=b<=10)和正整数n(b进制),输出n的十进制表示。
分析:算法很简单,就是二进制转十进制的算法。本题核心在于如何拆解正整数n,本人使用的方法把正整数当做字符串处理,使用scanf("%s")存入buf字符数组中,字符数组的大小当为sizeof(n)*8+1(如果b=2即二进制时,若整数为4个字节,则buf为32+1即‘\0’).
代码:
#include "stdafx.h" #include <string.h> #define MAX sizeof(int)*8+1//最长位数 +1是因为末尾应有'\0' int getBase(int m,int b) {//参数m表示乘方的幂,b表示进制 int i,base=1; for(i=0;i<m;i++){ base*=b; } printf("base=%d\n",base); return base; } int _tmain(int argc, _TCHAR* argv[]) { int b; int value=0,len,base; int i; char buf[MAX];//最长位数,超出长度不做处理 scanf("%d%s",&b,buf); printf("buf=%s\n",buf); len=strlen(buf); for(i=0;i<len;i++){ base=getBase(len-1-i,b); value+=(buf[i]-'0'+0)*base; } printf("%d\n",value); return 0; } //2 11111111111111111111111111111110
习题3-8 手机键盘(keyboard)
输入一个由小写字母组成的英文单词,输出用手机的默认英文输入法的敲键序列。例如要打出pig这个单词,需要按1次p,3次i,(稍作停顿后)1次g,记为p1i3g1(显然,书中这部分描述存在明显的错误,应以这里的描述为准)。
分析:本题算法框架很简单,输出每个字符极其对应的位置。本题核心在于如何找到各个字母需要的按键次数,所以本题的关键在如何组织手机键盘,我的做法是用一个数组记录各个字母需要按键的次数:int key_times[26]={1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,4,1,2,3,1,2,3,4};key_times下标为26个英文字母的序号,如a为0,b为1,c为2,其值对应需要按键的次数。
代码
#include "stdafx.h" #include "string.h" #define MAX 1024+1//姑且认为最长单词长度为1024 int key_times[26]={1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,4,1,2,3,1,2,3,4};//key_times下标为26个英文字母的序号,如a为0,b为1,c为2,其值对应需要按键的次数 int _tmain(int argc, _TCHAR* argv[]) { int i,pos; char buf[MAX]; scanf("%s",buf); for(i=0;i<strlen(buf);i++){ pos=buf[i]-'a'+0; printf("%c%d",buf[i],key_times[pos]); } printf("\n"); return 0; }