cs61b project1
Debug到死系列,感觉每一个方法都查了了好几遍。。。感觉完成project1之后对List和Array的理解加深了不少,而且debug的能力明显增强23333 。
代码很多写的也比较繁琐就不贴了,挑几个写的少的贴上吧,debug到最后自己经常都搞晕了,简单说下思路
part1: 设置了一个pixel的private class其中包含Red,Green,Yellow三个颜色的值,然后建立一个pixel的矩阵,就是基本的数据结构了。
Blur和Sobel方法:最好将原矩阵外扩一圈0,便于简化代码,还是注意扩大后矩阵width和height分别为width+2和height+2而不是+1(看组长的博客才意识到这点),
其余的就是多次用loop和recur改动矩阵的元素就好,细心一些避免出现OutOfBoundException。
测试结果:
part2-4:
其实并没有搞明白part2最开始让建立的那两个构造函数是干什么用的,感觉只需要part3那个构造函数就行了啊。
Run的构建是采用DoubleList(有一个head和tail),不过感觉用circularList(就是只有一个sentinel对象作为头和尾)更简化一些,List的node存放一个三个short值分别存放red,green和blue,还有一个int值(名字为num)用来表示其中包含重复pixel的个数。
part3:我是将自己的DoubleList的insert方法做了点改动,就是在insert进一个pixel的时候判断下是否和当前队尾(tail)元素的颜色值相同,若相同则tail的num加一并不增加node,若不同则新增一个num为1的node,这样就能保证list里面无重复元素。
1 void insert(DListNode d){ 2 if(size==0){ 3 head=new DListNode(d); 4 tail=head; 5 size=1; 6 } 7 else{ 8 if(d.red==tail.red&&d.green==tail.green&&d.blue==tail.blue){ 9 tail.num++; 10 } 11 else{18 DListNode node=new DListNode(d); 19 tail.next=node; 20 node.prev=tail; 21 tail=node; 22 size++; 23 }24 } 25 } 26 public RunLengthEncoding(PixImage image) { 27 this.width=image.getWidth(); 28 this.height=image.getHeight(); 29 for(int j=0;j<image.getHeight();j++){ 30 for(int i=0;i<image.getWidth();i++){ 31 DListNode node=new DListNode(image.getRed(i, j),image.getGreen(i, j),image.getBlue(i, j),1); 32 list.insert(node); 33 }
part2(c)可以利用part2(b)产生的Runiterator遍历List,code(最开始直接remove List的首元素,后来发现把list中的node全remove走了导致part4没法实现了。。。):
public PixImage toPixImage() { PixImage image=new PixImage(this.width,this.height); int i=0; int j=0; RunIterator runiterator=iterator(); while(runiterator.hasNext()){ int[]a=runiterator.next(); DListNode node=new DListNode(a[0],a[1],a[2],a[3]); for(int k=0;k<node.num;k++){ image.setPixel(i, j, node.red, node.green, node.blue); if(i<this.width-1){ i++; }else{ i=0; j++; } } } return image; }
part4:
part4感觉很麻烦,主要是得考虑很多种情况,我考虑的大致是是否是首尾元素,该node的num是否为一,如果不为一是在node中的首还是尾还是中间,然后再检查和前面的node是否一致,检查和后面的node是否一致。。。好麻烦的感觉:
后来想到个偷懒点的办法,就是可以先不管和前后重复不重复先插入一个新的node,最后再统一调整一遍,code:
public void prevcheck(){ DListNode node=list.head; while(node.next!=null){ if(node.red==node.next.red&&node.green==node.next.green&&node.blue==node.next.blue){ node.num++; node.next.next.prev=node; node.next=node.next.next; } node=node.next; } }
不过即便这样还是得判断插入node的位置,所以前面的分类还是避免不了要考虑到很多种情况(num是否为一?若不为一位于node中具体哪个位置(首位,中间,末位?)还有是否为head或tail。。),如果哪位大佬有更简单的办法跟麻烦告诉我一声,我感觉这个代码写的特别长。。。
运行结果: