【软件构造】LAB1所遇问题及解决

实验背景1:

从文件中读入矩阵判断其是否为magicsquare


问题1描述

一开始尝试用控制台输入的方式输入一个矩阵,先行判断算法的正确性其中用到了scanner类,并书写了类似下面的一个循环;

while(scan.hasNextline()){
    for...)
    ...
}

后面在debug过程中尝试类似下面的错误,在控制台按下回车后一直不会结束,只会有第一次返回TRUE的结果

Scanner scan = new Scanner(System.in);
System.out.println(scan.hasNextLine());
System.out.println(scan.hasNext());

原因分析:

hasNext和hasNextLine的使用

二者都是用于判断“有无键盘输入”的,有则返回true,没有则阻塞!一定记住是阻塞而不是返回false,会让你一直阻塞在判断阶段,就像上面提到的控制台输出一直不会结束的情况,以及无法跳出while循环执行后面语句;
两者具体使用功能如下:

  1. hasNext()方法会判断接下来是否有非空字符.如果有,则返回true,没有则阻塞。
  2. hasNextLine() 方法会根据行匹配模式去判断接下来是否有一行(包括空行),如果有,则返回true。注意:当这里用于控制台输入时,由于总会是以一个回车结束,导致敲了回车那都是true并且不会阻塞。

拓展学习

引用自:hasNext、hasNextLine、next、nextLine详解

  1. next方法不能录入空格,甚至会把空格当作回车,nextLine方法可以识录入空格;
  2. hasNext和hasNextLine的返回值都是boolean类型,但只有可能返回true,不可能返回false,并且都默认以回车键为结束;
  3. hasNext是线程阻塞的,对于hasNext来说,如果一直不输入字符,反而一直敲回车的话,整个线程会卡在这个输入的地方,直到有字符输入;

实验背景2:

凸包(Convex Hull)是一个计算几何(图形学)中的概念。

在一个实数向量空间V中,对于给定集合X,所有包含X的凸集的交集S被称为X的凸包。
X的凸包可以用X内所有点(X1,…Xn)的线性组合来构造.
在二维欧几里得空间中,凸包可想象为一条刚好包著所有点的橡皮圈。
用不严谨的话来讲,给定二维平面上的点集,凸包就是将最外层的点连接起来构成的凸多边型,它能包含点集中所有的点。
凸包算法:方法详解

实现障碍

  1. 用什么依据找到初始点,才能进一步实现算法;
  2. 所有点集中满足什么条件才能在遍历过程中将其纳入凸包集当中;
  3. 一些特殊情况的处理,比如多点共线,旋转角选取基准问题等;

算法思想及实现

Graham扫描法
思路:Graham扫描的思想是先找到凸包上的一个点,然后从那个点开始按顺时针方向逐个找凸包上的点,实际上就是进行极角排序,然后对其查询使用。(我们默认选择坐标系中最左下方的点作为初始点,角度以与y轴正方向为0°,顺时针至360°
在这里插入图片描述

步骤:
1.首先 判断点集中点的个数,若其中个数小于3,那么易得凸包包含所有点;
2.遍历所有点,找到最左下方的点,作为初始点开始寻找整个凸包;
3.遍历点集中所有不在凸包中的点,寻找与当前初始点形成旋转角最小,并且在保证前者的情况下满足距离最大,即这样的点即为下一个加入凸包集合里的点,一直循环直到下一个找到的点就是初始点,此时完整的凸包就形成了;
(此时还要考虑一种情况,在遍历点集时,它是一个无序集,所以存在第一次找点就找到了初始点,很明显这是不对的,所以要对这一情况做出相应的约束)
实现代码如下:

 if(points.size() < 3) {
    	            return points;
    	        }

Set<Point> set = new HashSet<>();
Point xmin = new Point(Double.MAX_VALUE, Double.MAX_VALUE);
for(Point item : points) {
    	if (item.x() < xmin.x() || (item.x() == xmin.x() && item.y() < xmin.y()))
    	                xmin = item;
 }

 Point nowPoint = xmin, tempPoint = xmin;
  double nowAngle = 0, minAngle = 360, tempAngle = 0;
  double distance;
 double maxdistance = -1;
  do{
   set.add(nowPoint);
   for(Point item : points) {
    if ((!set.contains(item) || (item == xmin&&set.size()!=1))  ) {
    tempAngle = calculateBearingToPoint(nowAngle, (int)nowPoint.x(), (int)nowPoint.y(), (int)item.x(), (int)item.y());
     distance = (item.x() - nowPoint.x())*(item.x() - nowPoint.x()) + (item.y() - nowPoint.y())*(item.y() - nowPoint.y());
    if(tempAngle < minAngle || ((tempAngle == minAngle) && (distance > maxdistance))) {
    minAngle = tempAngle;
    tempPoint = item;
    maxdistance = distance;
    	                    }
    	                }
    	            }
    minAngle = 360;
    nowAngle = minAngle;
    nowPoint = tempPoint;
 } while(nowPoint != xmin); 
 return set;

问题背景

实现并测试一个表示友谊的FriendshipGraph类社交网络,可以在图中计算两人之间的距离。一个辅助类Person也需要实现。

在FriendshipGraph类中出现了getDistance方法来计算两人间距离。在这里我们选择用广度优先搜索的原理来寻求实现。

回想在c语言中对二叉树的广度优先搜索中,其中设置了一个一维数组,来记录二叉树中的哪些点已经被访问过,并且还需要设置一个数组来记录最短距离。在java环境下,拥有更多得外部库供我们使用,想到了利用map接口来辅助我们。

map学习-map

Map用于保存具有映射关系的数据,Map集合里保存着两组值,一组用于保存Map的ley,另一组保存着Map的value;Map集合和查字典类似,通过key找到对应的value,通过页数找到对应的信息。用学生类来说,key相当于学号,value对应name,age,sex等信息。用这种对应关系方便查找。

Map集合的概述

interface Map<K,V> 其中K是键的类型,键是唯一的,不重复。V是值的类型,是可以重复。且每个键可以映射最多一个值。注意的是如果存在两个相同的键时,则会将现在的值替换之前的值。
特点:

  1. 键值对映射关系
  2. 一个键对应一个值
  3. 键不能重复,值可以重复
  4. 元素存取无序

常用方法:

1.声明一个Map :

Map map = new HashMap();

2 .向map中放值 ,注意: map是key-value的形式存放的,如:

map.put(“sa”,“dd”);

3 .从map中取值 :

String str = map.get(“sa”).toString();

结果是: str = "dd’

4 .遍历一个map,从中取得key和value :

Map m= new HashMap();

for(Object obj : map.keySet()){

Object value = map.get(obj );

}

getdistance实现

public int getDistance(Person a, Person b) {
		if (a.equals(b))
			return 0;
		Queue<Person> qu = new LinkedList<Person>();
		Map<Person, Integer> map = new HashMap<Person, Integer>();
		qu.offer(a);
		map.put(a, 0);
		while (!qu.isEmpty()) {
			Person first = qu.poll();
			List<Person> pal = first.friends;
			for (int i = 0; i < pal.size(); i++) {
				if (!map.containsKey(pal.get(i))) {
					qu.offer(pal.get(i));
					map.put(pal.get(i), map.get(first) + 1);
					if (pal.get(i).equals(b))
						return map.get(pal.get(i));
				}
			}
		}
		return -1;
	}

讨论

  1. try-catch-finally三体结构 详解
    try块和catch块中逻辑基本相同。try中出现异常跳转到catch,若catch中出现异常则跳转到finally,try或catch正常执行若存在return则先执行return的代码并保存返回值信息,然后执行finally,若finally中出现异常或包含return则执行结束,若无异常且没有return则会执行try或catch中的return或结束。
    示例代码:
try{
	//代码块
}catch(Exception1 e){
	//抛出异常后所要进行的操作
}finally
{   //代码块
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值