Draw Line:黑白显示器的屏幕现存可以看做一个一维数组,屏幕上的的每一个像素用1
个比特位表示,所以单字节就存储了8
个像素,int
存储了32
个像素。假设屏幕的宽度w
是32
的倍数,屏幕的高度可以根据数组的长度length
和w
计算得到。写一个函数,实现一条从(x1, y)
到(x2, y)
的水平线的绘制。
可以通过一个循环,将从x1
到x2
的比特位全部置位,但是更高效率的方法是将[x1, x2]
中所有的int
一次性置位。
将x1 / 32
可以得到x1
比特所在的int
,x1 % 32
可以得到x1
比特在该int
中的偏移。如果偏移不为0
,则[x1, x2]
中的第1
个需要置位的int
在下一字节;同理如果x2
偏移不为31
,则[x1, x2]
中的最后一个需要置位的int
在上一字节。
对于x1
和x2
所在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;
}
};