• 一些笔试题笔记1


    总结一些常见的笔试题:

    最小公约数和最大公倍数:

    这个其实很简单,记住概念就可以了,我们利用辗转相除法计算:

    最大公约数:(摘自百度百科)

    一般地,如果求a和b的最大公约数(a>b),那么

    b|a时,得left(a,b
ight)=b,这里b|a表示b整除a,而b
mid a表示b不能整除,b
mid a时,设余数为r_1,根据整除的性质,有left(a,b
ight)=left(b,r_1
ight)r_1|b时,得

    left(b,r_1
ight)=r_1r_1
mid b时,设余数为r_2,于是left(b,r_1
ight)=left(r_1,r_2
ight)

    最小公倍数=两数的乘积/最大公约(因)数

    #include <stdio.h>
    void func1(int a, int b)//非递归实现
    {
    	int max, min, temp;
    	if(a > b) {max = a; min = b;}
    	else 	  {max = b; min = a;}
    
    	while( min != 0)
    	{
    		temp = min;
    		min = max%min;
    		max = temp;
    	}
    	printf("最大公约数 %d
    ",max);
    	printf("最小公倍数 %d
    ",(a*b)/max);
    }
    
    int func2(int a, int b)//递归实现
    {
    	if(a == 0)
    		return b;
    	else if(b == 0)
    		return a;
    	int max, min;
    	if(a > b) {max = a; min = b;}
    	else 	  {max = b; min = a;}
    
    	max = func2(min, max%min);
    	return max;
    }
    void main()
    {
    	int x , y, ret;
    	printf("please input two num:
    ");
    	scanf("%d %d",&x, &y);
    	func1(x,y);
    	ret = func2(x,y);
    	printf("最大公约数 %d
    ",ret);
    	printf("最小公倍数 %d
    ",(x*y)/ret);
    
    }


    2.字符串翻转问题

    这个太简单了,就不多说了

    #include <stdio.h>
    #include <string.h>
    void turn(char *s)
    {
    	int len = strlen(s), mid = len/2, i = 0;
    	while(i < mid)//此处不能相等
    	{
    		char temp = s[len-1-i];
    		s[len-1-i] = s[i];
    		s[i] = temp;
    		i++;
    	}
    }
    int main()
    {
    	printf("please input a string
    ");
    	char s[20];
    	gets(s);
    	turn(s);
    	printf("after turn, the string is:%s
    ", s);
    	return 0;
    }


    3.判断小端还是大端

    使用联合体,取低字节

    int main()
    {
    	union{
    		int x;
    		char c;
    	}u;
    	u.x = 1;
    	if(u.c == 1)
    		printf("little endian
    ");
    	else
    		printf("big endian
    ");
    	return 0;
    }


    4.给定一个字符串,翻转一些位数

    例如:给定abcdefg,翻转后变为:efgabcd,这个也不难,先全部翻转过来,再翻转一定的位数,再把这些位数后面的翻转

    #include <stdio.h>
    #include <string.h>
    
    void turn(char *s, int n)
    {
    	int len = n, mid = len/2, i = 0;
    	while(i < mid)
    	{
    		char temp = s[len-1-i];
    		s[len-1-i] = s[i];
    		s[i] = temp;
    		i++;
    	}
    }
    int main()
    {
    	char s[] = "abcdefg";
    	turn(s, strlen(s));
    	printf("after turn: %s
    ",s);
    	turn(s, 3);
    	printf("after turn: %s
    ",s);
    	turn(s+3,strlen(s)-3);
    	printf("after turn: %s
    ",s);
    	return 0;
    }


    5.两个线程交替输出1-10个数

    考察线程的基本知识,要能写出来

    #include <pthread.h>
    #include <stdio.h>
    
    struct X
    {
    	int data;
    	pthread_mutex_t lock;
    }x = {10,PTHREAD_MUTEX_INITIALIZER};
    
    void *func1(void *arg)
    {
    	pthread_mutex_lock(&x.lock);
    	while(x.data >= 1)
    	{
    		printf("int the thread1: %d
    ",x.data);
    		x.data--;
    		sleep(1);
    	}
    	pthread_mutex_unlock(&x.lock);
    }
    
    void *func2(void *arg)
    {
    	pthread_mutex_lock(&x.lock);
    	while(x.data >= 1)
    	{
    		printf("int the thread2: %d
    ",x.data);
    		x.data--;
    		sleep(1);
    	}
    	pthread_mutex_unlock(&x.lock);
    }
    
    void main()
    {
    	pthread_t ptid[2];
    	int *ret, j;
    	pthread_create(&ptid[0], NULL, func1, NULL);
    	pthread_create(&ptid[1], NULL, func2, NULL);
    	for(j = 0; j < 2; j++)
    		pthread_join(ptid[j], (void**)&ret);//等待线程的退出
    }

    注意头文件<pthread.h>和编译链接项 -pthread

    6.宏定义交换两个数

    有多种写法

    #include <stdio.h>
    
    #define SWAP(x, y) (x = x+y, y = x-y, x = x-y)
    #define swap(x, y) (x = x^y, y = x^y, x = x^y)//不会产生大数字溢出问题
    
    //带有换行的
    #define Swap(x, y)
    	x = x+y;
    	y = x-y;
    	x = x-y
    	
    void main()
    {
    	int x = 3, y = 5;
    	//SWAP(x, y);
    	//Swap(x, y);
    	swap(x ,y);
    	printf("x:%d  y:%d
    ",x, y);
    }


    7.全排列的实现

    全排列是一个比较复杂的算法,例如“123”的全排列,我们可以枚举出来是123,132,231,213,321,312,我们发现,每一个数都会排在开头,那么这是不是递归的思想,

    我们把每一个数放到开头,剩下的数再全排列一下,这样就是拿出1,全排列23,拿出2,全排列13,拿出3,全排列12,这样一分析就简单了

    但是有一个问题,例如:如果有这样的数:1223那怎么办呢?我们这样想,在把第2个2拿到第一个位置的时候,我们发现这个2前面已经有个2了,这样就重复了呀,

    怎么办呢?(好多2啊-_-!),这里我们就不把第二个2拿到第一个位置就是了,我们写了一个 is_swap函数在每次把数拿到第一个位置的时候判断了一下

    #include <stdio.h>
    #include <string.h>
    
    void swap(char *s, char *t)
    {
    	char temp = *s;
    	*s = *t;
    	*t = temp;
    }
    
    int is_swap(char *s, int begin, int end)
    {
    	int i;
    	for(i = begin; i < end; i++)
    	{
    		if(s[i] == s[end])
    			return 0;
    	}
    	return 1;
    }
    
    void all_rang(char *s, int m, int n)
    {
    	int i, j;
    	if(m == n)
    	{
    		static int i = 1;
    		printf("第%d个全排列是:%s
    ", i++, s);
    		return;
    	}
    
    	for(j = m; j <= n; j++)
    	{
    		if(is_swap(s, m, j))
    		{
    			swap(s+m,s+j);
    			all_rang(s, m+1, n);
    			swap(s+m, s+j);
    		}
    	}
    
    }
    void main()
    {
    	char s[10] = "1223";
    	all_rang(s, 0, strlen(s)-1);
    }

    关于二维数组的总结:

    #include <stdio.h>
    
    void main()
    {
        int a[4][4] = 
        {   
            {1,2,3,4},
            {50,60,70,80},
            {900,1000,1100,1200},
            {13000,14000,15000,16000}
        };  
    
        int (*p1)[4] = a;
        int (*p2)[4] = &a[0];
        int (*p3)[4] = &a[0][0];
        printf("%d  %d
    ",*(*p1+7), *(*(p2+1)-4));//这里是这种写法
    
        int *p6 = a;
        int *p5 = &a[0];
        int *p4 = &a[0][0];
        printf("%d
    ",*(p4+7));//这里是这种写法
    
        //int *(p7)[4][4] = a;
      //int *(p8)[4][4] = &a[0];
        //int *(p9)[4][4] = &a[0][0];
        //printf("%d
    ",*(p7+7));
    }
          

    这个在笔试中常考,记住只有两种写法,并且指针的运算在这两种写法上的区别



  • 相关阅读:
    《20170914-构建之法:现代软件工程-阅读笔记》
    《结对-贪吃蛇游戏-开发环境搭建过程》
    《结对-贪吃蛇游戏-设计文档》
    《自我介绍》
    对于软件工程的期望
    GIT的使用方法
    结对-贪吃蛇-需求分析
    团队-井字棋-需求分析
    团队-井字棋-成员简介及分工
    新的目标
  • 原文地址:https://www.cnblogs.com/keanuyaoo/p/3320261.html
Copyright © 2020-2023  润新知