笔试3:兴业数金
岗位:C语言开发工程师
单选*40
SQL语言基本概念;
软件开发项目风险评估、风险分析相关概念;
数据流图父图和子图平衡;
DHCP服务相关概念;
原型化开发方法相关概念;
事务回滚概念;
SELECT DISTINCT;
C语言非空的基本数据类型;
UML基本概念;
什么是数据独立性?
……
多选*20
数据通信方式;
分布式混合体系结构;
分解关系基本原则?
瀑布式模型
…………
编程*1
实际系统发送一个报文时,为了保证发送的报文被接收方完整地接收,往往在发送报文时,增加同步字符、长度和分片处理。假如一个系统发送报文有如下规则:
(1)先发送同步字符串"000";报文按256字节分片发送,每一段内容如下:
(2)剩余报文长度和256长度的报文(最后不足256则为实际剩余报文),报文长度以4个字节的字符串形式,不足4位前面补0,如"0511"。
例子:一个510长度报文,实际发送的顺序为:0000510****(256长度报文)0254****(254长度报文)。
加入要发送一个报文实际内容为自然数序列的字符串,长度为9999,如12345678910111213...100101102103...99910001001...,那么输入一个整数,求这个整数位置(1为发送的第一个字符)的发送字符是什么?
输入:8
输出:1
说明:0009999123456789,第8位是1。
只过了85%,我再想下,这无脑的淳朴啊。
#define LEN 9999 vector<int>help1(int n) {//获取每一个数字的每一位 vector<int>res; while (n) { res.push_back(n % 10); n /= 10; } return res; } int getMessageN(int n) { //create message of 9999 length //"0009999****9743****" vector<int>msgs{ 0,0,0 }; //计算9999长度会产生多少256分片,即****,以及最后一个分片数目 int totalMsgLen = LEN; int nMsg = totalMsgLen / 256; //nMsg个长度为256的分片 int lastMsg = totalMsgLen % 256; //最后一个分片数目 int ziranshu = 1; vector<int>tmp; int index; for (int i = 0; i < nMsg; i++) { tmp = help1(totalMsgLen); msgs.insert(msgs.end(),tmp.rbegin(), tmp.rend()); tmp.clear(); index = 1; while (index <= 256) { tmp = help1(ziranshu); msgs.insert(msgs.end(), tmp.rbegin(), tmp.rend()); ziranshu++; index += tmp.size(); tmp.clear(); } totalMsgLen -= 256; } if (lastMsg > 0) { tmp = help1(totalMsgLen); msgs.insert(msgs.end(), tmp.rbegin(), tmp.rend()); tmp.clear(); index = 1; while (index <= lastMsg) { tmp = help1(ziranshu); msgs.insert(msgs.end(), tmp.rbegin(), tmp.rend()); ziranshu++; index += tmp.size(); tmp.clear(); } totalMsgLen -= lastMsg; } return msgs[n - 1]; }
剑指Offer上有一道类似的题目:查找自然数序列(即01234567891011121314151617181920...)中的第n位(从第0位开始)。
比较直观的朴素做法是使用一个变量记录数字位数之和,然后从0开始遍历。实际上要找规律:
0-9:每个数占1位,共10个数,共占1*10=10位;
10-99:每个数占2位,共90个数,共占2*90=180位;
100-999:每个数占3位,共900个数,共占3*900=2700位;
……
假设要找第800位,从0开始找第800位。因为800>10,则从10开始找第800-10=790位;因为790>180,则从100开始找第790-180=610位;因为610<2700,说明要找的数字在100-999之间。610=203*3+1,则要找的是100+203=303的第1位(注意下标从0开始)。
int getN(int n, int weight); //函数重载 int getN(int n) { if (n < 0) return 0; int weight = 1; //数字位数 while (true) { int number = weight == 1 ? 10 : (int)pow(10, weight - 1) * 9; //weight对应的数字数目 if (n < number*weight) return getN(n, weight); n -= number*weight; weight++; } return 0; } int getN(int n, int weight) { int beginNumber = weight == 1 ? 0 : (int)pow(10, weight - 1); //求出此范围内第一个数字,即100 int targetNumber = beginNumber + n / weight; //求出目标位所在的数字,即303 int indexFromRight = weight - n % weight; //这里有点意思 for (int i = 1; i < indexFromRight; i++) //注意从1开始 { targetNumber /= 10; } return targetNumber % 10; }