前言:
本阶段的题目集比较多,所以可写的内容也很多。在题目集07里,通过类设计和类的继承及多态最后到接口,可以说思路很清晰,不难;在题目集08里,通过图形卡片排序和分组游戏的设计在题目集07上进行升华,也不难;真正从题目集09开始,我们开始学习和运用Map和Set,难度开始上升。在题目集09里,我们去设计一个关键词计数的程序,要求运用Map设计,而尝试了三种方法:List、Set、Map来写,理解了三者的异同并初步理解了使用时机;之后的三次题目集里以课程成绩信息统计大题为主,体现了类与类之间的关系,并对输入数据处理有了更强的要求,在其中也学到了很多,并且能更加自如地运用Comparable接口和Map等相关知识。题量我认为很合理,难度也设计的很好。以下是更为详细的总结:
题目集07:
点与线的类的设计,很简单,为后面的题目做铺垫,没什么好说的,直接上代码:
1 import java.util.*; 2 3 class Point { 4 private double x; 5 private double y; 6 7 public Point() { 8 super(); 9 // TODO 自动生成的构造函数存根 10 } 11 12 public Point(double x, double y) { 13 super(); 14 this.x = x; 15 this.y = y; 16 } 17 18 public double getX() { 19 return x; 20 } 21 22 public void setX(double x) { 23 this.x = x; 24 } 25 26 public double getY() { 27 return y; 28 } 29 30 public void setY(double y) { 31 this.y = y; 32 } 33 34 public void display() { 35 String data = String.format("(%.2f,%.2f)", x, y); 36 System.out.println(data); 37 } 38 39 public boolean checkData() { 40 if(this.x <= 0 || this.x > 200 || this.y <= 0 || this.y > 200) { 41 return false; 42 } 43 return true; 44 } 45 } 46 47 class Line { 48 private Point point1 = new Point(); 49 private Point point2 = new Point(); 50 private String color; 51 52 public Line() { 53 super(); 54 // TODO 自动生成的构造函数存根 55 } 56 57 public Line(Point point1, Point point2, String color) { 58 super(); 59 this.point1 = point1; 60 this.point2 = point2; 61 this.color = color; 62 } 63 64 public Point getPoint1() { 65 return point1; 66 } 67 68 public void setPoint1(Point point1) { 69 this.point1 = point1; 70 } 71 72 public Point getPoint2() { 73 return point2; 74 } 75 76 public void setPoint2(Point point2) { 77 this.point2 = point2; 78 } 79 80 public String getColor() { 81 return color; 82 } 83 84 public void setColor(String color) { 85 this.color = color; 86 } 87 88 public double getDistance() { 89 double s = Math.pow(point1.getX() - point2.getX(), 2) + Math.pow(point1.getY() - point2.getY(), 2); 90 return Math.sqrt(s); 91 } 92 93 public void display() { 94 95 if(point1.checkData() && point2.checkData()) { 96 double distance = getDistance(); 97 String dis = String.format("%.2f", distance); 98 System.out.println("The line's color is:" + color); 99 System.out.println("The line's begin point's Coordinate is:"); 100 point1.display(); 101 System.out.println("The line's end point's Coordinate is:"); 102 point2.display(); 103 System.out.println("The line's length is:" + dis); 104 } else { 105 System.out.println("Wrong Format"); 106 } 107 } 108 109 } 110 111 public class Main { 112 113 public static void main(String[] args) { 114 Scanner input = new Scanner(System.in); 115 116 double x1 = input.nextDouble(); 117 double y1 = input.nextDouble(); 118 double x2 = input.nextDouble(); 119 double y2 = input.nextDouble(); 120 String color = input.next(); 121 122 Point point1 = new Point(x1, y1); 123 Point point2 = new Point(x2, y2); 124 125 Line line = new Line(point1, point2, color); 126 127 line.display(); 128 129 } 130 }
1 import java.util.*; 2 3 abstract class AbstractShape { 4 public abstract double getArea(); 5 public abstract void showArea(); 6 } 7 8 class Circle extends AbstractShape { 9 private double radius; 10 11 public Circle() { 12 super(); 13 // TODO 自动生成的构造函数存根 14 } 15 16 public Circle(double radius) { 17 super(); 18 this.radius = radius; 19 } 20 21 public double getRadius() { 22 return radius; 23 } 24 25 public void setRadius(double radius) { 26 this.radius = radius; 27 } 28 29 @Override 30 public double getArea() { 31 // TODO 自动生成的方法存根 32 return Math.PI * Math.pow(radius, 2); 33 } 34 35 @Override 36 public void showArea() { 37 // TODO 自动生成的方法存根 38 String area = String.format("%.2f", getArea()); 39 System.out.println("Type:Circle,Area:" + area); 40 } 41 } 42 43 class Ball extends Circle { 44 45 public Ball() { 46 super(); 47 // TODO 自动生成的构造函数存根 48 } 49 50 public Ball(double radius) { 51 super(radius); 52 // TODO 自动生成的构造函数存根 53 } 54 55 @Override 56 public double getArea() { 57 return 4 * Math.PI * Math.pow(getRadius(), 2); 58 } 59 60 @Override 61 public void showArea() { 62 String area = String.format("%.2f", getArea()); 63 System.out.println("Type:Ball,Area:" + area); 64 } 65 } 66 67 class Rectangle extends AbstractShape { 68 69 private double width; 70 private double length; 71 72 public Rectangle() { 73 super(); 74 // TODO 自动生成的构造函数存根 75 } 76 77 public Rectangle(double width, double length) { 78 super(); 79 this.width = width; 80 this.length = length; 81 } 82 83 public double getWidth() { 84 return width; 85 } 86 87 public void setWidth(double width) { 88 this.width = width; 89 } 90 91 public double getLength() { 92 return length; 93 } 94 95 public void setLength(double length) { 96 this.length = length; 97 } 98 99 @Override 100 public double getArea() { 101 return this.width * this.length; 102 } 103 104 @Override 105 public void showArea() { 106 String area = String.format("%.2f", getArea()); 107 System.out.println("Type:Rectangle,Area:" + area); 108 } 109 } 110 111 class Box extends Rectangle { 112 private double height; 113 114 public Box() { 115 super(); 116 // TODO 自动生成的构造函数存根 117 } 118 119 public Box(double width, double length, double height) { 120 super(width, length); 121 this.height = height; 122 // TODO 自动生成的构造函数存根 123 } 124 125 public double getHeight() { 126 return height; 127 } 128 129 public void setHeight(double height) { 130 this.height = height; 131 } 132 133 @Override 134 public double getArea() { 135 return 2*(getWidth()*getLength() + getWidth()*height + getLength()*height); 136 } 137 138 @Override 139 public void showArea() { 140 String area = String.format("%.2f", getArea()); 141 System.out.println("Type:Box,Area:" + area); 142 } 143 } 144 145 public class Main { 146 147 public static void main(String[] args) { 148 Scanner in = new Scanner(System.in); 149 150 int choice = in.nextInt(); 151 152 switch(choice) { 153 case 1: // 构建圆 154 double radius = in.nextDouble(); 155 if(radius > 0) { 156 AbstractShape circle = new Circle(radius); 157 circle.showArea(); 158 } else { 159 System.out.println("Wrong Format"); 160 } 161 162 163 break; 164 case 2: // 构建矩形 165 double width = in.nextDouble(); 166 double length = in.nextDouble(); 167 if(width > 0 && length > 0) { 168 AbstractShape rectangle = new Rectangle(width, length); 169 rectangle.showArea(); 170 } else { 171 System.out.println("Wrong Format"); 172 } 173 174 break; 175 case 3: // 构建球 176 double radius1 = in.nextDouble(); 177 if(radius1 > 0) { 178 Ball ball = new Ball(radius1); 179 ball.showArea(); 180 } else { 181 System.out.println("Wrong Format"); 182 } 183 break; 184 case 4: // 构建立方体 185 double width1 = in.nextDouble(); 186 double length1 = in.nextDouble(); 187 double height = in.nextDouble(); 188 if(width1 > 0 && length1 > 0 && height > 0) { 189 Box box = new Box(width1, length1, height); 190 box.showArea(); 191 192 } else { 193 System.out.println("Wrong Format"); 194 } 195 break; 196 default: 197 System.out.println("Wrong Format"); 198 break; 199 } 200 } 201 }
1 import java.util.*; 2 3 abstract class AbstractShape implements Comparable<AbstractShape> { 4 public abstract double getArea(); 5 public abstract void show(); 6 7 @Override 8 public int compareTo(AbstractShape o) { 9 // TODO 自动生成的方法存根 10 if(getArea() > o.getArea()) { 11 return 1; 12 } else if(getArea() < o.getArea()) { 13 return -1; 14 } else { 15 return 0; 16 } 17 } 18 } 19 20 class Circle extends AbstractShape { 21 private double radius; 22 23 public Circle() { 24 super(); 25 // TODO 自动生成的构造函数存根 26 } 27 28 public Circle(double radius) { 29 super(); 30 this.radius = radius; 31 } 32 33 public double getRadius() { 34 return radius; 35 } 36 37 public void setRadius(double radius) { 38 this.radius = radius; 39 } 40 41 @Override 42 public double getArea() { 43 // TODO 自动生成的方法存根 44 return Math.PI * Math.pow(radius, 2); 45 } 46 47 @Override 48 public void show() { 49 // TODO 自动生成的方法存根 50 String area = String.format("%.2f", getArea()); 51 System.out.println("Type:Circle,Area:" + area); 52 } 53 } 54 55 class Ball extends Circle { 56 57 public Ball() { 58 super(); 59 // TODO 自动生成的构造函数存根 60 } 61 62 public Ball(double radius) { 63 super(radius); 64 // TODO 自动生成的构造函数存根 65 } 66 67 @Override 68 public double getArea() { 69 // TODO 自动生成的方法存根 70 return 4 * Math.pow(getRadius(), 2) * Math.PI; 71 } 72 73 @Override 74 public void show() { 75 // TODO 自动生成的方法存根 76 String area = String.format("%.2f", getArea()); 77 System.out.println("Type:Ball,Area:" + area); 78 } 79 } 80 81 class Rectangle extends AbstractShape { 82 83 private double width; 84 private double length; 85 86 public Rectangle() { 87 super(); 88 // TODO 自动生成的构造函数存根 89 } 90 91 public Rectangle(double width, double length) { 92 super(); 93 this.width = width; 94 this.length = length; 95 } 96 97 public double getWidth() { 98 return width; 99 } 100 101 public void setWidth(double width) { 102 this.width = width; 103 } 104 105 public double getLength() { 106 return length; 107 } 108 109 public void setLength(double length) { 110 this.length = length; 111 } 112 113 @Override 114 public double getArea() { 115 // TODO 自动生成的方法存根 116 return this.width * this.length; 117 } 118 119 @Override 120 public void show() { 121 // TODO 自动生成的方法存根 122 String area = String.format("%.2f", getArea()); 123 System.out.println("Type:Rectangle,Area:" + area); 124 } 125 } 126 127 class Box extends Rectangle { 128 private double height; 129 130 public Box() { 131 super(); 132 // TODO 自动生成的构造函数存根 133 } 134 135 public Box(double width, double length, double height) { 136 super(width, length); 137 this.height = height; 138 // TODO 自动生成的构造函数存根 139 } 140 141 public double getHeight() { 142 return height; 143 } 144 145 public void setHeight(double height) { 146 this.height = height; 147 } 148 149 @Override 150 public double getArea() { 151 // TODO 自动生成的方法存根 152 return 2*(getWidth()*getLength() + getWidth()*height + getLength()*height); 153 } 154 155 @Override 156 public void show() { 157 // TODO 自动生成的方法存根 158 String area = String.format("%.2f", getArea()); 159 System.out.println("Type:Box,Area:" + area); 160 } 161 } 162 163 class ShapeUtil { 164 165 private ArrayList<AbstractShape> list = new ArrayList<>(); 166 167 public ShapeUtil() { 168 super(); 169 // TODO 自动生成的构造函数存根 170 } 171 172 public void init() { // 初始化用户输入 173 int choice = Main.input.nextInt(); 174 175 while(choice >= 1 || choice <= 4) { 176 switch(choice) { 177 case 1: // 生成一个圆 178 double radius = Main.input.nextDouble(); 179 if(radius > 0) { 180 Circle circle = new Circle(radius); 181 list.add(circle); 182 } else { 183 System.out.println("Wrong Format"); 184 } 185 choice = Main.input.nextInt(); 186 break; 187 case 2: // 生成一个矩形 188 double width = Main.input.nextDouble(); 189 double length = Main.input.nextDouble(); 190 if(width > 0 && length > 0) { 191 Rectangle rectangle = new Rectangle(width, length); 192 list.add(rectangle); 193 } else { 194 System.out.println("Wrong Format"); 195 } 196 choice = Main.input.nextInt(); 197 break; 198 case 3: // 生成一个球 199 double radius1 = Main.input.nextDouble(); 200 if(radius1 > 0) { 201 Ball ball = new Ball(radius1); 202 list.add(ball); 203 } else { 204 System.out.println("Wrong Format"); 205 } 206 choice = Main.input.nextInt(); 207 break; 208 case 4: // 生成一个立方体 209 double width1 = Main.input.nextDouble(); 210 double length1 = Main.input.nextDouble(); 211 double height = Main.input.nextDouble(); 212 if(width1 > 0 && length1 > 0 && height > 0) { 213 Box box = new Box(width1, length1, height); 214 list.add(box); 215 } else { 216 System.out.println("Wrong Format"); 217 } 218 choice = Main.input.nextInt(); 219 break; 220 default: 221 return ; 222 } 223 } 224 } 225 226 public void shapeSort() { // Collections分类,强大! 227 Collections.sort(list); 228 } 229 230 public AbstractShape Max() { 231 AbstractShape maxShape = list.get(0); 232 for(AbstractShape shape : list) { 233 if(maxShape.compareTo(shape) == -1) { 234 maxShape = shape; 235 } 236 } 237 return maxShape; 238 } 239 240 public AbstractShape Min() { 241 AbstractShape minShape = list.get(0); 242 for(AbstractShape shape : list) { 243 if(minShape.compareTo(shape) == 1) { 244 minShape = shape; 245 } 246 } 247 return minShape; 248 } 249 250 public double getSumArea() { 251 double sum = 0.0; 252 for(AbstractShape shape : list) { 253 sum += shape.getArea(); 254 } 255 return sum; 256 } 257 258 public void show() { 259 System.out.println("The sorted shape:"); 260 shapeSort(); 261 for(AbstractShape shape : list) { 262 shape.show(); 263 } 264 } 265 } 266 267 268 public class Main { 269 270 public static Scanner input = new Scanner(System.in); 271 272 public static void main(String[] args) { 273 ShapeUtil s = new ShapeUtil(); 274 s.init(); 275 276 int choice = input.nextInt(); 277 278 switch(choice) { 279 case 1: // 输出最大面积者 280 System.out.print("MAX:"); 281 s.Max().show(); 282 break; 283 case 2: // 输出最小面积者 284 System.out.print("MIN:"); 285 s.Min().show(); 286 break; 287 case 3: // 输出所有面积的总和 288 String sum = String.format("%.2f", s.getSumArea()); 289 System.out.print("Sum of area:" + sum); 290 break; 291 case 4: // 输出升序排序后的所有数据 292 s.show(); 293 break; 294 default : 295 return ; 296 } 297 } 298 }
类图和sourceMonitor:
题目集08:
题目集08围绕两个游戏展开,训练了类的继承和多态和接口应用。不难,就是要自己分清楚类与类之间的关系并仔细审题来写。
1 //package 图形卡片排序游戏; 2 3 import java.util.*; 4 import java.util.ArrayList; 5 6 abstract class Shape{ 7 8 public abstract boolean validate(); 9 public abstract double getArea(); // 获取图形面积 10 public abstract void showArea(); // 输出图形面积 11 } 12 13 class Circle extends Shape { 14 15 private double radiums; 16 17 18 19 public Circle() { 20 super(); 21 // TODO 自动生成的构造函数存根 22 } 23 24 public Circle(double radiums) { 25 super(); 26 this.radiums = radiums; 27 } 28 29 public double getRadiums() { 30 return radiums; 31 } 32 33 public void setRadiums(double radiums) { 34 this.radiums = radiums; 35 } 36 37 @Override 38 public double getArea() { 39 // TODO 自动生成的方法存根 40 return this.radiums * this.radiums * Math.PI; 41 } 42 43 @Override 44 public void showArea() { 45 // TODO 自动生成的方法存根 46 String area = String.format("%.2f", getArea()); 47 System.out.print("Circle:" + area); 48 } 49 50 @Override 51 public boolean validate() { 52 // TODO 自动生成的方法存根 53 if(this.radiums <= 0) { 54 return false; 55 } 56 return true; 57 } 58 } 59 60 class Rectangle extends Shape { 61 62 private double length; 63 private double width; 64 65 public Rectangle() { 66 super(); 67 // TODO 自动生成的构造函数存根 68 } 69 70 public Rectangle(double length, double width) { 71 super(); 72 this.length = length; 73 this.width = width; 74 } 75 76 public double getLength() { 77 return length; 78 } 79 80 public void setLength(double length) { 81 this.length = length; 82 } 83 84 public double getWidth() { 85 return width; 86 } 87 88 public void setWidth(double width) { 89 this.width = width; 90 } 91 92 @Override 93 public double getArea() { 94 // TODO 自动生成的方法存根 95 return this.length * this.width; 96 } 97 98 @Override 99 public void showArea() { 100 // TODO 自动生成的方法存根 101 String area = String.format("%.2f", getArea()); 102 System.out.print("Rectangle:" + area); 103 } 104 105 @Override 106 public boolean validate() { 107 // TODO 自动生成的方法存根 108 if(this.length <= 0 || this.width <= 0) { 109 return false; 110 } 111 return true; 112 } 113 114 } 115 116 class Triangle extends Shape { 117 118 private double side1; 119 private double side2; 120 private double side3; 121 122 public Triangle() { 123 super(); 124 // TODO 自动生成的构造函数存根 125 } 126 127 128 public double getSide1() { 129 return side1; 130 } 131 132 133 public void setSide1(double side1) { 134 this.side1 = side1; 135 } 136 137 138 public double getSide2() { 139 return side2; 140 } 141 142 143 public void setSide2(double side2) { 144 this.side2 = side2; 145 } 146 147 148 public double getSide3() { 149 return side3; 150 } 151 152 153 public void setSide3(double side3) { 154 this.side3 = side3; 155 } 156 157 158 public Triangle(double side1, double side2, double side3) { 159 super(); 160 this.side1 = side1; 161 this.side2 = side2; 162 this.side3 = side3; 163 } 164 165 166 public boolean validate() { 167 // 先排序 168 if(side1 > side2) { 169 double t = side1; 170 side1 = side2; 171 side2 = t; 172 } 173 if(side1 > side3) { 174 double t = side1; 175 side1 = side3; 176 side3 = t; 177 } 178 if(side2 > side3) { 179 double t = side2; 180 side2 = side3; 181 side3 = t; 182 } 183 184 if(side1 <= 0 || side1 + side2 <= side3) { 185 return false; 186 } 187 188 return true; 189 } 190 191 @Override 192 public double getArea() { 193 // TODO 自动生成的方法存根 194 double p = (side1 + side2 + side3) / 2; // 海伦公式的p 195 double area = Math.sqrt(p * (p - side1) * (p - side2) * (p - side3)); // 三角形面积海伦公式 196 return area; 197 } 198 199 @Override 200 public void showArea() { 201 // TODO 自动生成的方法存根 202 String area = String.format("%.2f", getArea()); 203 System.out.print("Triangle:" + area); 204 } 205 206 } 207 208 class Trapezoid extends Shape { 209 210 private double topSide; 211 private double bottomSide; 212 private double height; 213 214 public Trapezoid() { 215 super(); 216 // TODO 自动生成的构造函数存根 217 } 218 219 public Trapezoid(double topSide, double bottomSide, double height) { 220 super(); 221 this.topSide = topSide; 222 this.bottomSide = bottomSide; 223 this.height = height; 224 } 225 226 public double getUpSide() { 227 return topSide; 228 } 229 230 public void setUpSide(double upSide) { 231 this.topSide = upSide; 232 } 233 234 public double getDownSide() { 235 return bottomSide; 236 } 237 238 public void setDownSide(double downSide) { 239 this.bottomSide = downSide; 240 } 241 242 public double getHeight() { 243 return height; 244 } 245 246 public void setHeight(double height) { 247 this.height = height; 248 } 249 250 @Override 251 public double getArea() { 252 // TODO 自动生成的方法存根 253 return (this.topSide + this.bottomSide) * this.height / 2; 254 } 255 256 @Override 257 public void showArea() { 258 // TODO 自动生成的方法存根 259 String area = String.format("%.2f", getArea()); 260 System.out.print("Trapezoid:" + area); 261 } 262 263 @Override 264 public boolean validate() { 265 // TODO 自动生成的方法存根 266 if(this.bottomSide <= 0 || this.topSide <= 0 || this.height <= 0) { 267 return false; 268 } 269 return true; 270 } 271 272 } 273 274 class Card implements Comparable<Card>{ 275 276 private Shape shape; 277 278 public Card() { 279 super(); 280 // TODO 自动生成的构造函数存根 281 } 282 283 public Card(Shape shape) { 284 super(); 285 this.shape = shape; 286 } 287 288 public Shape getShape() { 289 return shape; 290 } 291 292 public void setShape(Shape shape) { 293 this.shape = shape; 294 } 295 296 @Override 297 public int compareTo(Card o) { 298 // TODO 自动生成的方法存根 299 if(this.shape.getArea() > o.getShape().getArea()) { 300 return 1; 301 } 302 if(this.shape.getArea() < o.getShape().getArea()) { 303 return -1; 304 } 305 return 0; 306 } 307 308 } 309 310 class DealCardList { 311 312 protected ArrayList<Card> cardList = new ArrayList<>(); 313 314 public DealCardList() { 315 super(); 316 // TODO 自动生成的构造函数存根 317 } 318 319 public DealCardList(ArrayList<Integer> list) { 320 for(int i : list) { 321 switch(i) { 322 case 1: // 创建圆卡牌对象 323 double radium = Main.input.nextDouble(); 324 Shape circle = new Circle(radium); 325 Card card1 = new Card(circle); 326 cardList.add(card1); 327 break; 328 case 2: // 创建矩形卡牌对象 329 double length = Main.input.nextDouble(); 330 double width = Main.input.nextDouble(); 331 Shape rectangle = new Rectangle(length, width); 332 Card card2 = new Card(rectangle); 333 cardList.add(card2); 334 break; 335 case 3: // 创建三角形卡牌对象 336 double side1 = Main.input.nextDouble(); 337 double side2 = Main.input.nextDouble(); 338 double side3 = Main.input.nextDouble(); 339 Shape triangle = new Triangle(side1, side2, side3); 340 Card card3 = new Card(triangle); 341 cardList.add(card3); 342 break; 343 case 4: // 创建梯形卡牌对象 344 double topSide = Main.input.nextDouble(); 345 double bottomSide = Main.input.nextDouble(); 346 double height = Main.input.nextDouble(); 347 Shape trapezoid = new Trapezoid(topSide, bottomSide, height); 348 Card card4 = new Card(trapezoid); 349 cardList.add(card4); 350 break; 351 // default : 352 // System.out.println("Wrong Format"); 353 // 354 } 355 } 356 357 } 358 359 public boolean validate() { 360 for(Card c : cardList) { 361 if(!c.getShape().validate()) { 362 return false; 363 } 364 } 365 return true; 366 } 367 368 public void cardSort() { // 从大到小分类 369 cardList.sort(Collections.reverseOrder()); 370 } 371 372 public double getAllArea() { 373 double allArea = 0.0; 374 for(Card c : cardList) { 375 allArea += c.getShape().getArea(); 376 } 377 return allArea; 378 } 379 380 public void showResult() { 381 String allArea = String.format("%.2f", getAllArea()); 382 383 System.out.println("The original list:"); 384 for(Card c : cardList) { 385 c.getShape().showArea(); 386 System.out.print(" "); 387 } 388 System.out.println(); 389 cardSort(); 390 System.out.println("The sorted list:"); 391 for(Card c : cardList) { 392 c.getShape().showArea(); 393 System.out.print(" "); 394 } 395 System.out.println(); 396 System.out.println("Sum of area:" + allArea); 397 } 398 399 } 400 401 public class Main { 402 // 在Main类中定义一个静态Scanner对象,这样在其它类中如果想要使用该对象进行输入,则直接 403 // 使用Main.input.next…即可(避免采坑) 404 public static Scanner input = new Scanner(System.in); 405 406 public static void main(String[] args){ 407 ArrayList<Integer> list = new ArrayList<Integer>(); 408 int num = input.nextInt(); 409 while(num != 0){ 410 if(num < 0 || num > 4) { 411 System.out.println("Wrong Format"); 412 System.exit(0); 413 } 414 list.add(num); 415 num = input.nextInt(); 416 } 417 DealCardList dealCardList = new DealCardList(list); 418 if(!dealCardList.validate()) { 419 System.out.println("Wrong Format"); 420 System.exit(0); 421 } 422 dealCardList.showResult(); 423 input.close(); 424 } 425 }
这题我认为可以修改的点的是可以把输入简化。
我的输入:
没必要再实体化三个double类的数据,直接在创建类时输入就好了。但是这样写问题也不大。
1 import java.util.*; 2 import java.util.ArrayList; 3 4 abstract class Shape{ 5 6 public abstract boolean validate(); 7 public abstract double getArea(); // 获取图形面积 8 public abstract void showArea(); // 输出图形面积 9 } 10 11 class Circle extends Shape { 12 13 private double radiums; 14 15 16 17 public Circle() { 18 super(); 19 // TODO 自动生成的构造函数存根 20 } 21 22 public Circle(double radiums) { 23 super(); 24 this.radiums = radiums; 25 } 26 27 public double getRadiums() { 28 return radiums; 29 } 30 31 public void setRadiums(double radiums) { 32 this.radiums = radiums; 33 } 34 35 @Override 36 public double getArea() { 37 // TODO 自动生成的方法存根 38 return this.radiums * this.radiums * Math.PI; 39 } 40 41 @Override 42 public void showArea() { 43 // TODO 自动生成的方法存根 44 String area = String.format("%.2f", getArea()); 45 System.out.print("Circle:" + area + " "); 46 } 47 48 @Override 49 public boolean validate() { 50 // TODO 自动生成的方法存根 51 if(this.radiums <= 0) { 52 return false; 53 } 54 return true; 55 } 56 } 57 58 class Rectangle extends Shape { 59 60 private double length; 61 private double width; 62 63 public Rectangle() { 64 super(); 65 // TODO 自动生成的构造函数存根 66 } 67 68 public Rectangle(double length, double width) { 69 super(); 70 this.length = length; 71 this.width = width; 72 } 73 74 public double getLength() { 75 return length; 76 } 77 78 public void setLength(double length) { 79 this.length = length; 80 } 81 82 public double getWidth() { 83 return width; 84 } 85 86 public void setWidth(double width) { 87 this.width = width; 88 } 89 90 @Override 91 public double getArea() { 92 // TODO 自动生成的方法存根 93 return this.length * this.width; 94 } 95 96 @Override 97 public void showArea() { 98 // TODO 自动生成的方法存根 99 String area = String.format("%.2f", getArea()); 100 System.out.print("Rectangle:" + area + " "); 101 } 102 103 @Override 104 public boolean validate() { 105 // TODO 自动生成的方法存根 106 if(this.length <= 0 || this.width <= 0) { 107 return false; 108 } 109 return true; 110 } 111 112 } 113 114 class Triangle extends Shape { 115 116 private double side1; 117 private double side2; 118 private double side3; 119 120 public Triangle() { 121 super(); 122 // TODO 自动生成的构造函数存根 123 } 124 125 126 public double getSide1() { 127 return side1; 128 } 129 130 131 public void setSide1(double side1) { 132 this.side1 = side1; 133 } 134 135 136 public double getSide2() { 137 return side2; 138 } 139 140 141 public void setSide2(double side2) { 142 this.side2 = side2; 143 } 144 145 146 public double getSide3() { 147 return side3; 148 } 149 150 151 public void setSide3(double side3) { 152 this.side3 = side3; 153 } 154 155 156 public Triangle(double side1, double side2, double side3) { 157 super(); 158 this.side1 = side1; 159 this.side2 = side2; 160 this.side3 = side3; 161 } 162 163 164 public boolean validate() { 165 // 先排序 166 if(side1 > side2) { 167 double t = side1; 168 side1 = side2; 169 side2 = t; 170 } 171 if(side1 > side3) { 172 double t = side1; 173 side1 = side3; 174 side3 = t; 175 } 176 if(side2 > side3) { 177 double t = side2; 178 side2 = side3; 179 side3 = t; 180 } 181 182 if(side1 <= 0 || side1 + side2 <= side3) { 183 return false; 184 } 185 186 return true; 187 } 188 189 @Override 190 public double getArea() { 191 // TODO 自动生成的方法存根 192 double p = (side1 + side2 + side3) / 2; // 海伦公式的p 193 double area = Math.sqrt(p * (p - side1) * (p - side2) * (p - side3)); // 三角形面积海伦公式 194 return area; 195 } 196 197 @Override 198 public void showArea() { 199 // TODO 自动生成的方法存根 200 String area = String.format("%.2f", getArea()); 201 System.out.print("Triangle:" + area + " "); 202 } 203 204 } 205 206 class Trapezoid extends Shape { 207 208 private double topSide; 209 private double bottomSide; 210 private double height; 211 212 public Trapezoid() { 213 super(); 214 // TODO 自动生成的构造函数存根 215 } 216 217 public Trapezoid(double topSide, double bottomSide, double height) { 218 super(); 219 this.topSide = topSide; 220 this.bottomSide = bottomSide; 221 this.height = height; 222 } 223 224 public double getUpSide() { 225 return topSide; 226 } 227 228 public void setUpSide(double upSide) { 229 this.topSide = upSide; 230 } 231 232 public double getDownSide() { 233 return bottomSide; 234 } 235 236 public void setDownSide(double downSide) { 237 this.bottomSide = downSide; 238 } 239 240 public double getHeight() { 241 return height; 242 } 243 244 public void setHeight(double height) { 245 this.height = height; 246 } 247 248 @Override 249 public double getArea() { 250 // TODO 自动生成的方法存根 251 return (this.topSide + this.bottomSide) * this.height / 2; 252 } 253 254 @Override 255 public void showArea() { 256 // TODO 自动生成的方法存根 257 String area = String.format("%.2f", getArea()); 258 System.out.print("Trapezoid:" + area + " "); 259 } 260 261 @Override 262 public boolean validate() { 263 // TODO 自动生成的方法存根 264 if(this.bottomSide <= 0 || this.topSide <= 0 || this.height <= 0) { 265 return false; 266 } 267 return true; 268 } 269 270 } 271 272 class Card implements Comparable<Card>{ 273 274 private Shape shape; 275 276 public Card() { 277 super(); 278 // TODO 自动生成的构造函数存根 279 } 280 281 public Card(Shape shape) { 282 super(); 283 this.shape = shape; 284 } 285 286 public Shape getShape() { 287 return shape; 288 } 289 290 public void setShape(Shape shape) { 291 this.shape = shape; 292 } 293 294 @Override 295 public int compareTo(Card o) { 296 // TODO 自动生成的方法存根 297 if(this.shape.getArea() > o.getShape().getArea()) { 298 return 1; 299 } 300 if(this.shape.getArea() < o.getShape().getArea()) { 301 return -1; 302 } 303 return 0; 304 } 305 306 } 307 308 class DealCardList { 309 310 protected ArrayList<Card> allCardList = new ArrayList<>(); 311 protected ArrayList<Card> circleCardList = new ArrayList<>(); 312 protected ArrayList<Card> rectangleCardList = new ArrayList<>(); 313 protected ArrayList<Card> triangleCardList = new ArrayList<>(); 314 protected ArrayList<Card> trapezoidCardList = new ArrayList<>(); 315 316 317 public DealCardList() { 318 super(); 319 // TODO 自动生成的构造函数存根 320 } 321 322 public DealCardList(ArrayList<Integer> list) { 323 for(int i : list) { 324 switch(i) { 325 case 1: // 创建圆卡牌对象 326 double radium = Main.input.nextDouble(); 327 Shape circle = new Circle(radium); 328 Card card1 = new Card(circle); 329 circleCardList.add(card1); 330 allCardList.add(card1); 331 break; 332 case 2: // 创建矩形卡牌对象 333 double length = Main.input.nextDouble(); 334 double width = Main.input.nextDouble(); 335 Shape rectangle = new Rectangle(length, width); 336 Card card2 = new Card(rectangle); 337 rectangleCardList.add(card2); 338 allCardList.add(card2); 339 break; 340 case 3: // 创建三角形卡牌对象 341 double side1 = Main.input.nextDouble(); 342 double side2 = Main.input.nextDouble(); 343 double side3 = Main.input.nextDouble(); 344 Shape triangle = new Triangle(side1, side2, side3); 345 Card card3 = new Card(triangle); 346 triangleCardList.add(card3); 347 allCardList.add(card3); 348 break; 349 case 4: // 创建梯形卡牌对象 350 double topSide = Main.input.nextDouble(); 351 double bottomSide = Main.input.nextDouble(); 352 double height = Main.input.nextDouble(); 353 Shape trapezoid = new Trapezoid(topSide, bottomSide, height); 354 Card card4 = new Card(trapezoid); 355 trapezoidCardList.add(card4); 356 allCardList.add(card4); 357 break; 358 } 359 } 360 } 361 362 public boolean validate() { 363 for(Card c : allCardList) { 364 if(!c.getShape().validate()) { 365 return false; 366 } 367 } 368 return true; 369 } 370 371 public void cardSort(ArrayList<Card> cardList) { // 从大到小分类 372 cardList.sort(Collections.reverseOrder()); 373 } 374 375 public double getAllArea(ArrayList<Card> cardList) { 376 double allArea = 0.0; 377 for(Card c : cardList) { 378 allArea += c.getShape().getArea(); 379 } 380 return allArea; 381 } 382 383 public void showResult() { 384 385 // 输出所有按照输入顺序的对象 386 System.out.println("The original list:"); 387 System.out.print("["); 388 for(Card c : allCardList) { 389 c.getShape().showArea(); 390 } 391 System.out.println("]"); 392 393 // 分类输出四类卡牌对象 394 System.out.println("The Separated List:"); 395 System.out.print("["); 396 for(Card circle : circleCardList) { 397 circle.getShape().showArea(); 398 } 399 System.out.print("]"); // 圆类卡牌输出完成 400 401 System.out.print("["); 402 for(Card rectangle : rectangleCardList) { 403 rectangle.getShape().showArea(); 404 } 405 System.out.print("]"); // 矩形类卡牌输出完成 406 407 System.out.print("["); 408 for(Card triangle : triangleCardList) { 409 triangle.getShape().showArea(); 410 } 411 System.out.print("]"); // 三角形类卡牌输出完成 412 413 System.out.print("["); 414 for(Card trapezoid : trapezoidCardList) { 415 trapezoid.getShape().showArea(); 416 } 417 System.out.println("]"); // 梯形类卡牌输出完成 418 419 // 先排序各图形类里的对象 420 cardSort(circleCardList); 421 cardSort(rectangleCardList); 422 cardSort(triangleCardList); 423 cardSort(trapezoidCardList); 424 // 再输出排序后的数据 425 System.out.println("The Separated sorted List:"); 426 System.out.print("["); 427 for(Card circle : circleCardList) { 428 circle.getShape().showArea(); 429 } 430 System.out.print("]"); // 圆类卡牌输出完成 431 432 System.out.print("["); 433 for(Card rectangle : rectangleCardList) { 434 rectangle.getShape().showArea(); 435 } 436 System.out.print("]"); // 矩形类卡牌输出完成 437 438 System.out.print("["); 439 for(Card triangle : triangleCardList) { 440 triangle.getShape().showArea(); 441 } 442 System.out.print("]"); // 三角形类卡牌输出完成 443 444 System.out.print("["); 445 for(Card trapezoid : trapezoidCardList) { 446 trapezoid.getShape().showArea(); 447 } 448 System.out.println("]"); // 梯形类卡牌输出完成 449 450 // 输出四大类里面积之和最大的值 451 double maxArea = 0.0; 452 // 先找出最大的面积之和的值 453 if(maxArea < getAllArea(circleCardList)) { 454 maxArea = getAllArea(circleCardList); 455 } 456 if(maxArea < getAllArea(rectangleCardList)) { 457 maxArea = getAllArea(rectangleCardList); 458 } 459 if(maxArea < getAllArea(triangleCardList)) { 460 maxArea = getAllArea(triangleCardList); 461 } 462 if(maxArea < getAllArea(trapezoidCardList)) { 463 maxArea = getAllArea(trapezoidCardList); 464 } 465 // 再将其转化成字符串 466 String theMaxArea = String.format("%.2f", maxArea); 467 System.out.println("The max area:" + theMaxArea); 468 469 } 470 471 } 472 473 public class Main { 474 // 在Main类中定义一个静态Scanner对象,这样在其它类中如果想要使用该对象进行输入,则直接 475 // 使用Main.input.next…即可(避免采坑) 476 public static Scanner input = new Scanner(System.in); 477 478 public static void main(String[] args){ 479 ArrayList<Integer> list = new ArrayList<Integer>(); 480 int num = input.nextInt(); 481 if(num == 0) { 482 System.out.println("Wrong Format"); 483 System.exit(0); 484 } 485 while(num != 0){ 486 if(num < 0 || num > 4) { 487 System.out.println("Wrong Format"); 488 System.exit(0); 489 } 490 list.add(num); 491 num = input.nextInt(); 492 } 493 DealCardList dealCardList = new DealCardList(list); 494 if(!dealCardList.validate()) { 495 System.out.println("Wrong Format"); 496 System.exit(0); 497 } 498 dealCardList.showResult(); 499 input.close(); 500 } 501 }
同上一题,就是最后输出格式麻烦点。
题目集09:
统计一段代码中出现的关键词次数,不统计注释内的内容。这题我尝试了三种方法来写,对Map和Set有了更深的理解,对用正则表达式处理数据也能更熟练地去使用了。这题是通过书上的例子进行改编。
1 import java.util.*; 2 3 class DataDeal { 4 5 private String[] key = {"if", "abstract", "float", "assert", "boolean", 6 "break", "byte", "case", "catch", "char", "class", "const", 7 "continue", "default", "do", "double", "else", "enum", 8 "extends", "false", "for", "final", "finally", "goto", 9 "implements", "import", "instanceof", "int", 10 "interface", "native", "new", "null", "package", "private", 11 "protected", "public", "return", "short", "static", 12 "strictfp", "super", "switch", "synchronized", "this", 13 "throw", "throws", "transient", "true", "try", "void", "volatile", 14 "while", "long"}; 15 Map<String, Integer> map = new TreeMap<>(); 16 private String singleLine; 17 18 public DataDeal() { 19 for(String s : key) { // 用了TreeMap就用不上HashSet了,就删了 20 map.put(s, 0); 21 } 22 } 23 24 public DataDeal(String singleLine) { 25 super(); 26 this.singleLine = singleLine; 27 } 28 29 public void setSingleLine(String singleLine) { 30 this.singleLine = singleLine; 31 } 32 33 public ArrayList<String> dealData(){ 34 singleLine = singleLine.replaceAll("//(.*)?\n", " "); // 双斜杠正则表达式 35 singleLine = singleLine.replaceAll("/\\*[\\s\\S]*?\\*/", " "); // /* */正则表达式 36 singleLine = singleLine.replaceAll("(\\*/)", " "); // */正则表达式 37 singleLine = singleLine.replaceAll("^\\s*\\n", " "); // 空白行正则表达式 38 singleLine = singleLine.replaceAll("\".*\"", " "); // 引号正则表达式 39 singleLine = singleLine.replaceAll("[\\+\\-\\*%/!@#$\\^>=<\\?&:~\\|]", "kk"); 40 singleLine = singleLine.replaceAll("\\W+", " "); // 非单词字符转换表达式 41 42 String[] splitedLine = singleLine.split("\\s+"); 43 ArrayList<String> toArrayData = new ArrayList<>(); 44 for(String s : splitedLine) { 45 toArrayData.add(s); 46 } 47 return toArrayData; 48 } 49 50 public void countValue() { 51 List<String> list = this.dealData(); 52 if(!list.isEmpty()) { 53 for(String s : list) { 54 if(map.containsKey(s)) { 55 map.compute(s, (key, oldValue) -> oldValue + 1); 56 } 57 } 58 } 59 } 60 61 public void show() { 62 for(Map.Entry<String, Integer> entries : map.entrySet()) { 63 if(entries.getValue() > 0) { 64 System.out.println(entries.getValue() + "\t" + entries.getKey()); 65 } 66 } 67 } 68 } 69 70 public class Main { 71 public static void main(String[] args) { 72 Scanner input = new Scanner(System.in); 73 DataDeal d = new DataDeal(); 74 75 String first = input.nextLine(); 76 if(first.equals("exit")) { 77 System.out.println("Wrong Format"); 78 System.exit(0); 79 } 80 String lines = first; 81 while(!first.equals("exit")) { 82 first = input.nextLine(); 83 if(first.equals("exit")) 84 break; 85 lines = lines.concat("\n" + first); 86 } 87 d.setSingleLine(lines); 88 d.countValue(); 89 d.show(); 90 } 91 }
这里我用ArrayList写的第一遍,没什么可说的,简单也很好理解;用Set写第二遍,它的优点在于不用对检测到的关键词做不重复添加的处理,但是仍需要再创建变量来统计关键词出现次数,与ArrayList相比方便了一些但是还是不够方便;用Map写第三遍,发现了新大陆。Map相当于离散数学里的“带权图”,每个Key都存着与之对应的Value。这在需要处理一一对应的关系的问题上很好用,比如学生和学生的分数,地区和地区的天气等。而统计关键词数量这题,我们把每个关键词当做Map的一个节点,把关键词出现的次数当做该节点的Value,出现的所有关键词通过一个Map关联起来。这在统计过程中要比前两种方法方便太多了。
这题有个难点:不统计注释内的关键词和声明变量中出现的关键词(如isint中的int)。这对输入数据的处理能力有一定的要求。首先我们要分好两种注释的处理方法,我用到了正则表达式:
通过正则表达式的分步处理将所有不符合要求的内容替换,将结果按照空格分割储存处理。
题目集10:
题目集10是一道大题:课程成绩统计程序。
1 import java.text.Collator; 2 import java.util.*; 3 import java.util.Map.Entry; 4 5 6 abstract class AbstractGrade { 7 8 public abstract int getGrade(); 9 } 10 11 class Inspect extends AbstractGrade{ 12 13 private int finalGrade = 0; 14 15 public Inspect() { 16 17 } 18 19 public Inspect(int finalGrade) { 20 this.finalGrade = finalGrade; 21 } 22 23 public int getFinalGrade() { 24 return finalGrade; 25 } 26 27 public void setFinalGrade(int finalGrade) { 28 this.finalGrade = finalGrade; 29 } 30 31 @Override 32 public int getGrade() { 33 int grade = getFinalGrade(); 34 return grade; 35 } 36 } 37 38 class Exam extends AbstractGrade{ 39 40 private int usualGrade = 0; 41 private int finalGrade = 0; 42 43 public Exam() { 44 super(); 45 // TODO 自动生成的构造函数存根 46 } 47 48 public Exam(int usualGrade, int finalGrade) { 49 this.usualGrade = usualGrade; 50 this.finalGrade = finalGrade; 51 } 52 53 public int getUsualGrade() { 54 return usualGrade; 55 } 56 57 public void setUsualGrade(int usualGrade) { 58 this.usualGrade = usualGrade; 59 } 60 61 public int getFinalGrade() { 62 return finalGrade; 63 } 64 65 public void setFinalGrade(int finalGrade) { 66 this.finalGrade = finalGrade; 67 } 68 69 @Override 70 public int getGrade() { 71 int grade = (this.getUsualGrade() * 3 + getFinalGrade() * 7) / 10; 72 return grade; 73 } 74 } 75 76 class Course implements Comparable<Course>{ 77 78 private String courseName; 79 private String courseType; 80 private String method; 81 82 public Course() { 83 84 } 85 86 public Course(String courseName, String courseType, String method) { 87 this.courseName = courseName; 88 this.courseType = courseType; 89 this.method = method; 90 } 91 92 public String getCourseName() { 93 return courseName; 94 } 95 96 public void setCourseName(String courseName) { 97 this.courseName = courseName; 98 } 99 100 public String getCourseType() { 101 return courseType; 102 } 103 104 public void setCourseType(String courseType) { 105 this.courseType = courseType; 106 } 107 108 public String getMethod() { 109 return method; 110 } 111 112 public void setMethod(String method) { 113 this.method = method; 114 } 115 116 public boolean isLegalCourse() { 117 if(this.courseType.equals("必修") && !this.method.equals("考试")) { 118 return false; 119 } 120 return true; 121 } 122 123 @Override 124 public int compareTo(Course o) { 125 return Collator.getInstance(Locale.CHINA).getCollationKey(this.getCourseName()). 126 compareTo(Collator.getInstance(Locale.CHINA).getCollationKey(o.getCourseName())); 127 } 128 } 129 130 class Student implements Comparable<Student>{ 131 132 private String name; 133 private String stuNum; 134 public Student() { 135 super(); 136 // TODO 自动生成的构造函数存根 137 } 138 139 public Student(String stuNum, String name) { 140 this.name = name; 141 this.stuNum = stuNum; 142 } 143 144 public String getName() { 145 return name; 146 } 147 148 public void setName(String name) { 149 this.name = name; 150 } 151 152 public String getStuNum() { 153 return stuNum; 154 } 155 156 public void setStuNum(String stuNum) { 157 this.stuNum = stuNum; 158 } 159 160 @Override 161 public int compareTo(Student o) { 162 // TODO 自动生成的方法存根 163 return this.getStuNum().compareTo(o.getStuNum()); 164 } 165 166 } 167 168 class Class implements Comparable<Class>{ 169 170 private String classNum = "0"; 171 private Map<Student, Integer> classMap = new LinkedHashMap<>(); 172 173 public Class() { 174 // TODO 自动生成的构造函数存根 175 } 176 177 public void setNum(String num) { 178 this.classNum = num; 179 } 180 181 public String getNum() { 182 return this.classNum; 183 } 184 185 public Map<Student, Integer> getStu(){ 186 return this.classMap; 187 } 188 189 public void addStudent(Student student, int grade) { 190 classMap.put(student, grade); 191 } 192 193 public int averageGrade() { 194 if(classMap.size() == 0) { 195 return -1; 196 } 197 int sum = 0; 198 for(Map.Entry<Student, Integer> entry : classMap.entrySet()) { 199 sum += entry.getValue(); 200 } 201 int average = sum / classMap.size(); 202 return average; 203 } 204 205 @Override 206 public int compareTo(Class o) { 207 // TODO 自动生成的方法存根 208 return this.getNum().compareTo(o.getNum()); 209 } 210 211 } 212 213 class CourseSelection implements Comparable<CourseSelection> { 214 215 private Student stu = new Student(); 216 private Set<Course> courses = new LinkedHashSet<>(); 217 private Set<AbstractGrade> grades = new LinkedHashSet<>(); 218 219 220 public CourseSelection() { 221 // TODO 自动生成的构造函数存根 222 } 223 224 public Student getStu() { 225 return stu; 226 } 227 228 public void setStu(Student stu) { 229 this.stu = stu; 230 } 231 232 233 public Set<Course> getCourses() { 234 return courses; 235 } 236 237 public void addCourses(Course courses) { 238 this.courses.add(courses); 239 } 240 241 public Set<AbstractGrade> getGrades() { 242 return grades; 243 } 244 245 public void addGrades(AbstractGrade grades) { 246 this.grades.add(grades); 247 } 248 249 public int calGrade() { 250 if(grades.size() == 0) { 251 return -1; 252 } 253 int sum = 0; 254 for(AbstractGrade ag : grades) { 255 sum += ag.getGrade(); 256 } 257 return sum / grades.size(); 258 } 259 260 @Override 261 public int compareTo(CourseSelection o) { 262 return this.getStu().getStuNum().compareTo(o.getStu().getStuNum()); 263 } 264 265 } 266 267 public class Main { 268 public static Scanner in = new Scanner(System.in); 269 270 public static String[] dealScanData() { 271 272 String line = Main.in.nextLine(); 273 if(line.equals("end")) { 274 return null; 275 } 276 String[] sLine = line.split("\\s+"); 277 if(sLine.length < 2 || sLine.length > 3 && !sLine[0].matches("[\\d]{1,}")) { 278 System.out.println("wrong format"); 279 sLine = new String[] {"null", "null", "null"}; 280 } 281 else if(sLine[0].length() > 10 || sLine[1].length() > 10) { 282 System.out.println("wrong format"); 283 sLine = new String[] {"null", "null", "null"}; 284 } 285 else if(sLine[0].matches("[\\d]{1,}") && sLine.length < 4 || sLine.length > 5) { 286 System.out.println("wrong format"); 287 sLine = new String[] {"null", "null", "null"}; 288 } 289 else if(sLine[1].equals("必修") && sLine.length == 3) { 290 if(sLine[2].equals("考察")) { 291 System.out.println(sLine[0] + " : course type & access mode mismatch"); 292 sLine = new String[] {"null", "null", "null"}; 293 } 294 else if(!sLine[2].equals("考试")) { 295 System.out.println("wrong format"); 296 sLine = new String[] {"null", "null", "null"}; 297 } 298 299 } 300 else if(sLine[1].equals("选修")) { 301 if(sLine.length == 3) { 302 if(!sLine[2].equals("考察") && !sLine[2].equals("考试")) { 303 System.out.println("wrong format"); 304 sLine = new String[] {"null", "null", "null"}; 305 } 306 } 307 else { 308 System.out.println("wrong format"); 309 sLine = new String[] {"null", "null", "null"}; 310 } 311 } 312 else if(!sLine[1].equals("必修") && !sLine[1].equals("选修") && !sLine[0].matches("[\\d]{1,}")) { 313 sLine = new String[] {"null", "null", "null"}; 314 System.out.println("wrong format"); 315 316 } 317 else if(sLine[0].matches("[\\d]{8}")) { 318 if(sLine.length >= 4 && !sLine[3].matches("^([0-9][0-9]{0,1}|100)$")) { 319 sLine = new String[] {"null", "null", "null"}; 320 System.out.println("wrong format"); 321 322 } 323 if(sLine.length == 5 && !sLine[4].matches("^([0-9][0-9]{0,1}|100)$")) { 324 sLine = new String[] {"null", "null", "null"}; 325 System.out.println("wrong format"); 326 } 327 } 328 return sLine; 329 } 330 331 public static void main(String[] args) { 332 String[] data = Main.dealScanData(); 333 if(data == null) { 334 System.exit(0); 335 } 336 List<CourseSelection> selectionList = new ArrayList<>(); // 每个学生的选课信息列表 337 List<Course> courseList = new ArrayList<>(); // 添加学生选了的课程的课程列表 338 List<Course> addCourseList = new ArrayList<>(); // 添加一开始输入的课程的列表 339 List<Class> classList = new ArrayList<>(); // 所有班级 340 Map<Course, Integer> courseMap = new TreeMap<>(); // 课程和课程的平均分用TreeMap来实现 341 Map<Course, Integer> courseUsualMap = new TreeMap<>(); // 课程平时成绩平均分 342 Map<Course, Integer> courseFinalMap = new TreeMap<>(); // 课程期末成绩平均分 343 344 while(data != null) { 345 346 boolean courseflag0 = true; // 是否重复添加课程的flag 347 for(Course c : addCourseList) { 348 if(c.getCourseName().equals(data[0])) { 349 courseflag0 = false; 350 } 351 } 352 if(courseflag0) { 353 Course course = null; 354 if(data.length <= 3 && data[1].equals("必修")) { 355 course = new Course(data[0], data[1], "考试"); 356 } 357 if(data[1].equals("选修") && data.length == 3) { 358 course = new Course(data[0], data[1], data[2]); 359 } 360 if(course != null) { 361 addCourseList.add(course); 362 courseMap.put(course, -100); 363 courseUsualMap.put(course, 0); 364 courseFinalMap.put(course, 0); 365 } 366 } 367 368 369 //-----------------------添加课程结束------------------------------// 370 371 if(data[0].matches("[\\d]{8}") && data.length >= 4) { 372 // 先添加人 373 CourseSelection selection = new CourseSelection(); 374 Student stu = new Student(data[0], data[1]); 375 String classNum = data[0].substring(0, 6); // 班级学号 376 Class cla = new Class(); 377 cla.setNum(classNum); 378 selection.setStu(stu); // 先添加人,不添加别的 379 if(selectionList.isEmpty()) { // 如果一开始是空,则直接添加选课和班级 380 selectionList.add(selection); 381 } 382 383 384 boolean flag0 = true; // 是否重复添加人的flag 385 boolean flag3 = true; 386 boolean flag4 = false; // 是否有效学生信息的flag 387 388 for(CourseSelection cs : selectionList) { 389 if(cs.getStu().getStuNum().equals(selection.getStu().getStuNum())) { 390 flag0 = false; // 如果重复加人则只加成绩 391 } 392 for(Course co : cs.getCourses()) { 393 if(co.getCourseName().equals(data[2]) && cs.getStu().getStuNum().equals(selection.getStu().getStuNum())) { 394 flag3 = false; 395 } 396 } 397 398 } 399 if(flag0 && flag3) { // 如果不是重复加人 400 selectionList.add(selection); 401 } 402 403 // 再遍历已经添加的课程的列表寻找是否存在该课程 404 boolean flag1 = false; 405 Course acourse = new Course(); 406 String method = null; // 如果找到该课程则记录它的考核方法并且将该课程添加进选课里 407 for(Course c : addCourseList) { 408 if(c.getCourseName().equals(data[2])) { 409 flag1 = true; 410 method = c.getMethod(); 411 acourse = c; 412 } 413 } 414 if(flag1 == false) { // 如果检测该课程不存在 415 System.out.println(data[2] + " does not exist"); 416 boolean flag2 = true; // 判断是否添加班级的flag 417 for(Class c : classList) { 418 if(c.getNum().equals(classNum)) { 419 flag2 = false; 420 } 421 } 422 if(flag2 && flag3) { 423 classList.add(cla); 424 } 425 } 426 else if(flag3){ // 课程存在,下一步检查分数情况 427 boolean flag2 = true; // 判断是否添加班级的flag 428 for(Class c : classList) { 429 if(c.getNum().equals(classNum)) { 430 flag2 = false; 431 } 432 } 433 if(flag2) { 434 classList.add(cla); 435 } 436 // 开始判断分数是否正确 437 if(data.length == 5) { // 考试有两个成绩 438 int usual = Integer.parseInt(data[3]); 439 int fina = Integer.parseInt(data[4]); 440 boolean scoreflag0 = true; 441 if(usual > 100 || usual < 0 || fina > 100 || fina < 0) { // 如果分数错误 442 System.out.println("wrong format"); 443 stu = null; 444 if(selectionList.indexOf(selection) >= 0) 445 selectionList.remove(selectionList.indexOf(selection)); 446 if(classList.indexOf(cla) >= 0) 447 classList.remove(classList.indexOf(cla)); 448 cla = null; 449 scoreflag0 = false; 450 } 451 452 else { // 分数正确进行下一步,可以开始添加选课 453 if(method.equals("考察") && scoreflag0) { // 检查是否符合考核方式所给的成绩 454 System.out.println(data[0] + " " + data[1] + " : access mode mismatch"); 455 } 456 else { 457 Exam exam = new Exam(usual, fina); 458 for(CourseSelection cslt : selectionList) { 459 460 if(cslt.getStu().getStuNum().equals(data[0])) { // 匹配到该人 461 selection.addCourses(acourse); 462 cslt.addGrades(exam); 463 cslt.addCourses(acourse); 464 courseList.add(acourse); 465 cla.addStudent(stu, exam.getGrade()); 466 courseMap.compute(acourse, (key, oldValue) -> oldValue + exam.getGrade()); 467 courseUsualMap.compute(acourse, (key, oldValue) -> oldValue + exam.getUsualGrade()); 468 courseFinalMap.compute(acourse, (key, oldValue) -> oldValue + exam.getFinalGrade()); 469 selectionList.set(selectionList.indexOf(cslt), cslt); 470 flag4 = true; 471 } 472 } 473 } 474 475 } 476 } 477 //--------------------考试考察分界线-------------------// 478 if(data.length == 4) { // 考察有一个成绩 479 int fina = Integer.parseInt(data[3]); 480 boolean scoreflag0 = true; 481 if(fina > 100 || fina < 0) { 482 System.out.println("wrong format"); 483 stu = null; 484 if(selectionList.indexOf(selection) >= 0) 485 selectionList.remove(selectionList.indexOf(selection)); 486 if(classList.indexOf(cla) >= 0) 487 classList.remove(classList.indexOf(cla)); 488 cla = null; 489 scoreflag0 = false; 490 } 491 492 else { 493 if(method.equals("考试") && scoreflag0) { // 检查是否符合考核方式所给的成绩 494 System.out.println(data[0] + " " + data[1] + " : access mode mismatch"); 495 } 496 else { 497 Inspect inspect = new Inspect(fina); 498 for(CourseSelection cslt : selectionList) { 499 if(cslt.getStu().getStuNum().equals(data[0])) { // 匹配到该人 500 selection.addCourses(acourse); 501 cslt.addGrades(inspect); 502 cslt.addCourses(acourse); 503 courseList.add(acourse); 504 cla.addStudent(stu, inspect.getGrade()); 505 courseMap.compute(acourse, (key, oldValue) -> oldValue + inspect.getGrade()); 506 courseFinalMap.compute(acourse, (key, oldValue) -> oldValue + inspect.getFinalGrade()); 507 selectionList.set(selectionList.indexOf(cslt), cslt); 508 flag4 = true; 509 } 510 } 511 } 512 513 } 514 } 515 } 516 if(stu != null && flag3) { 517 for(Class classes : classList) { 518 if(stu.getStuNum().contains(classes.getNum()) && flag4) { // 存在该班级 519 classes.addStudent(stu, cla.averageGrade()); 520 classList.set(classList.indexOf(classes), classes); 521 } 522 } 523 } 524 } 525 if(data[0].matches("[\\d]{9}+|[\\d]{1,7}")) { 526 System.out.println("wrong format"); 527 } 528 //-----------------------添加人结束-------------------------------// 529 530 data = Main.dealScanData(); 531 } 532 533 Collections.sort(courseList); 534 Collections.sort(selectionList); 535 Collections.sort(classList); 536 537 for(CourseSelection cs : selectionList) { // 个人成绩输出 538 if(cs.calGrade() == -1) { 539 System.out.println(cs.getStu().getStuNum() + " " + cs.getStu().getName() + " did not take any exams"); 540 } 541 else { 542 System.out.println(cs.getStu().getStuNum() + " " + cs.getStu().getName() + " " + cs.calGrade()); 543 } 544 } 545 for(Entry<Course, Integer> m : courseMap.entrySet()) { // 科目成绩输出 546 547 if(courseList.contains(m.getKey())) { 548 m.setValue(m.getValue() + 100); 549 } 550 551 if(m.getValue() < 0) { 552 System.out.println(m.getKey().getCourseName() + " has no grades yet"); 553 } 554 else { 555 int times = courseList.lastIndexOf(m.getKey()) - courseList.indexOf(m.getKey()) + 1; 556 if(m.getKey().getMethod().equals("考试")) { 557 System.out.println(m.getKey().getCourseName() + " " + courseUsualMap.get(m.getKey()) / times + " " + courseFinalMap.get(m.getKey()) / times + " "+ m.getValue() / times); 558 } 559 if(m.getKey().getMethod().equals("考察")) { 560 System.out.println(m.getKey().getCourseName() + " " + courseFinalMap.get(m.getKey()) / times + " "+ m.getValue() / times); 561 } 562 } 563 564 } 565 for(Class c : classList) { // 班级成绩输出 566 if(c.averageGrade() == -1) { 567 System.out.println(c.getNum() + " has no grades yet"); 568 } 569 else { 570 System.out.println(c.getNum() + " " + c.averageGrade()); 571 } 572 } 573 574 575 } 576 }
题目很长,需求很多而且情况分类很多。类的结构关系很明显。
这题的难点在于输入数据的判定和处理。如果这题的测试点有问题那么有80%的可能性是数据处理的问题。这题我用的是类似于过关斩将的数据处理方法,逐步判断数据的正确性,经过多重检测后最终将数据返回给主函数,主函数再根据是否重复或者是否是同一个人来进行最终的数据处理。在这点上我写了很多的if-else,并在主函数里创建了很多变量来存储不同的数据,有些变量写着写着自己都忘了为啥要用它,我认为这是我需要改进的地方。第一次写的很多问题我也在第二次作业里进行了改进,后面来具体说。
题目集11:
题目集11是题目集10的升级版,在课程成绩统计程序的基础上增加实验课的需求,升级成课程成绩统计程序2.0版本。这里需求多了就需要修改,如果按照我1.0版本的代码进行修改是无法实现开闭原则的。
需求增加:
1 import java.text.Collator; 2 import java.util.*; 3 import java.util.Map.Entry; 4 5 6 abstract class AbstractScore { 7 8 public abstract int getScore(); 9 } 10 11 class Inspect extends AbstractScore{ 12 13 private int finalGrade = 0; 14 15 public Inspect() { 16 17 } 18 19 public Inspect(int finalGrade) { 20 this.finalGrade = finalGrade; 21 } 22 23 public int getFinalGrade() { 24 return finalGrade; 25 } 26 27 public void setFinalGrade(int finalGrade) { 28 this.finalGrade = finalGrade; 29 } 30 31 @Override 32 public int getScore() { 33 int grade = getFinalGrade(); 34 return grade; 35 } 36 } 37 38 class Exam extends AbstractScore{ 39 40 private int usualGrade = 0; 41 private int finalGrade = 0; 42 43 public Exam() { 44 super(); 45 // TODO 自动生成的构造函数存根 46 } 47 48 public Exam(int usualGrade, int finalGrade) { 49 this.usualGrade = usualGrade; 50 this.finalGrade = finalGrade; 51 } 52 53 public int getUsualGrade() { 54 return usualGrade; 55 } 56 57 public void setUsualGrade(int usualGrade) { 58 this.usualGrade = usualGrade; 59 } 60 61 public int getFinalGrade() { 62 return finalGrade; 63 } 64 65 public void setFinalGrade(int finalGrade) { 66 this.finalGrade = finalGrade; 67 } 68 69 @Override 70 public int getScore() { 71 int grade = (this.getUsualGrade() * 3 + getFinalGrade() * 7) / 10; 72 return grade; 73 } 74 } 75 76 class Experiment extends AbstractScore { 77 78 private List<Integer> scoreList = new ArrayList<>(); 79 80 public Experiment() { 81 // TODO 自动生成的构造函数存根 82 } 83 84 public Experiment(List<Integer> scoreList) { 85 this.scoreList = scoreList; 86 } 87 88 public List<Integer> getScoreList() { 89 return scoreList; 90 } 91 92 public void addScoreList(int score) { 93 this.scoreList.add(score); 94 } 95 96 @Override 97 public int getScore() { 98 // TODO 自动生成的方法存根 99 int sum = 0; 100 for(Integer i : scoreList) { 101 sum += i; 102 } 103 return sum / scoreList.size(); 104 } 105 } 106 107 class Course implements Comparable<Course>{ 108 109 private String courseName; 110 private String courseType; 111 private String method; 112 113 public Course() { 114 115 } 116 117 public Course(String courseName, String courseType, String method) { 118 this.courseName = courseName; 119 this.courseType = courseType; 120 this.method = method; 121 } 122 123 public String getCourseName() { 124 return courseName; 125 } 126 127 public void setCourseName(String courseName) { 128 this.courseName = courseName; 129 } 130 131 public String getCourseType() { 132 return courseType; 133 } 134 135 public void setCourseType(String courseType) { 136 this.courseType = courseType; 137 } 138 139 public String getMethod() { 140 return method; 141 } 142 143 public void setMethod(String method) { 144 this.method = method; 145 } 146 147 public boolean isLegalCourse() { 148 if(this.courseType.equals("必修") && !this.method.equals("考试")) { 149 return false; 150 } 151 return true; 152 } 153 154 @Override 155 public int compareTo(Course o) { 156 return Collator.getInstance(Locale.CHINA).getCollationKey(this.getCourseName()). 157 compareTo(Collator.getInstance(Locale.CHINA).getCollationKey(o.getCourseName())); 158 } 159 } 160 161 class Student implements Comparable<Student>{ 162 163 private String name; 164 private String stuNum; 165 public Student() { 166 super(); 167 // TODO 自动生成的构造函数存根 168 } 169 170 public Student(String stuNum, String name) { 171 this.name = name; 172 this.stuNum = stuNum; 173 } 174 175 public String getName() { 176 return name; 177 } 178 179 public void setName(String name) { 180 this.name = name; 181 } 182 183 public String getStuNum() { 184 return stuNum; 185 } 186 187 public void setStuNum(String stuNum) { 188 this.stuNum = stuNum; 189 } 190 191 @Override 192 public int compareTo(Student o) { 193 // TODO 自动生成的方法存根 194 return this.getStuNum().compareTo(o.getStuNum()); 195 } 196 197 } 198 199 class Class implements Comparable<Class>{ 200 201 private String classNum = "0"; 202 private Map<Student, Integer> classMap = new LinkedHashMap<>(); 203 204 public Class() { 205 // TODO 自动生成的构造函数存根 206 } 207 208 public void setNum(String num) { 209 this.classNum = num; 210 } 211 212 public String getNum() { 213 return this.classNum; 214 } 215 216 public Map<Student, Integer> getStu(){ 217 return this.classMap; 218 } 219 220 public void addStudent(Student student, int grade) { 221 classMap.put(student, grade); 222 } 223 224 public int averageGrade() { 225 if(classMap.size() == 0) { 226 return -1; 227 } 228 int sum = 0; 229 for(Map.Entry<Student, Integer> entry : classMap.entrySet()) { 230 sum += entry.getValue(); 231 } 232 int average = sum / classMap.size(); 233 return average; 234 } 235 236 @Override 237 public int compareTo(Class o) { 238 // TODO 自动生成的方法存根 239 return this.getNum().compareTo(o.getNum()); 240 } 241 242 } 243 244 class CourseSelection implements Comparable<CourseSelection> { 245 246 private Student stu = new Student(); 247 private Set<Course> courses = new LinkedHashSet<>(); 248 private Set<AbstractScore> scores = new LinkedHashSet<>(); 249 250 251 public CourseSelection() { 252 // TODO 自动生成的构造函数存根 253 } 254 255 public Student getStu() { 256 return stu; 257 } 258 259 public void setStu(Student stu) { 260 this.stu = stu; 261 } 262 263 264 public Set<Course> getCourses() { 265 return courses; 266 } 267 268 public void addCourses(Course courses) { 269 this.courses.add(courses); 270 } 271 272 public Set<AbstractScore> getGrades() { 273 return scores; 274 } 275 276 public void addGrades(AbstractScore grades) { 277 this.scores.add(grades); 278 } 279 280 public int calGrade() { 281 if(scores.size() == 0) { 282 return -1; 283 } 284 int sum = 0; 285 for(AbstractScore ag : scores) { 286 sum += ag.getScore(); 287 } 288 return sum / scores.size(); 289 } 290 291 @Override 292 public int compareTo(CourseSelection o) { 293 return this.getStu().getStuNum().compareTo(o.getStu().getStuNum()); 294 } 295 296 } 297 298 299 public class Main { 300 public static Scanner in = new Scanner(System.in); 301 302 public static String[] dealScanData() { 303 304 String line = Main.in.nextLine(); 305 if(line.equals("end")) { 306 return null; 307 } 308 String[] sLine = line.split("\\s+"); 309 310 if(sLine.length < 2 || sLine.length > 3 && !sLine[0].matches("[\\d]{1,}")) { 311 System.out.println("wrong format"); 312 sLine = new String[] {"null", "null", "null"}; 313 } 314 else if(sLine[0].length() > 10 || sLine[1].length() > 10) { 315 System.out.println("wrong format"); 316 sLine = new String[] {"null", "null", "null"}; 317 } 318 else if(sLine[0].matches("[\\d]{1,}") && sLine.length < 4 || sLine.length > 13) { 319 System.out.println("wrong format"); 320 sLine = new String[] {"null", "null", "null"}; 321 } 322 else if(sLine[1].equals("必修") && sLine.length == 3) { 323 if(sLine[2].equals("考察") || sLine[2].equals("实验")) { 324 System.out.println(sLine[0] + " : course type & access mode mismatch"); 325 sLine = new String[] {"null", "null", "null"}; 326 } 327 else if(!sLine[2].equals("考试")) { 328 System.out.println("wrong format"); 329 sLine = new String[] {"null", "null", "null"}; 330 } 331 332 } 333 else if(sLine[1].equals("选修")) { 334 if(sLine.length == 3) { 335 if(sLine[2].equals("实验")) { 336 System.out.println(sLine[0] + " : course type & access mode mismatch"); 337 sLine = new String[] {"null", "null", "null"}; 338 } 339 else if(!sLine[2].equals("考察") && !sLine[2].equals("考试") && !sLine[2].equals("实验")) { 340 System.out.println("wrong format"); 341 sLine = new String[] {"null", "null", "null"}; 342 } 343 } 344 else { 345 System.out.println("wrong format"); 346 sLine = new String[] {"null", "null", "null"}; 347 } 348 } 349 else if(sLine[1].equals("实验")) { 350 if(sLine.length == 3) { 351 if(sLine[2].equals("考察") || sLine[2].equals("考试")) { 352 System.out.println(sLine[0] + " : course type & access mode mismatch"); 353 sLine = new String[] {"null", "null", "null"}; 354 } 355 else if(!sLine[2].equals("实验") && !sLine[2].equals("考察") && !sLine[2].equals("考试")) { System.out.println("wrong format"); 356 sLine = new String[] {"null", "null", "null"}; 357 } 358 } 359 else { 360 System.out.println("wrong format"); 361 sLine = new String[] {"null", "null", "null"}; 362 } 363 } 364 else if(!sLine[1].equals("必修") && !sLine[1].equals("选修") && !sLine[0].matches("[\\d]{1,}")) { 365 sLine = new String[] {"null", "null", "null"}; 366 System.out.println("wrong format"); 367 368 } 369 else if(sLine[0].matches("[\\d]{8}")) { 370 371 if(sLine.length >= 4) { // 可能有问题 372 for(int i = 4; i < sLine.length; i ++) { 373 if(!sLine[i].matches("^([0-9][0-9]{0,1}|100)$")) { 374 sLine = new String[] {"null", "null", "null", "null"}; 375 System.out.println("wrong format"); 376 break; 377 } 378 } 379 if(sLine.length != 4 && sLine.length != 5) { 380 int times = Integer.parseInt(sLine[3]); // 所输入的需要添加的课程的数量 381 if(times > 9 || times < 4) { 382 System.out.println("wrong format"); 383 sLine = new String[] {"null", "null", "null"}; 384 385 } 386 } 387 } 388 } 389 return sLine; 390 } 391 public static void main(String[] args) { 392 393 List<CourseSelection> selectionList = new ArrayList<>(); // 每个学生的选课信息列表 394 List<Course> courseList = new ArrayList<>(); // 添加学生选了的课程的课程列表 395 List<Course> addCourseList = new ArrayList<>(); // 添加一开始输入的课程的列表 396 List<Class> classList = new ArrayList<>(); // 所有班级 397 Map<Course, Integer> courseMap = new TreeMap<>(); // 课程和课程的平均分用TreeMap来实现 398 Map<Course, Integer> courseUsualMap = new TreeMap<>(); // 课程平时成绩平均分 399 Map<Course, Integer> courseFinalMap = new TreeMap<>(); // 课程期末成绩平均分 400 401 while(true) { 402 403 String[] data = Main.dealScanData(); 404 if(data == null) { 405 break; 406 } 407 408 boolean courseflag0 = true; // 是否重复添加课程的flag 409 for(Course c : addCourseList) { 410 if(c.getCourseName().equals(data[0])) { 411 courseflag0 = false; 412 } 413 } 414 if(courseflag0) { 415 Course course = null; 416 if(data.length <= 3 && data[1].equals("必修")) { 417 course = new Course(data[0], data[1], "考试"); 418 } 419 if(data[1].equals("选修") && data.length == 3) { 420 course = new Course(data[0], data[1], data[2]); 421 } 422 if(data[1].equals("实验") && data.length == 3) { 423 course = new Course(data[0], data[1], data[2]); 424 } 425 if(course != null) { 426 addCourseList.add(course); 427 courseMap.put(course, -100); 428 courseUsualMap.put(course, 0); 429 courseFinalMap.put(course, 0); 430 } 431 } 432 433 434 //-----------------------添加课程结束------------------------------// 435 436 if(data[0].matches("[\\d]{8}") && data.length >= 4) { 437 // 先添加人 438 CourseSelection selection = new CourseSelection(); 439 Student stu = new Student(data[0], data[1]); 440 String classNum = data[0].substring(0, 6); // 班级学号 441 Class cla = new Class(); 442 cla.setNum(classNum); 443 selection.setStu(stu); // 先添加人,不添加别的 444 if(selectionList.isEmpty()) { // 如果一开始是空,则直接添加选课和班级 445 selectionList.add(selection); 446 } 447 448 449 boolean flag0 = true; // 是否重复添加人的flag 450 boolean flag3 = true; 451 boolean flag4 = false; // 是否有效学生信息的flag 452 453 for(CourseSelection cs : selectionList) { 454 if(cs.getStu().getStuNum().equals(selection.getStu().getStuNum())) { 455 flag0 = false; // 如果重复加人则只加成绩 456 } 457 for(Course co : cs.getCourses()) { 458 if(co.getCourseName().equals(data[2]) && cs.getStu().getStuNum().equals(selection.getStu().getStuNum())) { 459 flag3 = false; 460 } 461 } 462 463 } 464 if(flag0 && flag3) { // 如果不是重复加人 465 selectionList.add(selection); 466 } 467 468 // 再遍历已经添加的课程的列表寻找是否存在该课程 469 boolean flag1 = false; 470 Course acourse = new Course(); 471 String method = null; // 如果找到该课程则记录它的考核方法并且将该课程添加进选课里 472 for(Course c : addCourseList) { 473 if(c.getCourseName().equals(data[2])) { 474 flag1 = true; 475 method = c.getMethod(); 476 acourse = c; 477 } 478 } 479 480 481 if(flag1 == false) { // 如果检测该课程不存在 482 System.out.println(data[2] + " does not exist"); 483 boolean flag2 = true; // 判断是否添加班级的flag 484 for(Class c : classList) { 485 if(c.getNum().equals(classNum)) { 486 flag2 = false; 487 } 488 } 489 if(flag2 && flag3) { 490 classList.add(cla); 491 } 492 } 493 else if(flag3){ // 课程存在,下一步检查分数情况 494 boolean flag2 = true; // 判断是否添加班级的flag 495 for(Class c : classList) { 496 if(c.getNum().equals(classNum)) { 497 flag2 = false; 498 } 499 } 500 if(flag2) { 501 classList.add(cla); 502 } 503 // 开始判断分数是否正确 504 if(data.length == 5) { // 考试有两个成绩 505 int usual = Integer.parseInt(data[3]); 506 int fina = Integer.parseInt(data[4]); 507 boolean scoreflag0 = true; 508 509 if(method.equals("考察") && scoreflag0) { // 检查是否符合考核方式所给的成绩 510 System.out.println(data[0] + " " + data[1] + " : access mode mismatch"); 511 } 512 else { 513 Exam exam = new Exam(usual, fina); 514 for(CourseSelection cslt : selectionList) { 515 516 if(cslt.getStu().getStuNum().equals(data[0])) { // 匹配到该人 517 selection.addCourses(acourse); 518 cslt.addGrades(exam); 519 cslt.addCourses(acourse); 520 courseList.add(acourse); 521 cla.addStudent(stu, exam.getScore()); 522 courseMap.compute(acourse, (key, oldValue) -> oldValue + exam.getScore()); 523 courseUsualMap.compute(acourse, (key, oldValue) -> oldValue + exam.getUsualGrade()); 524 courseFinalMap.compute(acourse, (key, oldValue) -> oldValue + exam.getFinalGrade()); 525 selectionList.set(selectionList.indexOf(cslt), cslt); 526 flag4 = true; 527 } 528 } 529 } 530 531 } 532 //--------------------考试考察分界线-------------------// 533 if(data.length == 4) { // 考察有一个成绩 534 int fina = Integer.parseInt(data[3]); 535 boolean scoreflag0 = true; 536 537 if(method.equals("考试") && scoreflag0) { // 检查是否符合考核方式所给的成绩 538 System.out.println(data[0] + " " + data[1] + " : access mode mismatch"); 539 } 540 else { 541 Inspect inspect = new Inspect(fina); 542 for(CourseSelection cslt : selectionList) { 543 if(cslt.getStu().getStuNum().equals(data[0])) { // 匹配到该人 544 selection.addCourses(acourse); 545 cslt.addGrades(inspect); 546 cslt.addCourses(acourse); 547 courseList.add(acourse); 548 cla.addStudent(stu, inspect.getScore()); 549 courseMap.compute(acourse, (key, oldValue) -> oldValue + inspect.getScore()); 550 courseFinalMap.compute(acourse, (key, oldValue) -> oldValue + inspect.getFinalGrade()); 551 selectionList.set(selectionList.indexOf(cslt), cslt); 552 flag4 = true; 553 } 554 } 555 } 556 557 } 558 559 //------------------------------实验(新加)-------------------------------// 560 561 if(method.equals("实验")) { 562 563 for(int i = 3; i < data.length; i ++) { 564 if(!data[i].matches("^([0-9][0-9]{0,1}|100)$")) { 565 System.out.println("wrong format"); 566 stu = null; 567 if(selectionList.indexOf(selection) >= 0) 568 selectionList.remove(selectionList.indexOf(selection)); 569 if(classList.indexOf(cla) >= 0) 570 classList.remove(classList.indexOf(cla)); 571 cla = null; 572 break; 573 } 574 575 } 576 577 int times = Integer.parseInt(data[3]); // 所输入的需要添加的课程的数量 578 List<Integer> scores = new ArrayList<>(); 579 for(int i = 4; i < data.length; i ++) { 580 scores.add(Integer.parseInt(data[i])); 581 } 582 if(times > 9 || times < 4) { 583 System.out.println("wrong format"); 584 stu = null; 585 if(selectionList.indexOf(selection) >= 0) 586 selectionList.remove(selectionList.indexOf(selection)); 587 if(classList.indexOf(cla) >= 0) 588 classList.remove(classList.indexOf(cla)); 589 cla = null; 590 continue; 591 } 592 if(times != scores.size()) { 593 System.out.println(data[0] + " " + data[1] + " : access mode mismatch"); 594 } 595 else { 596 Experiment ex = new Experiment(scores); 597 for(CourseSelection cslt : selectionList) { 598 if(cslt.getStu().getStuNum().equals(data[0])) { // 匹配到该人 599 selection.addCourses(acourse); 600 cslt.addGrades(ex); 601 cslt.addCourses(acourse); 602 courseList.add(acourse); 603 cla.addStudent(stu, ex.getScore()); 604 courseMap.compute(acourse, (key, oldValue) -> oldValue + ex.getScore()); 605 selectionList.set(selectionList.indexOf(cslt), cslt); 606 flag4 = true; 607 } 608 } 609 610 } 611 612 613 } 614 615 616 617 618 619 } 620 if(stu != null && flag3) { 621 for(Class classes : classList) { 622 if(stu.getStuNum().contains(classes.getNum()) && flag4) { // 存在该班级 623 classes.addStudent(stu, cla.averageGrade()); 624 classList.set(classList.indexOf(classes), classes); 625 } 626 } 627 } 628 } 629 if(data[0].matches("[\\d]{9}+|[\\d]{1,7}")) { 630 System.out.println("wrong format"); 631 } 632 633 } 634 635 Collections.sort(courseList); 636 Collections.sort(selectionList); 637 Collections.sort(classList); 638 639 for(CourseSelection cs : selectionList) { // 个人成绩输出 640 if(cs.calGrade() == -1) { 641 System.out.println(cs.getStu().getStuNum() + " " + cs.getStu().getName() + " did not take any exams"); 642 } 643 else { 644 System.out.println(cs.getStu().getStuNum() + " " + cs.getStu().getName() + " " + cs.calGrade()); 645 } 646 } 647 for(Entry<Course, Integer> m : courseMap.entrySet()) { // 科目成绩输出 648 649 if(courseList.contains(m.getKey())) { 650 m.setValue(m.getValue() + 100); 651 } 652 653 if(m.getValue() < 0) { 654 System.out.println(m.getKey().getCourseName() + " has no grades yet"); 655 } 656 else { 657 int times = courseList.lastIndexOf(m.getKey()) - courseList.indexOf(m.getKey()) + 1; 658 if(m.getKey().getMethod().equals("考试")) { 659 System.out.println(m.getKey().getCourseName() + " " + courseUsualMap.get(m.getKey()) / times + " " + courseFinalMap.get(m.getKey()) / times + " "+ m.getValue() / times); 660 } 661 if(m.getKey().getMethod().equals("考察")) { 662 System.out.println(m.getKey().getCourseName() + " " + courseFinalMap.get(m.getKey()) / times + " "+ m.getValue() / times); 663 } 664 if(m.getKey().getMethod().equals("实验")) { 665 System.out.println(m.getKey().getCourseName() + " " + m.getValue() / times); 666 } 667 } 668 669 } 670 for(Class c : classList) { // 班级成绩输出 671 if(c.averageGrade() == -1) { 672 System.out.println(c.getNum() + " has no grades yet"); 673 } 674 else { 675 System.out.println(c.getNum() + " " + c.averageGrade()); 676 } 677 } 678 679 } 680 681 }
这是类图,比上一题多了个Experiment类。
在1.0的基础上我在判断输入是否错误的代码上进行了优化,将输入课程的判断尽量结合到一起,不再分这么多判断。将输入学生成绩的判断结合,以便适应新加入的实验课程的成绩判断。
题目集12:
题目集12是题目集11的升级版,也就是课程成绩统计程序3.0版本。在2.0版本上有了很大的修改。修改量相当于重写。
类图也变了很多,因为将所有考核类型都结合起来了。
1 import java.text.Collator; 2 import java.util.*; 3 import java.util.Map.Entry; 4 5 6 class Score { 7 8 private List<Float> qList = new ArrayList<>(); 9 private List<Integer> sList = new ArrayList<>(); 10 11 public Score() { 12 // TODO 自动生成的构造函数存根 13 } 14 15 public Score(List<Float> qList, List<Integer> sList) { 16 this.qList = qList; 17 this.sList = sList; 18 } 19 20 public List<Float> getqList() { 21 return qList; 22 } 23 24 public void addqList(float f) { 25 this.qList.add(f); 26 } 27 28 public List<Integer> getsList() { 29 return sList; 30 } 31 32 public void addsList(Integer i) { 33 this.sList.add(i); 34 } 35 36 public void setqList(List<Float> qList) { 37 this.qList = qList; 38 } 39 40 public void setsList(List<Integer> sList) { 41 this.sList = sList; 42 } 43 44 public int getScore() { 45 int q = qList.size(); 46 int s = sList.size(); 47 int score = -1; 48 if(q == s) { 49 score += 1; 50 for(int i = 0; i < q; i++) { 51 score += (int) (qList.get(i) * sList.get(i)); 52 } 53 } 54 return score; 55 } 56 57 } 58 59 60 61 class Student implements Comparable<Student>{ 62 63 private String name; 64 private String stuNum; 65 public Student() { 66 super(); 67 // TODO 自动生成的构造函数存根 68 } 69 70 public Student(String stuNum, String name) { 71 this.name = name; 72 this.stuNum = stuNum; 73 } 74 75 public String getName() { 76 return name; 77 } 78 79 public void setName(String name) { 80 this.name = name; 81 } 82 83 public String getStuNum() { 84 return stuNum; 85 } 86 87 public void setStuNum(String stuNum) { 88 this.stuNum = stuNum; 89 } 90 91 @Override 92 public int compareTo(Student o) { 93 // TODO 自动生成的方法存根 94 return this.getStuNum().compareTo(o.getStuNum()); 95 } 96 97 } 98 99 class Class implements Comparable<Class>{ 100 101 private String classNum = "0"; 102 private Map<Student, Integer> classMap = new LinkedHashMap<>(); 103 104 public Class() { 105 // TODO 自动生成的构造函数存根 106 } 107 108 public void setNum(String num) { 109 this.classNum = num; 110 } 111 112 public String getNum() { 113 return this.classNum; 114 } 115 116 public Map<Student, Integer> getStu(){ 117 return this.classMap; 118 } 119 120 public void addStudent(Student student, int grade) { 121 classMap.put(student, grade); 122 } 123 124 public int averageGrade() { 125 if(classMap.size() == 0) { 126 return -1; 127 } 128 int sum = 0; 129 for(Map.Entry<Student, Integer> entry : classMap.entrySet()) { 130 sum += entry.getValue(); 131 } 132 int average = sum / classMap.size(); 133 return average; 134 } 135 136 @Override 137 public int compareTo(Class o) { 138 // TODO 自动生成的方法存根 139 return this.getNum().compareTo(o.getNum()); 140 } 141 142 } 143 144 class Course implements Comparable<Course>{ 145 146 private String courseName; 147 private String courseType; 148 private String method; 149 150 public Course() { 151 152 } 153 154 public Course(String courseName, String courseType, String method) { 155 this.courseName = courseName; 156 this.courseType = courseType; 157 this.method = method; 158 } 159 160 public String getCourseName() { 161 return courseName; 162 } 163 164 public void setCourseName(String courseName) { 165 this.courseName = courseName; 166 } 167 168 public String getCourseType() { 169 return courseType; 170 } 171 172 public void setCourseType(String courseType) { 173 this.courseType = courseType; 174 } 175 176 public String getMethod() { 177 return method; 178 } 179 180 public void setMethod(String method) { 181 this.method = method; 182 } 183 184 @Override 185 public int compareTo(Course o) { 186 return Collator.getInstance(Locale.CHINA).getCollationKey(this.getCourseName()). 187 compareTo(Collator.getInstance(Locale.CHINA).getCollationKey(o.getCourseName())); 188 } 189 } 190 191 class CourseSelection implements Comparable<CourseSelection> { 192 193 private Student stu = new Student(); 194 private Map<Course, Score> cs = new TreeMap<>(); 195 196 public CourseSelection() { 197 // TODO 自动生成的构造函数存根 198 } 199 200 public Student getStu() { 201 return stu; 202 } 203 204 public void setStu(Student stu) { 205 this.stu = stu; 206 } 207 208 public void addLeaf(Course c, Score s) { 209 this.cs.put(c, s); 210 } 211 212 public Map<Course, Score> getLeaf() { 213 return cs; 214 } 215 216 public int calScore() { 217 if(cs.size() == 0) { 218 return -1; 219 } 220 int sum = 0; 221 for(Map.Entry<Course, Score> e : cs.entrySet()) { 222 sum += e.getValue().getScore(); 223 } 224 return sum / cs.size(); 225 } 226 227 @Override 228 public int compareTo(CourseSelection o) { 229 return this.getStu().getStuNum().compareTo(o.getStu().getStuNum()); 230 } 231 } 232 233 public class Main { 234 public static Scanner in = new Scanner(System.in); 235 236 public static String[] dealData() { 237 String line = in.nextLine(); 238 if(line.equals("end")) { 239 return null; 240 } 241 242 String[] sLine = line.split("\\s+"); 243 244 245 return sLine; 246 } 247 248 public static void main(String[] args) { 249 List<CourseSelection> selectionList = new ArrayList<>(); 250 List<Course> courseList = new ArrayList<>(); // 添加学生选了的课程的课程列表 251 List<Course> addCourseList = new ArrayList<>(); // 添加一开始输入的课程的列表 252 List<Class> classList = new ArrayList<>(); // 所有班级 253 Map<Course, Integer> courseMap = new TreeMap<>(); // 课程和课程的平均分用TreeMap来实现 254 Map<Course, Integer> courseUsualMap = new TreeMap<>(); // 课程平时成绩平均分 255 Map<Course, Integer> courseFinalMap = new TreeMap<>(); // 课程期末成绩平均分 256 257 ArrayList<Float> arrayList = new ArrayList<>(); // 权重 258 259 while(true) { 260 String[] data = Main.dealData(); 261 if(data == null) { 262 break; 263 } 264 265 266 // 先加课 267 if(!data[0].matches("[\\d]{1,}")) { 268 if ((data[0].length() > 10 || ((!data[1].equals("必修") && !data[1].equals("选修") 269 && !data[1].equals("实验")) || (!data[2].equals("考试") && !data[2].equals("考察") 270 && !data[2].equals("实验"))))) { 271 System.out.println("wrong format"); 272 continue; 273 } else if ((data.length == 2) && (data[0].length() > 10 || !data[1].equals("必修"))) { 274 System.out.println("wrong format"); 275 continue; 276 } 277 if(data[1].equals("必修")) { 278 if(data[2].equals("选修") || data[2].equals("实验")) { 279 System.out.println(data[0] + " : course type & access mode mismatch"); 280 continue; 281 } 282 } 283 if(data[1].equals("选修")) { 284 if(data[2].equals("实验")) { 285 System.out.println(data[0] + " : course type & access mode mismatch"); 286 continue; 287 } 288 } 289 if(data[1].equals("实验")) { 290 if(data[2].equals("必修") || data[2].equals("选修")) { 291 System.out.println(data[0] + " : course type & access mode mismatch"); 292 continue; 293 } 294 } 295 Course course = new Course(data[0], data[1], data[2]); 296 if (data[1].equals("实验") && !data[3].matches("[4-9]")) { 297 System.out.println("wrong format"); 298 continue; 299 } else if (data[1].equals("实验") && Integer.parseInt(data[3]) + 4 != data.length) { 300 System.out.println(course.getCourseName() + " : number of scores does not match"); 301 continue; 302 } else if ((data[1].equals("必修") && (Math.abs (Float.parseFloat(data[3])+Float.parseFloat(data[4])- 1)>0.01))) { 303 System.out.println(course.getCourseName() + " : weight value error"); 304 continue; 305 } else if (data[1].equals("实验")) { 306 int n = Integer.parseInt(data[3]); 307 float sum = 0; 308 for (int i = 0; i < n; i++) { 309 float tempFloat = Float.parseFloat(data[i + 4]); 310 sum += tempFloat; 311 arrayList.add(tempFloat); 312 } 313 if (Math.abs(sum-1)>0.01) { 314 System.out.println(course.getCourseName() + " : weight value error"); 315 continue; 316 } 317 } else if (data[2].equals("考试")) { 318 arrayList.add(Float.parseFloat(data[3])); 319 arrayList.add(Float.parseFloat(data[4])); 320 } 321 boolean courseflag0 = true; // 是否重复添加课程的flag 322 for(Course c : addCourseList) { 323 if(c.getCourseName().equals(data[0])) { 324 courseflag0 = false; 325 } 326 } 327 if(!courseflag0) { 328 continue; 329 } 330 addCourseList.add(course); 331 courseMap.put(course, -100); 332 courseUsualMap.put(course, 0); 333 courseFinalMap.put(course, 0); 334 } 335 // for(Float f : arrayList) { 336 // System.out.println(f); 337 // } 338 339 // 再加人 340 if (data[0].matches("[0-9]{0,100}")) { 341 CourseSelection selection = new CourseSelection(); 342 Class cla = new Class(); 343 Student student = new Student(data[0], data[1]); 344 Course course = null; 345 Score score = new Score(); 346 List<Integer> scores = new ArrayList<>(); 347 List<Float> weight = new ArrayList<>(); 348 if (data.length >= 5) { 349 boolean flag = false; 350 for (int i = 3; i < data.length; i++) { 351 if (!data[i].matches("^([0-9][0-9]{0,1}|100)$")) { 352 System.out.println("wrong format"); 353 flag = true; 354 break; 355 } 356 // System.out.println(data[i]); 357 scores.add(Integer.parseInt(data[i])); 358 score.addsList(Integer.parseInt(data[i])); 359 // for(Integer s : scores) { 360 // System.out.println(s); 361 // } 362 } 363 if (flag) 364 continue; 365 } 366 if (data[0].length() != 8 || data[1].length() > 10 || data[2].length() > 10 367 || !data[3].matches("[0-9]{1,3}") || (Integer.parseInt(data[3]) < 0 || Integer.parseInt(data[3]) > 100)) { 368 System.out.println("wrong format"); 369 continue; 370 } 371 372 boolean flag0 = true; // 是否重复添加人的flag 373 boolean flag3 = true; 374 375 for(CourseSelection cs : selectionList) { 376 if(cs.getStu().getStuNum().equals(selection.getStu().getStuNum())) { 377 flag0 = false; // 如果重复加人则只加成绩 378 } 379 for(Course co : cs.getLeaf().keySet()) { 380 if(co.getCourseName().equals(data[2]) && cs.getStu().getStuNum().equals(selection.getStu().getStuNum())) { 381 flag3 = false; 382 } 383 } 384 385 } 386 if(flag0 && flag3) { // 如果不是重复加人 387 selectionList.add(selection); 388 } 389 390 boolean flag1 = false; 391 for(Course c : addCourseList) { 392 if(c.getCourseName().equals(data[2])) { 393 flag1 = true; 394 } 395 } 396 if(flag1 == false) { // 如果检测该课程不存在 397 System.out.println(data[2] + " does not exist"); 398 399 } 400 boolean flag2 = true; // 判断是否添加班级的flag 401 for(Class c : classList) { 402 if(c.getNum().equals(cla.getNum())) { 403 flag2 = false; 404 break; 405 } 406 } 407 if(flag2) { 408 classList.add(cla); 409 } 410 411 412 for(Course c : addCourseList) { 413 if(c.getCourseName().equals(data[2])) { // 找到该课程 414 course = c; 415 weight = arrayList; 416 score.setqList(arrayList); 417 break; 418 } 419 } 420 if (data.length == 5 && ((Integer.parseInt(data[4]) < 0) || (Integer.parseInt(data[4]) > 100))) { 421 System.out.println("wrong format"); 422 continue; 423 } else if (course != null && course.getMethod().equals("实验")) { 424 if(!course.getMethod().equals("实验") && data.length>5){ 425 System.out.println("wrong format"); 426 continue; 427 } 428 if (data.length != score.getqList().size() + 3) { 429 System.out.println(data[0] + " " + data[1] + " " + ": access mode mismatch"); 430 } 431 } 432 433 student.setStuNum(data[0]); 434 student.setName(data[1]); 435 selection.setStu(student); 436 cla.setNum(data[0].substring(0, 6)); 437 438 if(selectionList.isEmpty()) { 439 selectionList.add(selection); 440 } 441 442 443 for(CourseSelection cslt : selectionList) { 444 if(cslt.getStu().getStuNum().equals(data[0])) { // 匹配到该人 445 cslt.addLeaf(course, score); 446 selection.addLeaf(course, score); 447 courseList.add(course); 448 cla.addStudent(student, score.getScore()); 449 courseMap.compute(course, (key, oldValue) -> oldValue + score.getScore()); 450 selectionList.set(selectionList.indexOf(cslt), cslt); 451 } 452 } 453 454 if(flag3) { 455 for(Class classes : classList) { 456 // System.out.println("kk"); 457 if(student.getStuNum().contains(classes.getNum())) { // 存在该班级 458 classes.addStudent(student, cla.averageGrade()); 459 classList.set(classList.indexOf(classes), classes); 460 } 461 462 } 463 } 464 } 465 466 467 468 } 469 470 Collections.sort(courseList); 471 Collections.sort(selectionList); 472 Collections.sort(classList); 473 474 for(CourseSelection cs : selectionList) { // 个人成绩输出 475 if(cs.calScore() == -1) { 476 477 System.out.println(cs.getStu().getStuNum() + " " + cs.getStu().getName() + " did not take any exams"); 478 } 479 else { 480 System.out.println(cs.getStu().getStuNum() + " " + cs.getStu().getName() + " " + cs.calScore()); 481 } 482 } 483 for(Entry<Course, Integer> m : courseMap.entrySet()) { // 科目成绩输出 484 485 if(courseList.contains(m.getKey())) { 486 m.setValue(m.getValue() + 100); 487 } 488 489 if(m.getValue() < 0) { 490 System.out.println(m.getKey().getCourseName() + " has no grades yet"); 491 } 492 else { 493 int times = courseList.lastIndexOf(m.getKey()) - courseList.indexOf(m.getKey()) + 1; 494 if(m.getKey().getMethod().equals("考试")) { 495 System.out.println(m.getKey().getCourseName() + " " + courseUsualMap.get(m.getKey()) / times + " " + courseFinalMap.get(m.getKey()) / times + " "+ m.getValue() / times); 496 } 497 if(m.getKey().getMethod().equals("考察")) { 498 System.out.println(m.getKey().getCourseName() + " " + courseFinalMap.get(m.getKey()) / times + " "+ m.getValue() / times); 499 } 500 if(m.getKey().getMethod().equals("实验")) { 501 System.out.println(m.getKey().getCourseName() + " " + m.getValue() / times); 502 } 503 } 504 505 } 506 for(Class c : classList) { // 班级成绩输出 507 if(c.averageGrade() == -1) { 508 System.out.println(c.getNum() + " has no grades yet"); 509 } 510 else { 511 System.out.println(c.getNum() + " " + c.averageGrade()); 512 } 513 } 514 515 } 516 517 }
这里提交时我缺少了是否是同一班级的判断,以及是否是添加重复课程的判断,所以后面的测试点没过。但是相比于前两个版本,我优化了很多。首先是输入和判断,我不再把它写入主函数外,而是改为在while循环内,因为我认为没有必要分开处理了,分开反而对之后的处理带来了一定的麻烦。
客观评价:
1.教学理念(OBE):
了解了一下OBE教育理念,也有不少收获,也稍微理解了一下OBE。就我所体会和观察的,成果导向在PTA作业中的体现是:我们抓着测试点不放,以“面向结果”式的编程来完成题目的要求,追求分数上的达标,拿到100分后便如释重负。而质量上就难以得知了,有时候认为自己确实写得不够好不够简洁,但是也很少去想着动手修改,因为已经达标了。虽然老师说会人工审一遍,但是并不知道老师的评价,有时候觉得自己写的还可以,需要修改的点无关紧要之类的,这有时候确实会有点迷茫。
2.边讲边练:
我很喜欢边讲边练的方法,因为这可以在我上课学到的同时快速进行实践操作,这会使我印象深刻。
3.教学过程(PTA题目集驱动):
容易造成“面向测试点编程”的现象。
4.教学模式(BOPPPS):
初高中就是这么过来的,已经适应了。