2011-08-16 3 views
1

파일 생성하기 위해 트리 구조를 기반으로 행과 COLS을 caculate :의 코드로는 엑셀 내가 클래스 부서가

class Department{ 
    string des; 
    string name; 
    string id; 
    List<Department> subDeps; 
} 

를 한 부서는 여러 하위 departmens을 가질 수있다.

이제 데이터베이스에서 정보를 읽었으며 루트 Department 개체를 얻습니다.

은 그 때 나는 이런 식으로 같은 엑셀 워크 시트를 생성하려면 :

enter image description here

는 사실, 뿌리는 "부서"객체는 트리 구조입니다.

엑셀 시트에 항목을 쓰려고 할 때 해당 항목의 행과 열을 결정해야하지만 작성할 수 없습니다.

그리고 나에게 호의를 베풀 수 있습니까?

이 방법에서

답변

2

봐 : 당신이 노드 (왼쪽)과 해당 위치를 이름으로

0 00 000 | (0,0) (0,1) (0,2) 
    001 |    (1,2) 
1 10 100 | (2,0) (2,1) (2,2) 
    101 |    (3,2) 
    11  |  (4,1) 

내가 동일한 구문을 사용하여 "(행, 열)"그리드 (오른쪽)에 . 0과 1의 두 개의 최상위 부서가 있습니다. 모든 트리/최상위 부서의 깊이 첫 방문으로 "(x, y)"좌표로 노드의 레이블을 지정할 수 있습니다. 당신이 아버지에서 자식으로 내려갈 때마다 열 번호를 1 씩 증가시켜야합니다. 새로운 형제를 방문 할 때마다 행 색인은 비어있는 새 색인을 참조해야합니다 (이 예에서 10의 형제는 11이지만 행 3이 이미 부서 101에 의해 점유되었으므로 (3,1)에 넣을 수 없습니다.

다음 지침에 따라 알고리즘을 작성합니다. 방문한 현재 노드/부서와 함께 재귀 깊이 우선 방문 매개 변수로 전달 된 두 변수를 사용하여 현재 (x, y)를 추적합니다. 이 함수는 필요에 따라 엑셀 표현을 편집하지만 사용 된 최대 행 인덱스를 반환해야합니다 (이전 예제에서와 같이 새로운 형제를 방문 할 때 다음 행이 무엇인지 알 수 있도록). 재귀 호출을 할 때마다 새로운 열이므로 좌표 (x, y + 1)로 호출해야합니다. 비슷한 방식으로 새로운 형제를 방문하면 새로운 행이므로 (coords_prev_call_retn은 이전 형제의 마지막 재귀 호출 값임) 호출하면 (coords prev_call_retn + 1, y) 호출됩니다. 도우미 함수는 루트 노드에서 재귀 호출을 호출하고 기본 좌표 (0,0) 또는 시작하려는 항목을 사용합니다.

이 C에서
#include <iostream> 
#include <list> 
#include <string> 

using namespace std; 

class Dept { 
public: 
    string id; 
    list<Dept*> *subDepts; 

    Dept(string id) { 
     this->id = id; 
     this->subDepts = new list<Dept*>(); 
    } 

    Dept *addChild(Dept *d) { 
     this->subDepts->push_back(d); 
     return d; 
    } 

    Dept *addChild(string id) { 
     Dept *d = new Dept(id); 
     return this->addChild(d); 
    } 

}; 

void visit(Dept *d, int row, int col) { 
    cout << "Dept " << d->id << ": (" << row << ", " << col << ")\n"; 
} 

int label(Dept *d, int row, int col) { 
    if (d == 0) return row; 
    visit(d, row, col); 
    list<Dept*> *lst = d->subDepts; 
    for (list<Dept*>::iterator it = lst->begin() ; it != lst->end(); it++) 
    { 
     row = label(*it, row, col+1) + 1; 
    } 
    if (lst->size() > 0) row--; 
    return row; 
} 

int label(Dept *d) { 
    label(d, 0, 0); 
} 

에게 ++ 코드, 레이블() 관심있는 기능입니다.

매개 변수 행 및 COL은 부서 * D의 정확한 좌표가 있어야하는 우리가 할 수 있도록 즉시 노드를 방문하십시오.

루프는 각 자식 (있는 경우)에서 label()을 반복적으로 호출합니다. 마지막으로 사용 된 행 + 1을 추적하기 위해 변수 행을 사용합니다.

마지막으로 함수에서 마지막으로 사용한 행을 반환해야하지만 d-> subDepts 비어 있지 않습니다. 이는 for 반복문이 마지막 반복에서 1 개의 추가 행을 추가하기 때문입니다.여기에 결과

int main(int argc, char **argv) { 
    Dept *d0 = new Dept("0"); 
    Dept *d00 = d0->addChild("00"); 
    Dept *d01 = d0->addChild("01"); 
    Dept *d000 = d00->addChild("000"); 
    Dept *d001 = d00->addChild("001"); 
    Dept *d002 = d00->addChild("002"); 
    Dept *d010 = d01->addChild("010"); 
    Dept *d02 = d0->addChild("02"); 
    label(d0); 
    return 0; 
} 

그리고 :

bash-4.2$ g++ dept.cpp && ./a.out 
Dept 0: (0, 0) 
Dept 00: (0, 1) 
Dept 000: (0, 2) 
Dept 001: (1, 2) 
Dept 002: (2, 2) 
Dept 01: (3, 1) 
Dept 010: (3, 2) 
Dept 02: (4, 1) 

난이 도움이되기를 바랍니다 여기

는 주요 예입니다.

+0

좋은 답변 주셔서 감사합니다, 그리고 코드를 작성하려고하지만, 그것을 만들 수 없습니다, 나는 알고리즘이 좋지 않아. 너는 자유 시간에 여분의 시간을 할애 해 줄 수 있니? – hguser

+0

반갑습니다. 여기서는 작동하는 C++ 예제를 추가하여 내 대답을 편집했습니다. –

+0

, 감사합니다. 그것은 작동하지만, 나는 각 셀의 행 - 기간 및 열 - 범위를 caculate 수 있다면 궁금해? 귀하의 예제에서 'Dep0'은 하나의 열과 두 개의 행을 취하고 'Dep11'은 두 개의 열과 한 개의 행을 가져야합니다. – hguser

0

예제 에서처럼 레이아웃을 수행하고 싶으면 셀을 정렬하기 위해 colspans를 사용하여 먼저 찾거나 (하드 코딩), 최대 깊이를 알지 않고서는 아무 것도 볼 수 없습니다 트리의 총 수를 결정하려면이 항목이 필요합니다. (아래의 코드를 이해하는 데 도움이 될 것입니다) 일부 테이블 속성의

가정 :

  • 만 가장 오른쪽에있는 세포가 여러 열을 걸쳐 모든 사람들은 항상 가지고 colWidth 1 개
  • 가장 오른쪽 셀이 여러 행에 걸쳐 적이있다 colHeight 1
  • (코드에서 변수 blockWidth 또는 maxY을 설정)
테이블의 '부'부분의 최대 폭, 또는 대안 적으로 최대 열 인덱스를 계산하기 위해 몇몇 기능이 존재

의사 코드는 테이블 레이아웃 :

displayDeptTree(Department root) { 
    startX, startY: beginning coord of the root dept 
    blockWidth: total no. of columns (tree depth + 1, or hardcoded to value > possible depth) 
    maxY = startY + blockWidth - 1 // global var? 

    addDeptIntoCell(root, startX, startY) 
} 

// returns height of the cell 
int addDeptIntoCell(Department d, x, y) { 
    colHeight = 1 
    if (d->subDeps is empty) { 
     colWidth = maxY - y 
     addDepartment(d, x, y, colHeight, colWidth) // colHeight = 1 always 
    } else { 
     currY = y 
     for (Dept child : d->subDeps) { 
      childHeight = addDeptIntoCell(child, x + 1, currY); // increment x pos for children 
      currY += childHeight 
     } 
     colHeight = currY - y 
     addDepartment(d, x, colHeight, 1) 
    } 
    return colHeight 
} 


addDepartment(Department d, x, y, height, width) { 
    // Actually adds the department info into table, parameters should be self-explanatory, implementation not shown 
} 

이 등 하나의 오류로 해제 할 수 있습니다를, 나는 자바 감지하지 C++ 포인터 존중에> subDeps을 D- 사용하고 있지만 일반을 얻어야한다 아이디어 :