程序员面试金典 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;
    }
};
发布了194 篇原创文章 · 获赞 2 · 访问量 7722

猜你喜欢

转载自blog.csdn.net/RayoNicks/article/details/105407651
5.8
今日推荐