2017-01-29 4 views
0

올바른 사이트에있는 대문자 "A"를 나타내는 특정 바이트 배열을가집니다. (source)바이트 배열 반 시계를 시계 방향으로 회전

예상되는 결과는 대기열 "A"에 대해 시계열 방향으로 바이트 배열을 회전시키는 것입니다.

주어진 배열을 회전 된 버전으로 변환하려는 시도는 훌륭하지만 좋지 않습니다. 내 코드의 일부가 비트 이동 및 계산 부분의 "loop()"에서 올바르지 않습니다. 이런 이유로 x == 5와 x == 6을 따로 처리해야했습니다.

바이트 배열 반 시계를 시계 방향으로 더 일반적인 방법으로 c로 회전하려면 어떻게해야합니까?

마지막으로 어레이는 Arduino의 8x8 LED 매트릭스에 표시됩니다. 아래 코드와 출력을 참조하십시오.

코드 :

#include "LedControl.h" 
LedControl lc=LedControl(12,11,10,4); 

void setup(){ 
    for (int addr=0; addr<lc.getDeviceCount(); addr++){ 
    lc.shutdown(addr,false); 
    lc.setIntensity(addr,0); 
    lc.clearDisplay(addr); 
    } 
} 

void loop(){ 
    // given 
    byte a[5]={B01111110,B00010001,B00010001,B01111110,B00000000}; 

    // expected 
    byte a2[8]={B01100000,B10010000,B10010000,B10010000,B11110000,B10010000,B10010000,B00000000}; 

    // rotated 
    byte a3[8]; 
    byte row; 
    for (int x = 0; x < 8; x++){ 
    row = B00000000; 
    for (int y = 0; y < 5; y++){ 
     if (x==0 || x==1 || x==2 || x==3 || x==4) { 
     row |= (a[y] & B00000001 << x) << 7-x-y; 
     } 
     if (x==5) { 
     row |= (a[0] & B00100000) << 2; 
     row |= (a[1] & B00100000) << 1; 
     row |= (a[2] & B00100000); 
     row |= (a[3] & B00100000) >> 1; 
     } 
     if (x==6) { 
     row |= (a[0] & B01000000) << 1; 
     row |= (a[1] & B01000000); 
     row |= (a[2] & B01000000) >> 1; 
     row |= (a[3] & B01000000) >> 2; 
     } 
    } 
    a3[x] = row; 
    } 

    // output 
    for(int i=0; i<8; i++){ 
    lc.setRow(0,i,a[i]); // given 
    lc.setRow(1,i,a2[i]); // expected 
    lc.setRow(2,i,a3[i]); // rotated 
    delay(100); 
    } 
} 

출력의 LED :

given a   expected a2 
        rotated a3 

_ o o o o o o _ _ o o _ _ _ _ _ 
_ _ _ o _ _ _ o o _ _ o _ _ _ _ 
_ _ _ o _ _ _ o o _ _ o _ _ _ _ 
_ o o o o o o _ o _ _ o _ _ _ _ 
_ _ _ _ _ _ _ _ o o o o _ _ _ _ 
_ _ _ _ _ _ _ _ o _ _ o _ _ _ _ 
_ _ _ _ _ _ _ _ o _ _ o _ _ _ _ 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

답변

1

귀하의 코드는 정말 과장 보인다.

#include <stdio.h> 

typedef unsigned char byte; 

void printCharacter(const byte* data, size_t length) 
{ 
    for (size_t i = 0; i < length; ++i) 
    { 
    for (size_t j = 0; j < 8; ++j) 
    { 
     const unsigned char mask = 1 << j; 
     printf("%c ", data[i] & mask ? 'o' : '-'); 
    } 
    printf("\n"); 
    } 
} 

void rotate(const byte* source, byte* dest, size_t length) 
{ 
    /* for each bit position starting from first */ 
    for (size_t j = 0; j < 8; ++j) 
    { 
    /* this is the mask of the i-th bit in source data */ 
    const unsigned char mask = 1 << j; 

    /* for each row in source data (which will become column) */ 
    for (size_t i = 0; i < length; ++i) 
    { 
     /* if j-th bit of i-th row set */ 
     if (source[i] & mask) 
     /* then set i-th bit of j-th row */ 
     dest[j] |= 1 << i; 
    } 
    } 
} 

int main() { 
    byte a[5]= { 0b01111110,0b00010001,0b00010001,0b01111110,0b00000000 }; 
    byte b[8]= { 0 }; 
    printCharacter(a, 5); 
    rotate(a, b, 5); 
    printCharacter(b, 8); 
    return 0; 
} 

이제이하지 않다

- o o o o o o - 
o - - - o - - - 
o - - - o - - - 
- o o o o o o - 
- - - - - - - - 

- o o - - - - - 
o - - o - - - - 
o - - o - - - - 
o - - o - - - - 
o o o o - - - - 
o - - o - - - - 
o - - o - - - - 
- - - - - - - - 

출력 : 그에 따라 임의의 각 소스 데이터의 가능한 비트 신지 설정 데이터를 반복 할 중첩 루프 (기본적 인덱스 스왑 함) 같은 것을 사용하여 정확히 무엇을 찾고 있지만 원하는 회전에 따라 첫 번째/마지막 비트부터 시작하도록 마스크/색인을 조정하면됩니다.

+0

솔루션에서 소스와 대상이 겹칠 수 없습니다. –

+0

@PaulOgilvie : 요점은 어디 있습니까? 새로운 배열이 생성 된 후에'memcpy'를 사용하십시오. OP는 임시 데이터 사용을 피할 필요가 없으므로 보조 임시 배열을 사용하지 않고 왜 당신의 삶을 훨씬 더 복잡하게 만들었습니까? downvote 할 아무 이유도 없기 때문에 그것을 할 이유가 없습니다. – Jack

+0

잭, 네 말이 맞아. 알아 두실 가치가 있습니다 (부분적으로'const' 지시자에 의해). 내가 그것이 필요 조건이 아닌 것을 알아 차렸 더라면 downvote는 취소되었다. –