程序员面试金典 5.8

Draw Line:黑白显示器的屏幕现存可以看做一个一维数组,屏幕上的的每一个像素用1个比特位表示,所以单字节就存储了8个像素,int存储了32个像素。假设屏幕的宽度w32的倍数,屏幕的高度可以根据数组的长度lengthw计算得到。写一个函数,实现一条从(x1, y)(x2, y)的水平线的绘制。

可以通过一个循环,将从x1x2的比特位全部置位,但是更高效率的方法是将[x1, x2]中所有的int一次性置位。

x1 / 32可以得到x1比特所在的intx1 % 32可以得到x1比特在该int中的偏移。如果偏移不为0,则[x1, x2]中的第1个需要置位的int在下一字节;同理如果x2偏移不为31,则[x1, x2]中的最后一个需要置位的int在上一字节。

对于x1x2所在int,偏移从0开始,用0xFFFFFFFF右移得到该字节的掩码;对于x2,用0xFFFFFFFF左移得到该字节的掩码。

class Solution {
public:
    vector<int> drawLine(int length, int w, int x1, int x2, int y) {
        vector<int> scrn(length, 0);
        const int iSize = sizeof(int) * 8;
        const int iPerLine = w / iSize;
        int beginByte = x1 / iSize, beginOffset = x1 % iSize;
        int endByte = x2 / iSize, endOffset = x2 % iSize;
        if(beginOffset != 0) beginByte++;
        if(endOffset != iSize - 1) endByte--;
        for(int b = beginByte; b <= endByte; b++)
        {
            scrn[iPerLine * y + b] = 0xFFFFFFFF;
        }
        unsigned int beginMask = 0xFFFFFFFF >> beginOffset;
        unsigned int endMask = 0xFFFFFFFF << (iSize - endOffset - 1);
        if(x1 / iSize == x2 / iSize){
            scrn[iPerLine * y + x1 / iSize] = beginMask & endMask;
        }
        else{
            if(beginOffset != 0){
                scrn[iPerLine * y + beginByte - 1] = beginMask;
            }
            if(endOffset != iSize - 1){
                scrn[iPerLine * y + endByte + 1] = endMask;
            }
        }
        return scrn;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值