2010-04-21 2 views
2

나는 노동 조합 문 ++ C에서 스도쿠 보드를 설명하기 위해 노력하고있어 : 보드의 각 섹션은 배열의 올바른 부분증분 조합?

union Board 
{ 
    int board[9][9]; 
    int sec1[3][3]; 
    int sec2[3][3]; 
    int sec3[3][3]; 
    int sec4[3][3]; 
    int sec5[3][3]; 
    int sec6[3][3]; 
    int sec7[3][3]; 
    int sec8[3][3]; 
    int sec9[3][3];  
} 

해당시겠습니까? IE,

sec4는 [4-6] [0-3]과 일치합니까? 이런 종류의 일을 할 수있는 더 좋은 방법이 있습니까 (특히 스도쿠 보드를 설명하는)?

+7

문제가 무엇이든지간에 노조는 거의 정답이 아닙니다. –

+0

노동 조합은 공간을 절약하기위한 것이 아닌가? 표준은 심지어 sec3 [1] [1]에 무엇인가 넣고 보드 [0] [4]를 읽을 때 일어나는 일을 보장합니까? –

+0

@Maciej H : 표준은 공통 초기 시퀀스 (POD 구조체를 제외하고는 배열을 포함하지 않음)를 가진 POD 구조체에 대해 보증합니다. 그 외에도 일반적인 관행이 있지만 어떤 구현이 노동 조합에서하는 일을 문서화하는지는 알 수 없습니다. (정의 : POD 구조체는 C 프로그램에서 가질 수있는 "일반 오래된 데이터"를 포함하는'struct'입니다.) –

답변

5

당신은 클래스에 캡슐화하여 원하는 효과를 얻을 수있다 :

class Board { 
public: 
    int& sec1(int r, int c) { return board[r][c]); } 
    int& sec2(int r, int c) { return board[r][c+3]; } 
    // etc. 

private: 
    int board[9][9]; 
}; 

하지만, 나는 이것이 스도쿠 보드를 대표하는 가장 좋은 방법입니다 확실하지 않다. 논리에 대한 작업을 시작하면 더 나은 표현을 찾을 수 있습니다.

+0

+1 더 나은 해결책; 매개 변수로 섹션 번호가있는 단일 함수를 사용할 수도 있습니다. – Tomas

+0

그래, 훨씬 더 나은 해결책. 실제로 겹치는 멤버가있는 마법 구조를 설계하는 대신 여러 접근자를 정의하면됩니다 동일한 데이터에 대한 다양한 시각을 제공합니다. – jalf

1

작성된대로 작동하지 않습니다.

유니언은 모든 멤버가 유니온의 시작 오프셋 (offset) 0에있는 것처럼 동작합니다.

즉, sec9sec1과 동일한 오프셋 (0)을 가지므로 중복됩니다.

노조를 사용하여 할 수 없다고 생각합니다. 각 섹션의 끝에서 일어나는 특정 "건너 뛰기"가 있음을 표현해야하므로 다음 셀로 이동하십시오. 그 부분. C 또는 C++ 배열을 사용하여 그렇게 할 수 없습니다.

+0

그래도 이런 종류의 일을 성취 할 수있는 방법이 있습니까? – cam

+0

아니요. 섹션이 전체 보드의 행과 겹칩니다. –

0

C++ 언어 기능을 사용하여이 문제를 해결할 필요가 없습니다. 문제를 해결하는 데 필요한 구조에 대한 데이터 구조 및 작업에 대해 생각해야합니다. 즉, 클래스를 디자인해야합니다 가능한 여러 클래스들). 이것은 프로그래밍의 재미있는 부분이므로 솔루션을 제안하지는 않을 것입니다.

+0

이봐, 그 부분도 너무 좋아. 중복되는 데이터를 만드는 방법을 묻는 것입니다. : – cam

1

대답은 아니오입니다. 메모리 레이아웃이 예상 한 것과 다를 수 있습니다. C/C++에서 배열을 정의 할 때마다 메모리가 연속적이므로 9x9 배열의 경우 4 번째 요소는 두 번째 행의 첫 번째 요소가 아니라 두 번째 3x3 블록의 첫 번째 행의 첫 번째 요소가됩니다.

유니온의 메모리 레이아웃은 full 개체의 9 줄마다 하나씩 sec 개의 블록을 갖습니다.

0

다른 해결책 (Ferruccio가 제안한 것 외에)은 각 섹션에 대해 하나씩 int에 대한 3 개의 포인터 배열을 정의하고 해당 배열을 생성자에서 적절하게 초기화하는 것일 수 있습니다.

class Board { 
public: 
    int *sec1[3]; // sec1[0] = &(board[0][0]), sec1[1] = &(board[1][0]),sec1[2] = &(board[2][0]) 
    ... 

    int board[9][9]; 
}; 

하지만 솔직하게 액세스하는 방법이 훨씬 좋습니다.

1

모든 조합원, 따라서 모든 sec1..sec9 초가 동일한 위치에 있습니다. 당신은 구조체의 모든 종파를 포장 해 낼 수 있지만 여전히 그들은 3 × 3의 사각형에 해당되지 않지만 원래 구조에서 오히려 9 * 1 행 :

union Board 
{ 
    int board[9][9]; 
    struct { 
     int sec1[3][3]; 
     int sec2[3][3]; 
     int sec3[3][3]; 
     int sec4[3][3]; 
     int sec5[3][3]; 
     int sec6[3][3]; 
     int sec7[3][3]; 
     int sec8[3][3]; 
     int sec9[3][3];  
    } sects; 

} 

가 정리해하려면, 실제 클래스는 가장 좋은 방법이 될 것입니다.

0

9 * 9 보드의 각 3 * 3 영역이 불연속 메모리를 차지할 것이기 때문에 작동하지 않습니다.cell_ptr[0][0...80] 행에 걸쳐 반복하는을 허용, cell_ptr[1][0...80]가 열을 반복 할 수 있도록 cell_ptr 그리드에 포인터로 채워집니다

Cell grid[9][9]; 
Cell* cell_ptr[3][81]; //0 = by rows; 1 = by columns; 2 = by box 

cell_ptr[2][0...80]는 반복하는 3 * 3을 통해 지역 수 :

내가 무슨 짓을 한 것은 .