乐鑫科技春招在线笔试编程测试——以小见大
现在的编程测试都是比较有意思的,出题者设定一个有趣的背景,在这个背景下编写程序完成测试。
乐鑫科技的这次在线笔试有20条填空题,另外有两题在线编程题。今天就是以这两道题来分析怎么白板写程序。
ほら!
問題1:
解析: 线性回归方程的求解
好了有了这个公式,你能求出斜率k、截距b,这题就解完了。
上代码! 全部程序可直接上机运行
#include <iostream>
#include <math.h>
using namespace std;
#define N 10
double fsum(double *points, int pointLen,char a)
{
double sum_x = 0, sum_y = 0, sum_xx = 0, sum_xy = 0;
switch(a){
case 'x': //sum(x)
{
for(int i = 0; i<pointLen; i+=2){
printf("%.1f\t",*(points+i));
sum_x += *(points+i);
}
cout<<sum_x<<endl;
return sum_x;
break;
}
case 'y': //sum(y)
{
for(int j = 1; j<=pointLen; j+=2){
printf("%.1f\t",*(points+j));
sum_y += *(points+j);}
cout<<sum_y<<endl;
return sum_y;
break;
}
case '1': //sum(x^2)
{
for(int tt = 0; tt<=pointLen; tt+=2){
//printf("%.1f\t",*(points+tt));
sum_xx += *(points+tt) * (*(points+tt));}
return sum_xx;
break;
}
case '2': //sum(x*y)
{
for(int t = 0; t<=pointLen; t+=2){
//printf("%.1f\t",*(points+t));
sum_xy += *(points+t) * (*(points+t+1));}
return sum_xy;
break;
}
default:
cout<<"the charactor is error"<<endl;
return 0;
break;
}
}
double fun(double *arr, double k, double b, int l)
{
double sum = 0.0;
for(int i = 0; i < l; i+=2)
{
//cout<<(k * (*(arr+i)) + b - (*(arr+i+1))) * (k * (*(arr+i)) + b - (*(arr+i+1))) <<endl;
sum += (k * (*(arr+i)) + b - (*(arr+i+1))) * (k * (*(arr+i)) + b - (*(arr+i+1)));
}
return sum;
}
void main()
{
double arr[2*N] = {2.8, 25, 2.9, 27, 3.2, 29, 3.2, 32, 3.4, 34, 3.2, 36, 3.3, 35, 3.7, 39, 3.9, 42, 4.2, 45};
int len = 2*N;
float sum = 0;
//while(getchar() != 'q' && len < 2*N){
// cin >> *(arr+len);
// len++;
//}
//完整AC代码这段需要解放
//y = kx + b: k = sigma[(yi-y均值)*(xi-x均值)] / sigma[(xi-x均值)的平方];b = y均值 - a*x均值。
static double k,b,k0,b0;
double SX,SY, SXY, SXX;
double aver_x, aver_y;
double sigma1,sigma2;
sigma1 = sigma2 = 0.0;
SX = fsum(arr,len,'x') ;
SY = fsum(arr,len,'y') ;
aver_x = SX / ((len>>1)*1.0);
aver_y = SY / ((len>>1)*1.0);
cout<<aver_x <<"\t"<<aver_y<<endl;
SXY = fsum(arr,len,'2');
SXX = fsum(arr,len,'1');
printf(" x y\n");
for(int i = 0; i<len; i+=2){
printf("%.1f %.1f\n",*(arr+i),*(arr+i+1));
sigma1 += ((*(arr+i) - aver_x) * (*(arr+i+1) - aver_y));
sigma2 += ((*(arr+i) - aver_x) * (*(arr+i) - aver_x));
}
k0 = sigma1/sigma2;
b0 = aver_y - k0 * aver_x;
cout<<"\nmy method:"<<endl;
printf("k = %.3f\n",k0);
printf("b = %.3f\n",b0);
printf("sum = %.3f\n\n",fun(arr, k0, b0, len));
cout<<"GUO's method:"<<endl;
sigma1 = sigma2 =0;
for(i = 0; i<len; i+=2){
sigma1 += ((*(arr+i)) * (*(arr+i+1)) - len/2 * aver_x * aver_y);
sigma2 += ((*(arr+i)) * (*(arr+i)) - len/2 * (aver_x * aver_x));
}
//k = sigma1/sigma2;
k = (SXY - len/2 * aver_x *aver_y) / (SXX - len/2 * aver_x * aver_x);
b = aver_y - k * aver_x;
//b = (SXX * SY - SX * SXY) / (N * SXX - SX * SX); //wrong funcation formular
// k = (N * SXY - SX * SY) / (N * SXX - SX * SX);
printf("k = %.3f\n",k);
printf("b = %.3f\n",b);
printf("sum = %.3f\n",fun(arr, k, b, len));
}
先说一下这道题需要注意的点!
- 这是以到涉及数值计算的编程题,使用C/C++语言编写需要注意变量类型的转换,尤其是系统的强制转换。
如果你没注意到数值类型的话,很有可能就会出现这样的问题。
好了,我们在刷题或者练习编程的时候,要懂得举一反三,把一个编程内涉及到的问题都解决,这样才能学得快,学得好!
说明:
- 对于unsigned char和unsigned short int的整型提升问题,C99标准给出“保值”的转换方法:方法是将unsigned char和unsigned short int转换成int,如果超出表示范围,则转成unsigned int。
- 对于表格中第五行,long int与unsigned int的情况,在vc6.0没有这样实现,是直接转成unsigned int。
表格来源 C语言中的数据类型及其转换详解
相比之下,高级编程语言这方面就不用你去关心,例如Matlab、python等。
这里放一段我朋友郭雄编写的python程序,你一看就知道会简单许多。
import numpy as np
# please give the x and y coordinates
x = np.array([2.8, 25, 2.9, 27, 3.2, 29, 3.2, 32, 3.4, 34])
y = np.array([3.2, 36, 3.3, 35, 3.7, 39, 3.9, 42, 4.2, 45])
N = len(x)
k = 0
b = 0
S = 0
def cal_sx(x_position):
sx = 0
for i in range(0, N):
sx = sx + x_position[i]
return sx
def cal_sxx(x_position):
sxx = 0
for i in range(0, N):
sxx = sxx + x_position[i] * x_position[i]
return sxx
def cal_sxy(x_position, y_position):
sxy = 0
for i in range(0, N):
sxy = sxy + x_position[i] * y_position[i]
return sxy
def cal_s(k0, b0, x_position, y_position):
s = 0
for i in range(0, N):
s = s + (k0 * x_position[i] + b0 - y_position[i]) * (k0 * x_position[i] + b0 - y_position[i])
return s
if __name__ == '__main__':
SX = cal_sx(x)
SY = cal_sx(y)
AX = round(SX / N, 3)
AY = round(SY / N, 3)
SXX = cal_sxx(x)
SXY = cal_sxy(x, y)
k = round((SXY - N * AX *AY) / (SXX - N * AX * AX), 3)
b = round((AY - b * AX), 3)
print("k = " + str(k))
print("b = " + str(b))
S = round(cal_s(k, b, x, y), 3)
print("S =" + str(S))
- 关于程序中精确度的一些问题的解答
摘自一位百度网友的截图
接下来就是。。。。
当当当当!
問題2:
问题大致是这样描述的,说一个地区绝大部分的财富被少数一部分人占有(八二定律)。假如总共有n个人,m个富人,请问这m个富人所占的财富比重是多少。如用到排序算法请说明时间复杂度。
分析: 要得出这m个富人,肯定得用到排序的逻辑,但是如何排序使得时间复杂度更低,这是一个需要考虑的问题。
这里,我首先想到的是冒泡排序,只需要找出这较不富裕的n-m个人就可以顺利解决这题。那么可以缩短这个n!次比较次数,缩短为n*m! (这里m<n).
#include <iostream>
using namespace std;
#define DateType int
void swap(int *xp, int *yp)
{
int temp = *xp;
*xp = *yp;
*yp = temp;
}
void BobbleSort(DateType arr[], int len, int m) //第n-m个最小值放在数据末尾
{
int i,j,count = 0;
int max = 0;
if(len>=m)
{
for (i = 0; i<len-m; i++) //provided m<len
for(j = i; j<len-i-1; j++)
if(arr[j]<arr[j+1])
swap(&arr[j], &arr[j+1]);
}
else
printf("given 'm' is illegal\n");
}
void myprint(int arr[], int len)
{
for(int i = 0; i<len; i++)
cout<<arr[i]<<'\t';
cout<<endl;
}
int main(void)
{
int m,n; //总人数n,m个富人
cin>>n;
cin>>m;
double sum_n,sum_m;
sum_n = sum_m = 0;
int *arr=(int *)malloc(sizeof(int)*n);
//int arr[] = {10, 5, 7, 5, 9, 3, 6, 7, 8, 4};
for(int i = 0; i<n; i++)
{
cin>>*(arr+i);
sum_n += *(arr+i);
}
myprint(arr, n);
BobbleSort(arr, n, m);
myprint(arr, n);
for(int j = 0; j<m; j++)
sum_m += *(arr+j);
printf("%.2f", sum_m/sum_n);
return 0;
}
欢迎大家一起学习交流,我们有自己的学生学习小组,我们都一致认为学生之间在一起学习,效率更高、学习动力更足。这样我们的进度可以保持相对一致!
来加入我们吧!
关注微信公众号:迈微电子研发社,回复 “学习群” 获取本博客相关工程及数据文件。
也可加我微信 Yida_Zhang2.
知识星球:社群旨在分享AI算法岗的秋招/春招准备攻略(含刷题)、面经和内推机会、学习路线、知识题库等。
推荐阅读