一轮,笔试加测评
测评还是那个老题库,感觉都做了好几遍了。。
记录一下笔试的知识点。
1.指针步长:这个博客的最后一个知识点
2.边界对齐,前面刚对这个知识进行过记录,但是记的不详细,这里再记录的详细些。
分为两大部分;
1)没有#pragma pack的情况,需要遵循三个原则。
原则1、普通数据成员对齐规则:第一个数据成员放在offset为0的地方,以后每个数据成员存储的起始位置要从该成员大小的整数倍开始。
原则2、结构体成员对齐规则:如果一个结构里有某些结构体成员,则该结构体成员要从其内部最大元素大小的整数倍地址开始存储。(struct a里存有struct b,b里有char,int,double等元素,那b应该从8的整数倍开始存储。)
原则3、结构体大小对齐规则:结构体大小也就是sizeof的结果,必须是其内部成员中最大的对齐参数的整数倍,不足的要补齐。
补充:如果数组作为结构体成员,比如:char a[3]。它的对齐方式和分别写3个char是一样的,也就是说它还是按1个字节对齐。
2)有#pragma pack的情况。
#pragma pack(1)意思就是按照1字节对齐。后面是几就是按照几字节对齐。
这篇博客讲的比这里还好。
这篇博客中间对结构体的位域做了详细介绍。
3.是一道算法题。M(M<1000000)个数字中取前N(N<M)个大的数。
我当时用的优先级队列,不知道能不能这么多的数。
利用快排的思想如下:
#include<iostream>
using namespace std;
int a[1000000];
void swap(int& a, int& b)
{
int temp;
temp = b;
b = a;
a = temp;
}
void QuickSort(int a[], int s, int e, int m) //a[],0,n-1,m
{
if (s >= e)
return;
int k = a[s];
int i = s, j = e;
while (i != j)
{
while (j > i&& a[j] > k)
j--;
swap(a[i], a[j]);
while (j > i&& a[i] < k)
i++;
swap(a[i], a[j]);
}
//快排的思想,走一遍。然后看看右边的较大的数是否是m个。
int b = e - j; // 判断右边大的数有几个.
if (m > b) // 若小于m个,在左边再取m-b个
{
QuickSort(a, s, i, m - b); return;
}
if (m < b) // 若大于m个,在右边重新取m个
{
QuickSort(a, j + 1, e, m); return;
}
}
int main()
{
int m, n;
cin >> n >> m;
if (n < 0) { return -1; }
else if (m > n) { return -2; }
else {
for (int i = 0; i < n; i++)
cin >> a[i];
QuickSort(a, 0, n - 1, m);
for (int i = n - 1; i >= n - m; i--)
cout << a[i] << " ";
return 0;
}
}
得牛客网大佬指点:
快排的时间复杂度在
,
如果使用冒泡排序,部分排序的时间复杂度为
,
如果使用小根堆,时间复杂度是
。
int main()
{
int n = 0;
int m = 0;
cin >> n >> m;
vector<int>vec;
for (unsigned int i = 0; i < n; ++i)
{
int n1 = 0;
cin >> n1;
vec.push_back(n1);
}
priority_queue<int, vector<int>, greater<int>> minHeap; //建立最小堆
//注意:最小堆要加上greater<int>
//其实,优先级队列的底层就是堆。
//greater<int>表示数字大的优先级小。
for (unsigned int i = 0; i < m; i++)
{
minHeap.push(vec[i]); //push的时间复杂度是O(log n)
}
for (unsigned int i = m; i < n; ++i)
{
//遍历判断容器中剩余的每个数与堆顶元素的大小
//若大于堆顶元素 则把堆顶元素出堆 把该元素入堆
if (vec[i] > minHeap.top())
{
minHeap.pop(); //push和pop操作的复杂度是O(log n).
minHeap.push(vec[i]);
}
}
//这个循环的时间复杂度是O(n*log m)
while (!minHeap.empty())
{
//打印小根堆里边的m个最大的数
cout << minHeap.top() << " ";
minHeap.pop();
}
cout << endl;
return 0;
}
哎,笔试没过。收到消息了。下次再接再厉。