第三章 数组和字符串

来源:互联网 发布:为什么淘宝衣服很便宜 编辑:程序博客网 时间:2024/06/05 23:28

习题3-2  单词的长度(word)
输入若干个单词,输出它们的平均长度。单词只包含大写字母和小写字母,用一个或多个空格隔开。

分析:本题核心在于如何把一个个单词区别出来,从题中信息可知,单词之间由空格隔开,因此使用scanf函数读入字符串刚好能把单词区分出来

代码

#include "stdafx.h"#include "string.h"#define MAX 1024//单词最大长度姑且记为1024-1int _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;}


习题3-3  乘积的末3位(product)
输入若干个整数(可以是正整数、负数或者零),输出它们的乘积的末3位。这些整数中会混入一些由大写字母组成的字符串,你的程序应当忽略它们。提示:试试看,在执行scanf("%d")时输入一个字符串会怎样?

分析:本题核心为乘积的末三位。本题存在小陷阱,就是参与运算的整数之乘积有可能超过整数的表示范围,而我们知道末三位只与参加运算的每个整数的末三位有关,因此,我们先对输入的整数做处理(包括去除其中的大写字母),然后对每个整数取末三位参加运算,运算的结果也只取末三位。这样,此题的算法框架如下:
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){//若成功返回每行字符的个数,失败返回0char 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;}




0 0