HIT软件构造实验2

知识共享许可协议 版权声明:署名,允许他人基于本文进行创作,且必须基于与原先许可协议相同的许可协议分发本文 (Creative Commons

1 实验目标概述

本次实验训练抽象数据类型(ADT)的设计、规约、测试,并使用面向对象 编程(OOP)技术实现 ADT。具体来说:
针对给定的应用问题,从问题描述中识别所需的 ADT;
 设计 ADT 规约(pre-condition、post-condition)并评估规约的质量;
 根据 ADT 的规约设计测试用例;
 ADT 的泛型化;
 根据规约设计 ADT 的多种不同的实现;针对每种实现,设计其表示 (representation)、表示不变性(rep invariant)、抽象过程(abstraction function)
 使用 OOP 实现 ADT,并判定表示不变性是否违反、各实现是否存在表 示泄露(rep exposure);
 测试 ADT 的实现并评估测试的覆盖度;
 使用 ADT 及其实现,为应用问题开发程序;
 在测试代码中,能够写出 testing strategy 并据此设计测试用例。

2 实验环境配置

简要陈述你配置本次实验所需环境的过程,必要时可以给出屏幕截图。特别是要记录配置过程中遇到的问题和困难,以及如何解决的。

在 Eclipse IDE 中安装配置 EclEmma(一个用于统计 JUnit 测试用例的代码覆盖度的 plugin)直接从Eclipse Market下载安装即可。
在这里给出你的GitHub Lab2仓库的URL地址(Lab2-学号)。
https://github.com/ComputerScienceHIT/Lab2-1170301026.git

3 实验过程

请仔细对照实验手册,针对三个问题中的每一项任务,在下面各节中记录你的实验过程、阐述你的设计思路和问题求解思路,可辅之以示意图或关键源代码加以说明(但千万不要把你的源代码全部粘贴过来!)。

3.1 Poetic Walks

分别在两个类ConcreteEdgesGraph,ConcreteVerticesGraph 实现Graph接口。
Graph接口要求实现add(添加新节点),set(添加新边),remove(移除节点),vertices(获得所有的节点集合),sources(target)获得以target为目标节点的边的起始节点,targes(source)获得以source为起始节点的边的目标节点。
Poet:假设存在一条由a到b的有向边,构造有向图,再给定一句子,如果句子中两个相邻单词在有向图中有一个中间单词,则将该单词插入到a与b中间,若存在多个中间单词,则插入权重最大的那个

3.1.1 Get the code and prepare Git repository

自https://github.com/rainywang/Spring2019_HITCS_SC_Lab2/tree/master/P1 获得实验代码。
Git命令:

git init
git remote add origin [email protected]:ComputerScienceHIT/Lab2-1170301026.git
git pull origin master
git add .
git commit -m “init”
git push origin master

3.1.2 Problem 1: Test Graph < String >

测试Graph需将empty改成如下:

更改empty函数
可运行GraphStaticTest进行测试

3.1.3 Problem 2: Implement Graph < String >

以下各部分,请按照MIT页面上相应部分的要求,逐项列出你的设计和实现思路/过程/结果。

3.1.3.1 Implement ConcreteEdgesGraph

  • 1 实现Edge< L >
Fileds 作用
private L source 起始节点
private L target 目标节点
private int weight 边权值
Method 作用
getsource() 返回有向边起始节点
gettarget() 返回有向边目标节点
getweight() 返回边权值
@Override toString() 使用@Override注释toString以确保正确覆盖Object方法的toString方法
/**
 * TODO specification Immutable. This class is internal to the rep of
 * ConcreteEdgesGraph.
 * 
 * <p>
 * PS2 instructions: the specification and implementation of this class is up to
 * you.
 */
class Edge<L> {

	// TODO fields
	private final L source;
	private final L target;
	private final int weight;
	// Abstraction function:
	// AF(source,target,weight)=an edge contains the source vertex,the target vertex label,weight
	// Representation invariant:
	// weight no negative number
	// Safety from rep exposure:
	// All fields are private;
    //   source and target are Strings, so are guaranteed immutable;
    //   use final to guarantee weight is immutable; 

	// TODO constructor
	public Edge(L s, L t, int w) {
		this.source = s;
		this.target = t;
		this.weight = w;
		checkRep();
	}
	// TODO checkRep
	//Check the rep invariant is true
	//***Warning:this does nothing unless you turn on assertion checking
	// by passing -enableassertions to Java
	private void checkRep() {
		assert weight>=0;
	}
	// TODO methods

	public L getsource() {
		checkRep();
		return source;
	}

	public L gettarget() {
		checkRep();
		return target;
	}

	public int getweight() {
		checkRep();
		return weight;
	}

	// TODO toString()
         @Override
	public String toString() {
		String tmp = null;
		tmp=source.toString()+target.toString()+Integer.toString(weight);
		checkRep();
		return tmp;

	}
}
  • 2.实现ConcreteEdgeGraph
method 作用
add(L vertex) 调用vertices.add,其返回结果为boolean且满足spec定义。
set(L source,L target,int weight) 检查输入满足weight!=0,若满足则调用edges.add添加边并返回weight,若满足weight=0且该边存在于edges中
remove(L vertex) 检查输入满足vertex存在vertices中,当存在时,删除该节点,同时删除所有与之相连的边
Set vertices 返回vertices
Sources(L target) 遍历edges,调用gettarget方法,若找到与tareget相同的,则将该边加入map中
Targets(L source) 遍历edges,调用getsource方法,若找到与source相同的,则将该边加入map中
@Override toString()
/* Copyright (c) 2015-2016 MIT 6.005 course staff, all rights reserved.
 * Redistribution of original or derived work requires permission of course staff.
 */


package src.P1.graph;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * An implementation of Graph.
 * 
 * <p>
 * PS2 instructions: you MUST use the provided rep.
 */
public class ConcreteEdgesGraph<L> implements Graph<L> {

	private final Set<L> vertices = new HashSet<>();
	private final List<Edge<L>> edges = new ArrayList<>();

	// Abstraction function:
	// AF(vertices,edges)=a graph with vertices and edges
	// Safety from rep exposure:
	// All fields are private
	// use final to guarantee immutable

	@Override
	public boolean add(L vertex) {
		try {
			if (!vertices.contains(vertex)) {
				vertices.add(vertex);
				return true;
			} else
				return false;
		} catch (Exception e) {
			throw new RuntimeException("not implemented");
		}

	}

	@Override
	public int set(L source, L target, int weight) {
		try {
			Edge<L> e = new Edge<L>(source, target, weight);
			if (weight != 0) {
				edges.add(e);
				return weight;
			} // if weight nozero,add edge and set weight
			else if (weight == 0 && edges.contains(e)) {
				edges.remove(e);
				return 0;
			} // if weight zero&the edge exists,
			else
				return 0;
		} catch (Exception e) {
			throw new RuntimeException("not implemented");
		}

	}

	@Override
	public boolean remove(L vertex) {
		try {
			if (vertices.contains(vertex)) {
				for (Edge<L> item : edges) {
					if (vertex == item.getsource() || vertex == item.gettarget()) {
						edges.remove(item);
					}
				}
				return vertices.remove(vertex);
			} else
				return false;

		} catch (Exception e) {
			throw new RuntimeException("not implemented");
		}
	}

	@Override
	public Set<L> vertices() {
		try {
			return vertices;
		} catch (Exception e) {
			throw new RuntimeException("not implemented");
		}
	}

	@Override
	public Map<L, Integer> sources(L target) {
		try 
		{
			Map <L,Integer>map=new HashMap<>();
			for(Edge<L> item:edges) 
			{
				if(target==item.gettarget()) 
				{
					 map.put(item.getsource(),Integer.valueOf(item.getweight()));	 
				}
			}
			return map;
		}
		catch(Exception e) 
		{
			throw new RuntimeException("not implemented");
		}
		
	}

	@Override
	public Map<L, Integer> targets(L source) {
		try 
		{
			Map <L,Integer>map=new HashMap<>();
			for(Edge<L> item:edges) 
			{
				if(source==item.getsource()) 
				{
					 map.put(item.gettarget(),Integer.valueOf(item.getweight()));	 
				}
			}
			return map;
		}
		catch(Exception e) 
		{
			throw new RuntimeException("not implemented");
		}
	}

	// TODO toString()
	@Override public String toString() {
		String tmp = null;
		tmp = getClass().getName() + '@' + Integer.toHexString(hashCode());
		return tmp;

	}
}

3.1.3.2 Implement ConcreteVerticesGraph

  • 1 实现Vertex< L >
Field 作用
private L label 节点名字
private Map<L,Integer> sources 所有以label为目标节点的边,<起始节点lable,边的权重>.
private Map<L,Integer> targets 所有以label为其实节点的边,<目标节点label,边的权重>
Interface 作用
setSource(L source,int weight) 检查输入满足source!=null,weight>=0。当weight==0时,调用this.removeSource,当weight>0时,调用Map.put修改source并且记录初始值。
removeSource(L source) 检查输入满足source!=null,调用sources.remove,并返回(不存在则返回0)。
setTarget(L target,int weight) 检查输入满足target!=null,weight>=0,当weight=0时,调用this.removeTarget,当weight>0时,调用targets.put并返回(不存在则返回0)。
removeTarget(L target) 检查满足target!=null。调用targets.remove(),返回。
remove(final L vertex) 调用removeSource和removeTarget
  • 2 实现ConcreteVerticeGraph
Method 实现思路
add(L vertex) 检查输入满足vertex!=null。遍历点集vertices,若已存在vertex则返回false,否则调vertices.add并返回true
set(L source,L target,int weight) 遍历点集两次,分别检查vertices中是否存在source vertex和target vertex,若均不存在则调用vertices.add并调用source.setTarget和target.setSource设置边和权值,
remove(L vertex) 检查输入满足vertex!=null。如果输入节点不存在则返回false,否则,遍历vertices中的每一个节点调用v.remove在targes和sources中删除该节点,
Set vertices(L vertex) 遍历点集,找到Label与vertex相同的点并加入Setans中,最后返回ans
Sources(L target) 遍历点集.如果没有target则返回空集合,否则调用targetVertex.getSources(target)
Targets(L source) 遍历点集如果没有target则返回空集合,否则调用sourceVertex.getTargets(source)

3.1.4 Problem 3: Implement generic Graph< L >

3.1.4.1 Make the implementations generic

将类及接口声明改为:
ConcreteVerticesGraph< L >
ConcreteEdgeGraph< L >

3.1.5 Problem 4: Poetic walks

3.1.5.1 Test GraphPoet

在这里插入图片描述

Field 说明
Private final Graph affinityGraph 配置文件生成的Graph
Private final List corpusWord 文集包含的单词

3.1.5.3 Graph poetry slam

  • main函数:
    在这里插入图片描述

3.2 Re-implement the Social Network in Lab1

用P1中实现的ConcreteEdgeGraph或者ConcreteVertexGraph实现FriendshipGraph

3.2.1 FriendshipGraph类

public class FriendshipGraph extends ConcreteEdgesGraph<Person> {

	/**
	 * Add Vertex(Person)
	 * 
	 * @param a person p
	 */
	public void addVertex(Person p) {
		this.add(p);
	}

	/**
	 * Add Edge
	 * 
	 * @param Person pa
	 * @param Person pb
	 * @param weight
	 */
	public void addEdge(Person pa, Person pb, int w) {
		this.set(pa, pb, w);
	}

	/**
	 * Calculate the distance between two person
	 * 
	 * @param a person pa
	 * @param a person pb
	 * @return the shortest distance between two person,return -1 if personA can't
	 *         reach personB
	 */
	public int getDistance(Person pa, Person pb) {
		if (pa == pb) {
			return 0;
		}
		int dis = 1;
		// BFS
		Queue<Person> queue = new LinkedList<Person>();
		// use LinkedList to implement queue
		Map<Person, Integer> map = new HashMap<Person, Integer>();
		queue.offer(pa);
		while (!queue.isEmpty()) // queue not empty
		{
			Person p = queue.poll();// return top person
			Map<Person, Integer> neighbour = this.targets(p);
			Iterator entries = neighbour.entrySet().iterator();
			// Traversing the map to find key person
			while (entries.hasNext()) {
				Map.Entry<Person, Integer> entry = (Map.Entry<Person, Integer>) entries.next();
				Person key = entry.getKey();
				Integer value = entry.getValue();
				if (!map.containsKey(key)) {
					map.put(key, value);
					queue.offer(key);
					if (key == pb) {
						return map.get(key);
					}
				}
			}
			dis++;
		}
		return -1;
	}
}
函数 实现思路
addVertex(Person p) 调用父类接口this.add(newPerson)
addEdge(Person pa,Person pb) 调用父类接口this.set(pa,pb,1)
getDistance(Person pa,Person pb) 使用BFS算法求得图中stPerson与edPerson之间的最短距离,BFS中需要遍历邻居节点,遍历map并调用父类接口的targets方法获得父类接口

3.2.2 Person类

在这里插入图片描述

3.2.3 客户端main()

与实验一中基本一致

3.2.4 测试用例

直接采用实验一测试代码,认识的两人之间权值设置为1即可

猜你喜欢

转载自blog.csdn.net/franc0106/article/details/93399860
今日推荐