笔试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;
}
全部评论
这个题目***,跟剑指offer那个序列的是一回事吗?
点赞
送花
回复
分享
发布于 2021-04-15 08:39

相关推荐

看网上风评也太差了
投递万得信息等公司8个岗位 >
点赞 评论 收藏
转发
4 26 评论
分享
牛客网
牛客企业服务