第十二周周总结

来源:互联网 发布:convertfrom json 编辑:程序博客网 时间:2024/06/11 10:51

这周我对指针进行了更加深入的学习,明白了指针和数组之间是有着千丝万缕的关系的,数组变量其实可以看作一个const的指针变量。而指针使用const会出现两种情况,第一种是对指针本身即指针所指的地址const(上面说数组可以看成cons的指针就是这种);第二种是对指针所指的变量const(这里所指变量const是指无法通过指针修改变量,但这个变量的本身其实是可以修改的)。第一种const是这样创建的  const int *p或者int const* p ,第二种则是 int *const p。当然,如果这样创建数组 const int *const p 则指针既不能更改地址,也不能修改指向地址上的值。

我们平时对于指针使用是比较少的,但是指针其实也是有一些妙用的。例如,它可以类似的是一个函数返回多个值,代码如下:

void minmax( int a[] , int len , int *min , int *max)

{

       int i ;

       *min =  *max = a[0];

       for( i = 0 ; i <= len - 1 ; i++){

              if( a[i] < *min ){

                      *min = a[i];

              }

              if( a[i] > *max ){

                      *max = a[i];

              }

       }

}

这样一个函数就能同时找出一个数组中的最大值和最小值。

这周除了指针以外,我还对算法进行了学习,但是因为C语言还没有学好,在算法的学习中也是遇到了不少麻烦,也并没有去接触一些难度大的算法,而是找了一些简单的算法题进行解答。

例如上次程序设计大赛上的最大子序列和问题,我当时是这样写的:

#include<stdio.h>

int main(void){

     int thissum,maxsum,i,j,N;

     scanf("%d",&N);
     int A[N];
     for( i = 0 ; i <= N - 1 ; i++)
     {
        scanf("%d",&A[i]);
     }

     maxsum = thissum = 0

     for( i = 0 ;  i <= N -1 ; i++){

           thissum = 0;

           for( j = 0 ; j <= N - 1; j++){

                 thissum += A[j];

                 if ( thissum > maxsum){

                         maxsum = thissum;

                  }

            }

      }      

       return 0;

}

很简单,就是将所有的连续子数列全部遍历一遍,找出最大的序列。但是,这样写运算量会很大,当数组元素到一定大小后就会导致程序崩溃,我参考资料后看到了这样一个代码,将计算量降到了最小。

#include<stdio.h>
int main(){
    int N,i,maxsum,thissum;
    scanf("%d",&N);
    int A[N];
    for( i = 0 ; i <= N - 1 ; i++)
    {
        scanf("%d",&A[i]);
    }
 thissum=maxsum=0;
 for( i = 0; i <= N - 1; i++ )
    {
  thissum += A[i];
  if(thissum > maxsum)
   maxsum = thissum;
  else if(thissum < 0 )
   thissum = 0;
 }
    printf("%d",maxsum);
    return 0;
}

这个算法的关键在于,当当前总和小于0时,就把0赋给当前总和,因为当前面的和为负,它势必会减小后面的数的总和,所以直接把前面的数全部舍弃,从下一个数开始。

在做算法题的时候,我也是遇到了不少的问题,因为一些看似简单的算法的题上,往往涉及很多强制的格式要求,例如:

#include<stdio.h>
int main(){
    int length,width,height,n,i;
    while(scanf("%d",&n) && n != -1){
        int a[n];
        char name[n][9];
        for( i = 0 ; i <= n-1; i++){
            scanf("%d %d %d",&length,&width,&height);
            a[i] = length*width*height;
            scanf("%s",&name[i]);
        }
        int max = 0,min = 250*n,x,y;
        for( i = 0 ; i <= n-1 ; i++){
            if(max <= a[i]){
                max = a[i];
                x = i;
            }
            if(min >= a[i]){
                min = a[i];
                y = i;
            }
        }
        printf("%s took clay from %s.\n",&name[x],&name[y]);
    }
    return 0;
}

这是在计蒜客上的题目,名字叫“泥塑课”,题目本身不难,但是敲出这串代码却是花费了我不少时间,先是去学习了字符串的知识,又去了解了while上的一个妙用,即这句代码 while(scanf("%d",&n) && n != -1)。

在例如:

#include<stdio.h>
int main(){
    long long a;
    while( (scanf("%lld",&a) ) != EOF){
        double x = 10000;
        while(x*x - a > 0.1 || x*x-a < -0.1){
            x = x - ( x*x - a ) / (2 * x) ;
        }
        printf("%d\n",(int)x);
    }
    return 0;
}

这是一个简单的用牛顿迭代法求根号x的算法,但是题目上要求的输出必须是去尾整数、EOF结束以及所能计算数字的大小却让我花费了大量的时间,先是去搜资料学习EOF文件结束符怎么使用,然后发现这题上不论用整型还是浮点型都无法得到题目要求的结果,因为整型会导致迭代时死循环,而浮点更是不行,于是又学习了如何强制转换变量的类型,最后在提交时,又发现有一组数据通过不了,想了一会才意识的这可能是数据太大,需要将 int 改为 long long int。

总之,通过这周对于对算法的学习,我不仅对算法有了初步了解,也是对解决算法题上的基础知识有了更好的掌握。