CS106B Section Solutions #4
阿新 • • 發佈:2018-12-15
Problem 1: Filling a Region
回溯思想填空白
#include <iostream> #include "vector.h" #include "grid.h" using namespace std; enum pixelStateT { White, Black }; struct pointT { int row, col; }; void FillReign(pointT pt, Grid<pixelStateT> & screen); bool IsOffGrid(pointT pt, Grid<pixelStateT> & grid); pointT move(pointT pt, int i); int main() { //建立圖 Grid<pixelStateT> screen(10,10); for(int i=0;i<10; i++) screen(0,i) = Black; for(int i=0;i<10; i++) screen(1,i) = White; for(int i=0;i<10; i++) screen(2,i) = Black; for(int i=0;i<10; i++) screen(3,i) = White; for(int i=0;i<10; i++) screen(4,i) = Black; for(int i=0;i<10; i++) screen(5,i) = White; for(int i=0;i<10; i++) screen(6,i) = Black; for(int i=0;i<10; i++) screen(7,i) = White; for(int i=0;i<10; i++) screen(8,i) = Black; for(int i=0;i<10; i++) screen(9,i) = White; //列印圖 for(int i=0; i<10; i++){ cout<< screen(i,0)<<screen(i,1)<<screen(i,2)<<screen(i,3) <<screen(i,4) <<screen(i,5)<<screen(i,6)<<screen(i,7)<<screen(i,8)<<screen(i,9)<<endl; } //選擇點 cout <<"-------------"<<endl; pointT pt; pt.row = 7; pt.col = 4; //填充 FillReign(pt, screen); //列印新圖 for(int j=0; j<10; j++){ cout<< screen(j,0)<<screen(j,1)<<screen(j,2)<<screen(j,3) <<screen(j,4) <<screen(j,5)<<screen(j,6)<<screen(j,7)<<screen(j,8)<<screen(j,9)<<endl; } return 0; } void FillReign(pointT pt, Grid<pixelStateT> & screen){ if (IsOffGrid(pt,screen)) return; if (screen(pt.row, pt.col) == Black) return; screen(pt.row, pt.col) = Black; for(int i=0; i<4; i++) { FillReign(move(pt, i),screen); } } bool IsOffGrid(pointT pt, Grid<pixelStateT> & grid){ return pt.row < 0 || pt.row >= grid.numRows() || pt.col < 0 || pt.col >= grid.numCols(); } pointT move(pointT pt, int i){ pointT temp; switch(i){ case 0: temp.row = pt.row-1; temp.col = pt.col ; break; case 1: temp.row = pt.row+1; temp.col = pt.col ; break; case 2: temp.row = pt.row; temp.col = pt.col-1 ; break; case 3: temp.row = pt.row; temp.col = pt.col+1 ; break; } return temp; /* 結果展示: point (7,4): 1111111111 0000000000 1111111111 0000000000 1111111111 0000000000 1111111111 0000000000 1111111111 0000000000 ------------- 1111111111 0000000000 1111111111 0000000000 1111111111 0000000000 1111111111 1111111111 1111111111 0000000000 point (8,4): 1111111111 0000000000 1111111111 0000000000 1111111111 0000000000 1111111111 0000000000 1111111111 0000000000 ------------- 1111111111 0000000000 1111111111 0000000000 1111111111 0000000000 1111111111 0000000000 1111111111 0000000000 */
Problem 2: Shortest Path Through a Maze
由於mazesolve函式已經給出類,只需要稍微改改就行
int ShortestPathLength(pointT pt){ int shortest, len; if(OutsideMaze(pt)) { return 0; } if(IsMarked(pt)) { return Nosolution; } shorest = NoSolution; MarkSquire(pt); for(directionT dir = North; dir <= West; dir = directionT(dir+1)){ if(!WallExists(pt,dir)) { len = ShortestPathLength(AdjacentPoint(pt, dir)); if (len < shortest){ shortest = len; } } } UnmarkSquare(pt); if (shortest == NoSolution){ return NoSolution; } else { return (shortest + 1); } }
Problem 3: Pointers
這個指標概念問題沒什麼說得
Problem 4: Linked List Warmup
a) 兩種方法將vector改成連結串列,遞迴方法看看就好
Cell * ConvertToListIter(Vector<int> vector){ Cell *head = new Cell;//連結串列頭用new建立 head->next = NULL; head->value = vector[0]; Cell *curr = head;//取頭指標,之前的 head用於返回 for(int i=0;i<vector.size(); i++){ Cell *newCell = new Cell; newCell->next = NULL; newCell->value = vector[i]; curr->next = newCell; newCell = curr; } return head; } Cell * ConvertToListRealRecur(Vector<int> &vector, int index) { if(index >= vector.size()) return NULL; Cell *curr = new Cell; curr->value = vector[index]; curr->next = ConvertToListRealRecur(vector, index + 1); return curr; } Cell * ConvertToListRecur(Vector<int> vector) { return ConvertToRealRecur(vector, 0); }
b)連結串列操作
int SumListIter(Cell *list){
int sum = 0;
Cell *curr = list;//curr指向頭指標
whlie(curr != NULl){
sum += curr->value;
curr = curr->next;
}
return sum;
}
int SumListRecur(Cell *list)
{
if(list == NULL)
return 0;
else
return list->value + SumListRecur(list->next);//連結串列遞迴經典操作
}
Problem 5: Linked List Trace
實現的功能就是把連結串列最後一個提到第一個,果然學指標最好的例子還是連結串列
//Link List Trave
void PopRocks(Cell * & mikey)//&傳遞,用於改變頭指標
{
Cell *ptr;
for (ptr = mikey; ptr->next != NULL; ptr = ptr->next)//將指標傳遞到結尾
{
/* Note: loop body intentionally left empty */ //想不到把,空迴圈
}
ptr->next = mikey;//將結尾連到開頭
ptr = ptr->next;//移到原來頭指標
mikey = mikey->next;//把原來的第二個數變成頭指標
ptr->next = NULL;//把原來的第一個指向空指標,即變成結尾
}
Problem 6: Append
記得以前資料結構老師講過這個例子,懷念
void Append(Cell *& first,Cell * second){
if(first == NULl)
{
first = second; //這就是為什麼之前first要用&傳遞,因為當first為空時,first的頭指標會改變
}
else{
Append(first->next,second);//臥槽,亮瞎有木有
}
}