大众点评笔试题:十六进制序列

这是一道关于十六进制序列的题目,给定一个位置i,需要找到第i个位置上的字符。例如,对于序列112123...,当i=50时,字符为5,i=100时,字符为9。解决方法包括确定i所在的序列,计算在序列中的位置,然后找出对应的16进制数字的哪一位。提供的C语言实现代码可帮助完成这一转换。

描述:有一个十六进制序列由S1S2…Sk组成,其中Sk由1到k的十六进制数字依次组成。给定一个位置i,返回第i个位置上的字符。数字i为32位int。

例如,S1S2…Sk的前200个字符为

112123123412345123456123456712345678123456789123456789A123456789AB123456789ABC

123456789ABCD123456789ABCDE123456789ABCDEF123456789ABCDEF10123456789ABCDEF

1011123456789ABCDEF101112123456789ABCDEF10111213

所以i=50时,字符为5,i=100时,字符为9

要求时间复杂度小于O(n),空间复杂度O(1)


思路:先找出i落在哪个Sk序列上,再找出是在Sk序列的第几个数,最后找出是在这个数的第几位。

1. 对于每个Sk序列,先求出该序列的总字符个数。假设数字k用16进制表示有p位,则将Sk序列划分为如下几个区间,将每个区间的字符个数累加求和。


2. 找出是落在哪个Sk之后,再判断是在Sk的哪个区间上,找到对应的数字num

3. 计算是数字num的第几位(16进制),通过移位操作得到对应的字符即可。

C语言实现代码如下:

#include <stdio.h>
#include <assert.h>

//数n用16进制表示的位数
int hex_counts(int n)
{
    int count = 0;
    do {
        count++;
        n = n >> 4;
    } while(n > 0);
    return count;
}

//序列Sk中的数字个数
int sum(int k)
{
    int i, p, sum;
    p = hex_counts(k); //hexadecimal bits
    sum = 0;
    for (i = 1; i < p; i++) {
        sum += ((1<<(4*i)) - (1<<(4*(i-1)))) * i;
    }
    sum += (k - (1<<(4*(p-1))) + 1) * p;
    return sum;
}

//将数字n转化成十六进制
char upper(int n)
{
    assert(n>=0 && n <= 15);
    if (n >= 0 && n <= 9)
        return '0' + n;
    else
        return 'A' + n - 10;
}

//返回Sk中第pos个字符
char get_value(int pos, int k)
{
    int i, p, num, value, sum = 0;
	p = hex_counts(k);
    for (i = 1; i < p; i++) {
        if (sum + ((1<<(4*i)) - (1<<(4*(i-1))))*i >= pos)
            break;
        sum += ((1<<(4*i)) - (1<<(4*(i-1))))*i;
    }
    num = (1<<(4*(i-1))) + (pos-sum-1)/i; //第pos个字符在数字num上,num共有i位
    value = (num>>(4*(i - (pos-sum-1)%i - 1)))&0xF; //第pos个字符是num的第(pos-num-1)%i+1位
    return upper(value);
}

//返回S1S2...Sk序列中的第i个字符
char get_pos(int i)
{
    int k, tmp, count;
    k = 1;
    count = 0;
    while (1) {
        tmp = sum(k);
        if (count + tmp >= i)
            break;
        count += tmp;
        k++;
    }
    return get_value((i - count), k);
}

int main(void)
{
    int i;
    for (i = 1; i <= 200; i++) {
        printf("%c", get_pos(i));    
    }
    printf("\n");
    return 0;
}


有个类似的题:POJ-1019 Number Sequence

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值