C语言笔试题小记

题目一

问题:
编码完成下面的处理函数。 函数将字符串中的字符*到串的前部分,前面的非*字符后移,但不能改变非*字符的先后顺序,函数返回串中字符*的数量。 如原始串为:ab**cd**e*12, 处理后为*****abcde12,函数并返回值为5
(要求使用尽量少的时间和辅助空间)


思路讲解:

  1. 第一步,要构造一个交换函数,可以交换两个指针指向的内容;
  2. 构造函数主体,首先创建两个指针指向字符串末尾,控制两个指针向前遍历,其中一个指针始终指向最后一个*,另一个指针始终指向最后一个*前面的第一个非*字符,调用第一步的交换函数,交换两个指针指向的内容,就可以把*前移。

C语言代码

#include "stdio.h"
#include "string.h"

//指针内容交换函数
void exchange_str(char* p, char* q){
    char temp = *p;
    *p = *q;
    *q = temp;
}

//功能函数主体
int sort(char* str ){
	int length = strlen(str);
    char* s1 = str+length-1;
    char* s2 = str+length-1;
	
	//在最后一次交换函数执行后,整个字符串已经完成,此时s2指向最后一个*,
	//由于s2前面没有非*字符,所以s1会自己自减到字符串首地址的前一个地址,
	//所以以此来判断任务完成
    while (s1 > str){
		//s2始终指向最后一个'*'
        while(*s2 != '*')
            s2--;
        s1 = s2-1;
        
		//s1始终指向s2前面的第一个非'*'字符
        while(*s1 == '*')
            s1--;
                        
        exchange_str(s1,s2);
    }
    return s2-s1;
}

int main(void)
{

    char str[] = "ab**cd**e*12";

    int num = sort(str);
    printf("%d\n",num);
    printf("%s\n",str);

    while(1);
    
    return 0;
}

运行结果
在这里插入图片描述


题目二

问题:
两个按从小到大排好序的数组,构造一个函数高效得判断这两个数组中是否存在相同的数字。


思路讲解:
题目已经提供了两个排好序的数组,不需要遍历整个数组,只需要取两个数组的首地址,让指向内容小的指针自增,去追赶指向内容大的指针,在这个过程中如果两个指针指向内容相等,则有相同的值,整个过程结束还没有说明没有相同的值。


假如一个数组长度为5,另一个为10,传统遍历要执行5*10=50次,这个方法最多遍历10+5=15次.

C语言代码

#include "stdio.h"
#include "stdbool.h"

bool have_same(int* a, int* b, int a_len, int b_len){
	int* p ,* q;		//定义两个指针变量,作为监视哨 
	p = a;
	q = b;
	int* b_end = b + b_len;
	int* a_end = a + a_len;
	
	while(p < a_end && q < b_end){		//防溢出
		if(*p < *q){
            p++;
        }
        else if(*p > *q){
            q++; 
        }
        else {
            return true;
        }
	}
   return false;
}


int main(void)
{

    int a[10] = {5,6,7,8,9,10,77,88,99,109};
    int b[5] = {0,1,2,3,11};

	int a_len = sizeof(a)/sizeof(int);
	int b_len = sizeof(b)/sizeof(int);

    if(have_same(a,b,10,5))
        printf("have same");
        
    else
        printf("no same");

   while(1);
}

运行结果在这里插入图片描述


题目三

问题:
对一已经从小到大排序好的数组使用二分法查找某一数字,找到并输出其下标,若找不到返回-1。


思路讲解:
二分法查找数字是很基本的算法,整个过程中需要三个量,首值、中值、末值的索引;通过循环不断判断目标值与中值的大小关系,改变首、中、末索引,直到找到或结束循环输出-1。

C语言代码

#include "stdio.h"


int dichotomy(int find_num, int* array, int len){
    int star,mid,end;
    star = 0;
    end = len-1;

    while(star <=end){
        mid = (end+star)/2;

        if(array[mid] > find_num){
            star = star;
            end = mid-1;
        }
        else if (array[mid] < find_num){
            end = end;
            star = mid+1;
        }
        else
            return mid;
    }
    return -1;
}


int main(void)
{

    int a[9] = {5,6,7,8,9,11,77,88,99};
    while(1){
        int find_num ;
        scanf("%d",&find_num);

        int b =dichotomy(find_num,a,9);
        printf("%d\n\n",b);
    }
    

运行结果在这里插入图片描述在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

握不住的草

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值