zoukankan      html  css  js  c++  java
  • C 2014年笔试题

    1、指出程序中的错误,说明原因并修正

    1.1

    int *p,*q;
    p=malloc(sizeof(int)*20); 
    q=malloc(sizeof(int)*10);
    …
    q=p;
    …
    free(p);
    free(q);
    

    分析:

    错误1,q原本储存一片int类型的内存区域的地址,在没有释放这片地址时就修改了q的内容,使这片区域无法收回,导致内存泄漏

    错误2,p与q指向同一片内存区域,在使用free(p)后该内存区域已经释放,不能再free一遍。改正:将free(q)放在q=p前面(改正有多种说法,这里选择其中一种)


    1.2

    //交换字符串
    void swap(char *p, char *q)
    {
    	char *temp; //p、q所指的值的交换
    	*temp=*p;
    	*p=*q;
    	*q=*temp;
    }
    

    分析:该代码首先创建了形参p和q接受两个char类型的地址,在代码内部交换的这两个形参的内容,没有对外界产生任何影响。

    该代码的修改如下:

    void swap(char *p, char *q)
    {
    	char temp[100];
    	strcpy(temp,p); //strcpy函数:复制字符串
    	strcpy(p,q);
    	strcpy(q,temp);
    }

    2、简答题

    2.1 arr为整型数组,N为数组长度,enumb为整型变量,下列函数负责找出arr数组中等于enumb的元素所在位置。指出程序的三种异常,并说明原因。

    for(i=N-1;arr[i]!=enumb;--i)
      printf(“%d”,i);
    

    分析:

    首先for循环后面应该有分号,否则每次循环都有输出。

    其次如果arr数组中没有enumb,i就会变为负号,数组溢出。

    最后,若i一直减小,i会减小直到溢出。


    2.2  if(B) s1 else s2;是什么结构?使用显示结构语言该如何表示?并标出条件跳转和强制跳转

     分析:条件分支结构

    if(b) goto L1;//条件跳转
    goto L2;//强制跳转
    L1:	s1
    L2:     s2

    2.3 C语言中,常量存储在哪里?静态局部变量和静态全局变量存储在哪里?

    分析:常量存储在常量区,静态局部变量和静态全局变量存储在全局数据区。


    3填空题

    3.1 下面程序是对链表进行选择排序,填上空缺的部分

    list selectsort(list head){
    	list p = (struct node*)malloc(sizeof(node));
    	p->next = head;
    	head = p;//新建一个头结点
    	p = head->next;
    	list k = head, q = head;
    
    	while (p->next)
    	{
    		q = p->next;
    		k = q;  //k记录最小值位置
              //找到最小元素位置 while (q) { if (q->data < k->data) { k = q; } q = q->next; }
              //交换元素位置 if (p->next != k) { int r = p->next->data; p->next->data = k->data; k->data = r; } p = p->next; //填空一 } p = head; head = head->next; //填空二 free(p); //释放头结点 return head; //填空三 } 

    3.2 速排序法求某个数组前n个元素第k大的数

    int find_k(int *a, int n,int k) {
    	int i, j, t;
    	int low = 0,high = n - 1;
    	do {
    		i = low; j = high; t = a[low];
    		do {
    			while (a[j]>t) j--;
    			while (a[i]<t) i++;
    			if () 
    				swap(&a[j], &a[i]);
    			else
    				;
    		} while (i<j);
    		if (i == k)
    			return t;
    		if (i>k)
    			;
    		if (i<k)
    			;
    	} while (low<high);
    	;
    }
    

    分析:该题目使用快排划分的第一种写法,原理是利用每次快排划分之后总能确定一个元素的最终位置。该程序可能仍然存在问题,最大的数字是第0个。

    int find_k(int *a, int n,int k) { //从大到小排序
    	int i, j, t;
    	int low = 0,high = n - 1;
    	do {
    		i = low; j = high; t = a[low];
    		do {
    			while (a[j]<t) j--;
    			while (a[i]>t) i++;
    			if (i<j) 
    				swap(&a[j], &a[i]);
    			else
    				break;   //填空1
    		} while (i<j);
    		if (i == k)
    			return t;
    		if (i>k)
    			high = i - 1;   //填空2
    		if (i<k)
    			low = i + 1;     //填空3
    	} while (low<high);
    	return  a[low];   //填空4
    }
    

    3.3约瑟夫环问题 【见2015年】 

    int a[N + 1];
    int *p = a, i,j,k;
    for(i = 0; i<N + 1; i++)
        *(p+i) = i;
    ;
    ;
    for( i = 0; k != 1; p++)
    {
        if()
            p = a + 1;
        if()
            i++;
        if()
        {
            k--;
            i = 0;
            *p = 0;
        }
    }
    for(i = 0; i<N + 1; i++)
    {
        if()
            printf("%d
    ",a[i]);
    }
    

    分析:15年约瑟夫环区别

    int a[N + 1];
    int *p = a, i,j,k;
    //赋值0~N for(i = 0; i<N + 1; i++) *(p+i) = i; p = a + 1; //填空1 k = N; //填空2 for( i = 0; k > 1; p++) //k为剩下的人数 { if(p>a + N) p = a + 1; if(*p != 0) //碰到元素为0说明已经杀死,不参与计数 i++; //i报数 if(i == 3) { k--; i = 0; *p = 0; } }
    //打印输出 for(i = 0; i<N + 1; i++) { if(a[i] != 0) printf("%d ",a[i]); }

    3.4 完美乘法,若a*b=c,且abc中0~9的数字各出现一次,填写程序空缺处。

    int f[10],s[3];
    int n=0;
    for (int a = 12; a<999; a++)
    {
        int t = 0;
        //清空数字计数
        for (int x = 0; x<10; x++)
            f[x] = 0;
        for (int b = 345; b<9999; b++)
        {
            int c ;
            ;     //填空一
            s[0] = a;
            s[1] = b;
            s[2] = c;
            //计算abc中出现数字的次数
            for (int x = 0; x < 3; x++)
            {
                int y = s[x];
                while ()
                {
                    int t = y % 10;
                    f[t]++;
                    ;    //填空二
                }
            }
            //检查是否每个数都个出现一次
            for (int x = 0; x<10; x++)
            {
                if ()  ;   //填空三
            }
            if ()
                printf("%d*%d=%d
    ",a,b,c);
                ;//填空四 } }

    分析:

    int f[10],s[3];
    int n=0;
    for (int a = 12; a<999; a++)
    {
        int t = 0;
        //清空数字计数
        for (int x = 0; x<10; x++)
            f[x] = 0;
        for (int b = 345; b<9999; b++)
        {
            int c = a*b;
            s[0] = a;
            s[1] = b;
            s[2] = c;
            //计算abc中出现数字的次数
            for (int x = 0; x < 3; x++)
            {
                int y = s[x];
                while (y > 0)
                {
                    int t = y % 10;
                    f[t]++;
                    y = y / 10;
                }
            }
            //检查是否每个数都个出现一次
            for (int x = 0; x<10; x++)
            {
                if (f[x] != 1)  t++;
            }
            if (t == 0)
                printf("%d*%d=%d
    ",a,b,c);
            n++;			//统计循环次数
        }
    }
    

    4编程题

    4.1 将字符串逆转,函数原型void reverse(char *str);,要求空间复杂度为O(1)

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    void reverse(char *str)
    {
        int i = 0, len = strlen(str);
        for (; i < len / 2; i++)
        {
            char a = str[i];
            str[i] = str[len - i - 1];
            str[len - i - 1] = a;
        }
    }
    int main()
    {
        char ch[] = "helloworld";
        reverse(ch);
        printf("逆转后:%s",ch);
        return 0;
    }
     

    4.2 比较两个身份证字符串的生日大小。函数原型int isbothsame(char str1[19], char str2[19]);

    #include <stdio.h>
    #include <stdlib.h>
    
    int isbothsame(char str1[19], char str2[19])
    {
        int low = 6, hight = 13;
        while (low<hight &&str1[low] == str2[low])low++; //low记录不相同的位置
        return str1[low] - str2[low];  //负数表示str1的年长
    }
    int main()
    {
        char a[] = "412824199605281234",b[] = "41282519960825789x";
        if(isbothsame(a,b) < 0)
            printf("a年长!");
        else
            printf("b年长!");
        return 0;
    }

    4.3 计算1-x+x^2/2!-x^3/3!+…+x^n/n!  【见2015年】

    void main()
    {
        int n, x, j, i = 1;
        float sum = 1, k = -1;
        printf("Input n and x:
    ");
        scanf("%d %d", &n, &x);
        while (i <= n) {
            k = -1;
            for (j = 1; j <= i; j++) {
                k = -1*k*x;
            }
            for (j = 1; j <= i; j++) {
                k =  k/ j;
            }
            sum += k;
            i++;
        }
        printf("%f
    ", sum);
    }
    

    动态规划改进:

    void main()
    {
            int n,x,i=1;
            float sum = 1,k = -1;
            printf("Input n and x:
    ");
            scanf("%d %d", &n, &x);
            while (i <= n) {
                k = -1 * k*x / i;
                sum += k;
                i++;
            }
            printf("%f", sum);
    }

    4.4一个链表,找出其中数据项最大的结点,然后将其移动到链表尾部(结点node由整型data节点指针next构成不允许申请新的结点

    #include <stdio.h>
    #include <stdlib.h>
    
    typedef struct slist
    {
        int data;
        struct slist *next;
    };
    void movemax(struct slist *L)
    {
        struct slist *p = L->next, *pre = L, *max = p;
        //找到最大值的位置
        while (p)
        {
            if (p->data>max->data)max = p;
            pre = p;
            p = p->next;
        }
        //此时p指向NULL,pre指向最后一个结点
        //最大值和最后一个节点交换
        int temp = pre->data;
        pre->data = max->data;
        max->data = temp;
    }
    int main()
    {
        //建立单链表【尾插法】
        int a[] = {1,4,7,8,5,2,9,6,3};
        struct slist *p,*head = (struct slist*)malloc(sizeof(struct slist));
        head ->next = NULL;
        int i;
        p = head;
        for(i = 0;i < 9;i++)
        {
            struct slist *node = (struct slist*)malloc(sizeof(struct slist));
            node ->data = a[i];
            node ->next = p ->next;
            p ->next = node;
            p = node;
        }
        printf("找到最大值后移:
    ");
        movemax(head);
        //输出
        p = head ->next;
        while(p != NULL)
        {
            printf("%d	",p ->data);
            p = p->next;
        }
        return 0;
    }
  • 相关阅读:
    LeetCode--Reorder List
    LeetCode--Combination Sum
    LeetCode--Binary Tree Level Order Traversal
    LeetCode--Plus One
    第五届蓝桥杯决赛CC++B组——生物芯片
    第五届蓝桥杯决赛CC++B组——Log大侠
    第五届蓝桥杯决赛CC++B组——出栈次序
    1098 均分纸牌 ——http://codevs.cn/problem/1098/
    1294 全排列——http://codevs.cn/problem/1294/
    1501 二叉树最大宽度和高度——http://codevs.cn/problem/1501/
  • 原文地址:https://www.cnblogs.com/pam-sh/p/12585160.html
Copyright © 2011-2022 走看看