一、删除数组指定元素
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来存储新的数据序列了,唯一的做法就是在原数组上操作。