《算法竞赛入门经典(第2版)》第三章笔记及思考题解

  • 数组的定义最好放在main函数的外面,只有放在外面的时候,数组才可以开的很大,放在main函数内,数组稍大就会异常退出。

  • #include memcpy(b,a,sizeof(int)*k):复制数组a的k个int型元素到数组b

    memset(a,0,sizeof(a)):将数组a清零

    memset()函数注意:

    1. memset()函数是按照字节进行替换,所以一般都用memset()函数进行清零操作。

      例:

      #include
      #include
      int main()
      {
          int a[5];
          memset(a,1,sizeof(a));
          printf("%d\n",a[0]);
      }
      
    2. 写成1字节(8位)的二进制是0000 0001,对于一个int型的变量是4字节,所以经过memset()函数,int型的量用二进制表示为0000 0001 0000 0001 0000 0001 0000 0001,转换为10进制就是我们的输出结果16843009.

    3. memset()函数的第三个参数是数组的长度,但是要注意的是单位是字节,所以一般情况下使用sizeof()函数不容易出错。

  • scanf("%s",s);遇到空白字符即会停止输入。

  • sprintf(buf,"%d%d%d%d%d",a,b,c,d,e);输出到字符串中,需要保证写入的字符串有足够的空间。

  • strlen(s)作用是获取字符串s的实际长度,返回的是结束标记之前的字符总数。

  • strchr(s,a)作用是在字符串s中查找字符a,若未查找到返回NULL

  • 输入字符串的方法

    方法一:

    使用fgetc(fin),它读取一个打开的文件fin,读取一个字符,然后返回一个int值,因为如果文件结束,fgetc将返回一个特殊标记EOF,并不是一个char。如果将其返回值强制转换为char,将无法把EOF与普通字符区分开。如果要从标准输入读取一个字符,可以使用getchar(),它等价于fgetc().
    **提示:**使用fgetc(fin)可以从打开的文件fin中读取一个字符。一般情况下应当检查它不是EOF后再将其转换为char。
    fgetc()和getchar()将读取下一个字符,包括空格和换行符,但是不同操作系统的回车换行符是不同的,Windows系统的换行符是”\r\n”,Linux是’\n’,MacOS是’\r’,在Windows系统下读取Windows文件时,会将’\r’舍弃,读取’\n’,而如果在Linux下运行相同的文件,会将’\r’’\n’都读取,所以应该尽量避免编写和操作系统差异性有关的文件。

    方法二:

    使用fgets(buf,maxn,fin),buf的声明是 char buf[maxn],也就是说fgets()可以读取maxn-1个字符没然后在结尾添加结束符’\0’,该函数遇到换行符’\n’,会停止输入,最后一个有效字符是‘\n’(以’\0’结尾)。

  • 头文件:ctype.h

    isalpha(ch):判断字符ch是否为字母

    isupper(ch):判断字符ch是否为大写字母

    islower(ch):判断字符ch是否为小写字母

    isdigit(ch):判断字符ch是否为十进制数字

    isprint(ch):判断字符ch是否为可打印字符(0x20~0x7E)

    上述函数,如果符合返回非0值,如果不符合则返回0.

    toupper() tolower()函数原型:

    int toupper(int c);
    int tolower(int c);
    

    将一个大(小)写字母转换为小(大)写字母,如果输入的字符不能转换的话,返回原字符。

  • 需要枚举的题目,可以尝试使用打表法解决。

  • 字符串概念:字典序

    字典序,是字符串在字典中的顺序。对于两个字符串,从第一个字符开始,当某一位置字符不同时,字符小的串字典序小,如果有一字符串已经没有字符了,较短的字符串字典序小。

思考题

题目1(必要的储存量):

数组可以用来保存很多数据,但在一些情况下,并不需要把数据保存下来。下面哪些题目可以不借助数组,哪些必须借助数组?请编程实现。假设输入只能读一遍。

  1. 输入一些数,统计个数。

    #include
    int main()
    {
        int n,count=0;
        while(scanf("%d",&n)==1)
        {
            count++;
        }
        printf("%d\n",count);
    }
    
  2. 输入一些数,求最大值、最小值和平均数

    #include
    int main()
    {
        int n,max,min,count=0,sum=0;
        if(scanf("%d",&n)==1)
        {
            max=n;min=n;count++;
            sum+=n;
        }
        while(scanf("%d",&n)==1)
        {
            if(n>max)max=n;
            if(n<min)min=n;
            sum+=n;
            count++;
        }
        double average=(double)sum/count;
        printf("max=%d,min=%d,average=%.4f\n",max,min,average);
    }
    
  3. 输入一些数,哪两个数最接近

    #include
    #include
    int num[10000];
    int main()
    {
        int n=0;
        while(scanf("%d",&num[n])==1)
        	n++;
        int a=num[0],b=num[1],dis=abs(num[0]-num[1]);
        for(int i=0;i<n-1;i++)
        {
            for(int j=i+1;j<n;j++)
            {
                if(abs(num[i]-num[j])<dis)
                {
                    dis=abs(num[i]-num[j]);
                    a=num[i];
                    b=num[j]:
                }
            }
        }
        printf("n1=%d,n2=%d,dis=%d\n",a,b,dis);
    }
    

    程序写的很烂,希望大佬们能够提些意见和建议,感激不尽♪(・ω・)ノ

  4. 输入一些数,求第二大的值

    #include
    int main()
    {
        int max,sec_max,n;
        scanf("%d",&max);
        scanf("%d",&n);
        if(n>max)
        {
            sec_max=max;
            max=n;
        }
        else
            sec_max=n;
        while(scanf("%d",&n)==1)
        {
            if(n>max)
            {
                sec_max=max;
                max=n;
            }
            if(n<max&&n>sec_max)
           		sec_max=n;
        }
        printf("%d\n",sec_max);
    }
    
  5. 输入一些数,求他们的方差

    #include
    int num[10000];
    int main()
    {
        int n=0,sum=0;
        double s=0,average;
        while(scanf("%d",&num[n])==1)
        {
            sum+=num[n];n++;
        }
        average=(double)sum/n;
        for(int i=0;i<n;i++)
        {
            s+=(average-num[i])*(average-num[i]);
        }
        printf("%.4f",s/n);
    }
    
  6. 输入一些数,统计不超过平均数的个数

    #include
    int num[10000];
    int main()
    {
        int n=0,sum=0,count=0;
        double average;
        while(scanf("%d",&num[n])==1)
        {
            sum+=num[n];n++;
        }
        average=(double)sum/n;
        for(int i=0;i<n;i++)
        {
            if(num[i]<=average)
            {
                count++;
            }
        }
        printf("%d",count);
    }
    

题目2(统计字符1的个数):

下面的程序意图在于统计字符串中字符1的个数,可惜有瑕疵:

#include
#define maxn 10000000+10
int main()
{
    char s[maxn];
    scanf("%s",s);
    int tot=0;
    for(int i=0;i<strlen(s);i++)
        if(s[i]==1)tot++;
    printf("%d\n",tot);
}

该程序至少有三个问题,一个导致程序无法运行,另一个导致及结果不正确,还有一个导致效率低下,找到他们并改正。

解答: 1. strlen()包含在头文件

​ 2.if(s[i]==‘1’) 或if(s[i]==49)

​ 3.maxn过大,s数组应该在main()函数外定义

你可能感兴趣的:(算法竞赛入门经典)