第三十篇,C++面经之手写代码(四)

本文介绍了四个C++代码示例,包括删除数组指定元素、互模求最大公约数、判断大小端以及检测素数的方法。这些代码展示了如何在有限的空间复杂度下进行高效的操作,如数组元素的移除和替换,以及数值计算的基本算法。
摘要由CSDN通过智能技术生成

一、删除数组指定元素

void func(int a[], const int size, const int k)
{
    int count = 0;
    for (int i = 0; i < size; i++)
    {
        if (a[i] == k)
            count++;
        else
            a[i - count] = a[i];
    }
}

删除数组指定元素,并用后续元素补位。
a为待操作数组,size为数组长度,k为指定的待删除元素,该元素在数组a中可实际存在也可不存在,这段代码都可处理。
关键在于count的妙用,表面意思是在a中找到了几个k,更深一层的作用在于补位操作,由于是数组,找到k后所谓的删除操作也不能把这块内存抹去或delete,只能是用其它元素来占位、补位,count就起到了告诉后续元素往前移动几步的补位操作。

二、互模求最大公约数

int gcd(int a, int b) // 互模求最大公约数
{
    while (b != 0)
    {
        int tmp = a % b;
        a = b;
        b = tmp;
    }

    return a;
}

求a和b的最大公约数,查了一下叫什么“互模”法,思考之后原理大致是理解了。
互模算法利用了两个数最显而易见的特征,即必然一个大一个小,鉴于求最大公约数的目的,大数中包含小数整倍数的部分是不影响计算的,所以把它求模舍去,这样不仅简化运算还是运算中的步骤,利用可求模这一点,如此循环往复之后,最后使得求模为0的部分即为a和b最大的公共部分,即最大公约数。

三、判断大小端

判断当前设备是大端序还是小端序,大端序返回true小端序返回false。

bool isBigEdn() {
    unsigned short a = 0x1234;
    unsigned char bytes[2];
    memcpy(bytes, &a, 2);
    if (bytes[0] == 0x12)
        return false;
    else
        return true;
}

可参见之前博文里对大小端的描述。
代码中的a可用2字节也可用4字节、8字节,关键是要多字节不能单字节,因为涉及到顺序则必然不能是单个。

四、判断素数

bool isPrime(int n)
{
    int i = 0;
    for (i = 2; i * i <= n; i++)
    {
        if (n % i == 0)
        	return false;
    }
    return true;
}

素数也叫质数,它的因数只有1和它自身,或者说它只能分解为1和它自身的乘积,否则称为合数。
这段代码的原理暂没理解透,不过是可以背过的。

五、删除数组重复元素

int removeDuplicates(int A[], int n)
{
    int key = A[0];
    int count = 0;
    for (int i = 1; i < n; i++)
    {
        if (A[i] == key)
            count++;
        else
        {
            A[i - count] = A[i];
            key = A[i];
        }
    }

    return n - count;
}

这个题和第一个题类比着看,不指定删除哪一个,而是让你自己去找,找到重复且连续的并全部删除,且后续元素往前补位,返回剩余元素数量。
和第一个题的共同点是都是有序数组(其实无序也没关系)、要求常数级空间复杂度;尤其这个对空间复杂度的要求,你就不能新开辟一个数组或者弄个std::vector来存储新的数据序列了,唯一的做法就是在原数组上操作。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值