『算法』读书笔记 1.2 Java语法 - 练习代码总结

Chapter 1

本章结构

1.1Java语法

1.2数据抽象 练习部分

1.3集合类抽象数据类型:背包 (Bags) 、队列 (Queues) 、栈 (Stacks)

1.4面向操作的抽象数据类型

1.5连通性问题-Case Study: Union - Find ADT

 

1.2.1 编写一个Point2D的用例,从命令行接受一个整数N。在单位正方形内生成N个随机点,然后计算两点之间的最近距离

问题:用例中所采用的双层循环计算两点之间距离的方法有无更好的实现?

   1:  public class ShortDistance {
   2:      public static void main(String[] args)
   3:      {
   4:          int N = Integer.parseInt(args[0]);
   5:          Point2D[] p = new Point2D[N];
   6:          double min = 1.00;
   7:          
   8:          //Generation of N points
   9:          for (int i = 0; i < N; i++)
  10:          {
  11:              double x = Math.random();
  12:              double y = Math.random();
  13:              p[i] = new Point2D(x, y);
  14:              p[i].draw();
  15:          }
  16:          
  17:          //Calculation of minimum distance between two points
  18:          for (int i =0; i < N; i++)
  19:          {
  20:              for (int j = 0; j < N; j++)
  21:              {
  22:                  if (i != j)
  23:                  {
  24:                  if (p[i].distanceTo(p[j]) < min )
  25:                      {
  26:                          min = p[i].distanceTo(p[j]);
  27:                      }
  28:                  }
  29:              }
  30:              
  31:          }
  32:          StdOut.print("the minimum distance is " + min);
  33:      }
  34:   
  35:  }



ex1.2.3 编写一个Interval1D的用例,从命令行接受一个整数N。从标准输入中读取N个间隔(每个间隔由一对double值定义)并打印出所有相交的间隔对

总结:

1.从标准输入中读取数据可以直接利用double[] d = StdIn.readDoubles()实现

2.双层遍历循环中,外层范围限制为[0,N/2),内层范围限制为[N/2,N),这样可以避免循环后再处理重复比较的问题

   1:  public class Interval1DClient
   2:  {
   3:      public static void main(String[] args)
   4:      {
   5:          int N = Integer.parseInt(args[0]);
   6:          Interval1D[] interval = new Interval1D[N];
   7:          double[] d = StdIn.readDoubles();
   8:         
   9:          for (int i = 0; i < N; i++)
  10:          {   
  11:              interval[i] = new Interval1D(d[2*i], d[2*i+1]);
  12:             // StdDraw.line(interval[i].left(), .5, interval[i].right(), 5); 
  13:          }
  14:          
  15:          /*
  16:           * The following codes are for test only
  17:          for (int i = 0; i < N; i++)
  18:          {   
  19:              //interval[i] = new Interval1D(d[2*i], d[2*i+1]);
  20:              StdDraw.line(interval[i].left(), .5, interval[i].right(), .5); 
  21:          }
  22:          */
  23:          
  24:          for (int i = 0; i < N / 2; i++)
  25:          {
  26:              for (int j = N / 2; j < N; j++)
  27:              {
  28:                  if (i != j)
  29:                      if (interval[i].intersects(interval[j]))
  30:                      {     
  31:                          StdDraw.line(interval[i].left(), .5, interval[i].right(), .5);
  32:                          StdOut.println("Interval[" + i + "] intersects with interval[" + j + "].");
  33:                      }
  34:                  
  35:              }
  36:          }
  37:          
  38:      }
  39:  }


  

ex1.2.9 修改BinarySearch,使用COunter统计在键数被查找的次数并在查找全部结束后打印该值

   1:  import java.util.Arrays;
   2:   
   3:  public class BinarySearchCount {
   4:   
   5:      // precondition: array a[] is sorted
   6:      public static int rank(int key, int[] a, Counter keys) {
   7:          int lo = 0;
   8:          int hi = a.length - 1;
   9:          keys.increment();
  10:          while (lo <= hi) {
  11:              // Key is in a[lo..hi] or not present.
  12:              int mid = lo + (hi - lo) / 2;
  13:              if      (key < a[mid]) hi = mid - 1;
  14:              else if (key > a[mid]) lo = mid + 1;
  15:              else return mid;
  16:          }
  17:          return -1;
  18:      }
  19:   
  20:      public static void main(String[] args) {
  21:          Counter keys = new Counter("keys");
  22:          int[] whitelist = In.readInts(args[0]);
  23:   
  24:          Arrays.sort(whitelist);
  25:   
  26:          // read key; print if not in whitelist
  27:          while (!StdIn.isEmpty()) {
  28:              int key = StdIn.readInt();
  29:              if (rank(key, whitelist, keys) == -1)
  30:                  StdOut.println(key);
  31:          }
  32:          StdOut.println("Summary: " + keys + " examined");
  33:      }
  34:  }

 

 

ex1.2.10 编写一个VisualCounter类,支持加一和减一操作。它的构造函数接受两个参数N和max,其中N指定了操作的最大次数,max指定了计数器的最大绝对值。作为副作用,用图像显示每次计数器变化后的值。

总结:

1.构造函数中应该把绘图相关的参数给初始化,例如X和Y轴的取值范围以及笔触的大小

2.Y轴的取值范围特别注意,为正负max,因为要考虑绝对值空间

   1:  public class VisualCounter {
   2:      private int count;//Record the times
   3:      private int val;//Record value of the Counter
   4:      private int x = 0;
   5:      int maxOperation;
   6:      int maxVal;
   7:      
   8:      public VisualCounter(int N, int max)
   9:      {
  10:          maxOperation = N;
  11:          maxVal = max;
  12:          StdDraw.setXscale(0, N);
  13:          StdDraw.setYscale(-max, max);
  14:          StdDraw.setPenRadius(.05);
  15:      }
  16:      
  17:      public int tally()
  18:      {    return count;    }
  19:      
  20:      public void increment()
  21:      {
  22:          if (count < maxOperation && val < maxVal)
  23:          {
  24:              count++;
  25:              val++;
  26:              x++;
  27:              StdDraw.point(x, val);
  28:          }
  29:      }
  30:      
  31:      public void decrement()
  32:      {
  33:          if (count < maxOperation && val > -maxVal)
  34:          {
  35:              count++;
  36:              val--;
  37:              x++;
  38:              StdDraw.point(x, val);
  39:          }
  40:      }
  41:      
  42:      //Test Client
  43:      public static void main(String[] args)
  44:      {
  45:          VisualCounter VC = new VisualCounter(10, 20);
  46:          
  47:          
  48:          VC.increment();
  49:          VC.increment();
  50:          VC.decrement();
  51:          VC.decrement();
  52:          VC.decrement();
  53:          VC.decrement();
  54:          VC.decrement();
  55:          VC.decrement();
  56:          VC.decrement();
  57:          VC.decrement();
  58:          VC.decrement();
  59:          VC.decrement();
  60:   
  61:          
  62:          
  63:          StdOut.println(VC.tally());
  64:          
  65:          
  66:      }
  67:      
  68:  }

 

 

 

ex1.2.11 根据Date的API实现一个SmartDate类型,在日期非法时抛出一个异常

ex1.2.12 为SmartDate添加一个方法dayOfTheWeek(),为日期中每周的日返回Monday、Tuesday、Wednesday、Thursday……假定是21世纪

总结:

1.学习Switch Case语句中多个值匹配同一个代码块的写法

2.Zeller公式可以用来计算dayOfTheWeek

问题:日期合法性判断有无更好的实现?

   1:  public class SmartDate {
   2:      private final int month;
   3:      private final int day;
   4:      private final int year;
   5:      public int dayOfTheWeek;
   6:      
   7:      public SmartDate(int m, int d, int y)
   8:      {    
   9:          month = m; 
  10:          day = d; 
  11:          year = y;
  12:          if (month < 13 && month >0 )
  13:          {
  14:              switch(month)
  15:              {
  16:              case 1:
  17:              case 3:
  18:              case 5:
  19:              case 7:
  20:              case 8:
  21:              case 10:
  22:              case 12:
  23:                  if (day > 31 || day < 1)
  24:                      throw new RuntimeException("Error: illegal Date");
  25:              break;
  26:              
  27:              case 4:
  28:              case 6:
  29:              case 9:
  30:              case 11:
  31:                  if (day > 30 || day < 1)
  32:                      throw new RuntimeException("Error: illegal Date");
  33:              break;
  34:              
  35:              case 2:
  36:                  if (year % 4 == 0)
  37:                  {
  38:                      if (day > 29 || day < 1)
  39:                          throw new RuntimeException("Error: illegal Date");
  40:                  }
  41:                  else if (day > 28 || day < 1)
  42:                      throw new RuntimeException("Error: illegal Date");
  43:              }
  44:          }
  45:          else throw new RuntimeException("Error: illegal Date");
  46:      }
  47:      
  48:      public int month()
  49:      {    return month;    }
  50:      public int day()
  51:      {    return day;        }
  52:      public int year()
  53:      {    return year;    }
  54:      public void dayOfTheWeek()
  55:      {    
  56:          dayOfTheWeek = (year+(year/4)-15+(26*(month+1)/10)+day-1)%7;//using Zeller formula to obtain the value
  57:          switch(dayOfTheWeek)
  58:          {
  59:          case 1:
  60:              StdOut.println("Monday");
  61:              break;
  62:          case 2:
  63:              StdOut.println("Tuesday");
  64:              break;
  65:          case 3:
  66:              StdOut.println("Wednesday");
  67:              break;
  68:          case 4:
  69:              StdOut.println("Thursday");
  70:              break;
  71:          case 5:
  72:              StdOut.println("Friday");
  73:              break;
  74:          case 6:
  75:              StdOut.println("Saturday");
  76:              break;
  77:          case 7:
  78:              StdOut.println("Sunday");
  79:              break;
  80:          }
  81:      }
  82:   
  83:      
  84:      public static void main(String[] args)
  85:      {
  86:          SmartDate SD = new SmartDate(Integer.parseInt(args[0]),Integer.parseInt(args[1]),Integer.parseInt(args[2]));
  87:          SD.dayOfTheWeek();
  88:      }
  89:      
  90:  }

posted @ 2012-12-16 10:34  Memphis Yip  阅读(1484)  评论(0编辑  收藏  举报