[关闭]
@w1024020103 2017-02-03T12:12:09.000000Z 字数 6051 阅读 1269

KdTree.java使用了未经检查或不安全的操作

algorithm princeton coursera


命令行编译报错:
错误:BST.Node可以在BST中访问private
import edu.princeton.cs.algs4.BST.Node

注:KdTree.java使用了未经检查或不安全的操作。
注:有关详细信息,请使用-Xlint:unchecked 重新编译

Then,
1.JPG-30.5kB

`Exception in thread "main" java.lang.NullPointerException

2.JPG-43.3kB

3.JPG-31.2kB
4.JPG-45.9kB

5.JPG-41.7kB

main方法出现了空指针异常

1、NullPointerException是java应用程序中最常见的一种异常,空指针异常
2、空指针异常是一种运行时异常,发生在调用对象的方法或者属性的时候。
3、当对象为null时,调用其任何方法均会报NullPointerException
4、最好的解决办法是在调用一个对象或者集合类时,先判断当前对象是否为null,为null进入其他的业务处理流程。
示例:

Then,
Exception in thread "main" 0.765625 0.515625 java.lang.StackOverflowError
6.JPG-30.2kB
7.JPG-36.6kB
8.JPG-31.3kB
9.JPG-30.3kB

How to solve StackOverflowError

solution:
I changed code line 88
10.JPG-13.3kB

Now there's no Exception, but I don't know why this works.
What is the difference between return new Node(); and t = new Node()
Isn't it true that they both creat an object and takes the same memory? Still confused. And still there's something wrong with the program.

I got result like this:
11.JPG-33.9kB

Next day, I plan to modify the most parts of my codes, using other people's codes as refrences, because my score was too low(41/100) which shows that I might lack background knowledge to actually finish the assignment. I don't want to continue without a clue, so...

I met plenty of problems:
When I wrote

  1. private int cmp(Point2D a, Point2D b, int depth){
  2. if(depth % 2 == 0){
  3. int cmp = (a.x()).compareTo((b.x()));

It doesn't work, has to change to:

  1. private int cmp(Point2D a, Point2D b, int depth){
  2. if(depth % 2 == 0){
  3. int cmp = new Double(a.x()).compareTo(new Double(b.x()));

Why?

After modify(nearly rewrite) insert() method, the output seems correct as the photo shows:

12.JPG-24.5kB
But when I submitted, I still got a low score(54/100)
let's see the feedback:
image_1b80np7od141kn9s17rjlbun01l.png-26.2kB

I checked line 60, which turned out to be an endless recursion.
13.JPG-12.3kB
So, I declaredprivate int size;in KdTree.class,and changed line 60 to:

  1. public int size(){
  2. return this.size;
  3. }

but it doesn't work still, until I added size = 0 in the KdTree constructor.

  1. public KdTree(){
  2. root = null;
  3. size = 0;
  4. }

Don't know why and how size actually know the size of KdTree at all.

Then, I passed corectness tests about insert() method, but still got a low score(66/100) because I failed in almost all contains() method tests. Let's take a look.

As insert(), I changed the comparator which pissed me off(likely read from a pdf named hw5 from Delaware university, it sucked) to a simpler one, but I still am a little bit confused about how to use the recursion. And I passed the contains() related tests.So, now I got 81/100, which is the passing score for the assignment.

My range() method worked fine, but I've got plenty of problems in nearest() method, let's take a look.

I modified my codes according to someone's (tested 95/100) like this:

  1. public Point2D nearest(Point2D p){
  2. if(isEmpty()) {
  3. return null;
  4. }else{
  5. Point2D closestPoint = null;
  6. closestPoint = nearest(root,closestPoint,p);
  7. return closestPoint;
  8. }
  9. }
  10. //what is this Node t, guess it's the starting node when searching for the nearest to the query
  11. //or look it as the current Node
  12. private Point2D nearest(Node t, Point2D closestSofar, Point2D queryPoint){
  13. // because I only have this one point, it has to be the nearest to the query point
  14. if(t != null ){
  15. if( closestSofar == null){
  16. closestSofar = t.p;
  17. }
  18. //closestDistance >= t.rect.distanceSquaredTo(queryPoint) has been mentioned in the video
  19. //it's not very intuitive
  20. if(closestSofar.distanceSquaredTo(queryPoint) >= t.rect.distanceSquaredTo(queryPoint)) {
  21. if(t.p.distanceSquaredTo(queryPoint) < closestSofar.distanceSquaredTo(queryPoint)) {
  22. closestSofar = t.p;
  23. }
  24. }
  25. //determining first search the left or right?
  26. if(t.rt != null && t.rt.rect.contains(queryPoint)){
  27. closestSofar = nearest(t.rt, closestSofar, queryPoint);
  28. closestSofar = nearest(t.lb, closestSofar, queryPoint);
  29. }else{
  30. closestSofar = nearest(t.lb, closestSofar, queryPoint);
  31. closestSofar = nearest(t.rt, closestSofar, queryPoint);
  32. }
  33. }
  34. return closestSofar;
  35. }

This is the original codes i refrenced:

  1. public Point2D nearest(Point2D point) {
  2. if (isEmpty()) {
  3. return null;
  4. } else {
  5. Point2D result = null;
  6. result = nearest(root, point, result);
  7. return result;
  8. }
  9. }
  10. private Point2D nearest(Node x, Point2D point, Point2D min) {
  11. if (x != null) {
  12. if (min == null) {
  13. min = x.p;
  14. }
  15. // If the current min point is closer to query than the current point
  16. if (min.distanceSquaredTo(point)
  17. >= x.rect.distanceSquaredTo(point)) {
  18. if (x.p.distanceSquaredTo(point) < min.distanceSquaredTo(point)) {
  19. min = x.p;
  20. }
  21. // Check in which order should we iterate
  22. if (x.right != null && x.right.rect.contains(point)) {
  23. min = nearest(x.right, point, min);
  24. min = nearest(x.left, point, min);
  25. } else {
  26. min = nearest(x.left, point, min);
  27. min = nearest(x.right, point, min);
  28. }
  29. }
  30. }
  31. return min;
  32. }

I'm trying to figure out what went wrong in my codes, it says things like:

Test 6a: Insert n non-degenerate points and call nearest() with random query points
* 50000 random non-degenerate points in a 100000-by-100000 grid

    ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
    OperationCountLimitExceededException
    Number of calls to methods in Point2D exceeds limit: 1000000000
    ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  • 5000 random non-degenerate points in a 10000-by-10000 grid
    ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
    OperationCountLimitExceededException
    Number of calls to methods in Point2D exceeds limit: 1000000000
    ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  • 500 random non-degenerate points in a 1000-by-1000 grid
    ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
    OperationCountLimitExceededException
    Number of calls to methods in Point2D exceeds limit: 1000000000
    ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

This is annoying, I nearly copied this guy's codes, but mine still got 84/100. let's take a look.

Guess what? I figured out where went wrong in my code, I had placed a "}" in a wrong place. Briefly speaking, as you can see in the above codes, there's three "}" above return closestSofar;, while in my codes there's only two. That's what went wrong. But i haven't thoroughly understand why yet.

btw, I got errors in nearest() method in PointSET.java as well, I modified my codes learning from the same person's codes.
mine that didnt work were like :

  1. public Point2D nearest (Point2D p){ // a nearest neighbor in the set to point p; null if the set is empty
  2. if(isEmpty()) {
  3. return null;
  4. }
  5. Point2D nearestPoint = null;
  6. for(Point2D point : set){
  7. if(point.distanceTo(p)< nearestPoint.distanceTo(p)){
  8. nearestPoint = point;
  9. }
  10. }
  11. return nearestPoint;
  12. }

I changed to:

  1. public Point2D nearest (Point2D p){ // a nearest neighbor in the set to point p; null if the set is empty
  2. if(isEmpty()) {
  3. return null;
  4. }else{
  5. Point2D nearestPoint = null;
  6. for(Point2D point : set){
  7. if(nearestPoint == null || point.distanceTo(p)< nearestPoint.distanceTo(p)){
  8. nearestPoint = point;
  9. }
  10. }
  11. return nearestPoint;
  12. }
  13. }

It worked, now I got 100/100. But I actually still have a lot of problems that I didn't understand need investigations.

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注