coursera 算法二 week 1 wordnet
这周的作业可谓是一波三折,但是收获了不少,熟悉了广度优先搜索还有符号图的建立。此外还知道了Integer.MAX_VALUE。
SAP:
求v和w的大概思路是对v和w分别广度优先搜索,然后遍历图中每一个顶点,如果v和w都可以到达一个顶点,就计算v和w到这一顶点的距离和,最后求出最短的距离以及对应的顶点便是所求length和ancestor。
至于Iterable<Integer> v和Iterable<Integer> w,开始我是求v中每一个顶点和w中的每一个顶点的距离,然后求出最短距离,但提交后时间测试通不过。参考了其他人的一些博客后发现可以遍历一次完成对v或w的广度优先搜索,于是自己写了一个BFS类。然而这次提交出现了OperationCountLimitExceededException,最后检查了半天才发现bfs时丢了一句 ' if(!marked[w]) '。。。后来发现官方提供的BreadthFirstDirectedPaths类可以完成Iterable<Integer> v的广度优先搜索,于是干脆直接调用这个。
但是提交后还是有问题。。。对于没有共同祖先的情况判断不正确,不能返回-1,检查了半天发现每次求length或ancestor都应该在前面加上 anc = -1; 否则这次求返回的是上次的anc。
import edu.princeton.cs.algs4.*;
import edu.princeton.cs.algs4.In; public class SAP {
private Digraph G;
private int anc = -1;
// constructor takes a digraph (not necessarily a DAG)
public SAP(Digraph G) {
if(G == null) throw new IllegalArgumentException();
this.G = new Digraph(G);
} // length of shortest ancestral path between v and w; -1 if no such path
public int length(int v, int w) {
if(v < 0 || v > G.V() - 1 || w < 0 || w > G.V() - 1)
throw new IllegalArgumentException();
anc = -1; BreadthFirstDirectedPaths bv = new BreadthFirstDirectedPaths(G, v);
BreadthFirstDirectedPaths bw = new BreadthFirstDirectedPaths(G, w); int minLength = Integer.MAX_VALUE; for(int i = 0; i < G.V(); i++) {
if(bv.hasPathTo(i) && bw.hasPathTo(i)) {
int l = bv.distTo(i) + bw.distTo(i);
if(l < minLength) {
minLength = l;
anc = i;
}
}
} if(minLength == Integer.MAX_VALUE) return -1;
else return minLength; } // a common ancestor of v and w that participates in a shortest ancestral path; -1 if no such path
public int ancestor(int v, int w) {
length(v, w);
return anc;
} // length of shortest ancestral path between any vertex in v and any vertex in w; -1 if no such path
public int length(Iterable<Integer> v, Iterable<Integer> w) {
if(v == null || w == null)
throw new IllegalArgumentException();
anc = -1; for(int i : v) {
if(i < 0 || i > G.V() - 1)
throw new IllegalArgumentException();
}
for(int i : w) {
if(i < 0 || i > G.V() - 1)
throw new IllegalArgumentException();
} BreadthFirstDirectedPaths bv = new BreadthFirstDirectedPaths(G, v);
BreadthFirstDirectedPaths bw = new BreadthFirstDirectedPaths(G, w); int minLength = Integer.MAX_VALUE; for(int i = 0; i < G.V(); i++) {
if(bv.hasPathTo(i) && bw.hasPathTo(i)) {
int l = bv.distTo(i) + bw.distTo(i);
if(l < minLength) {
minLength = l;
anc = i;
}
}
} if(minLength == Integer.MAX_VALUE) return -1;
else return minLength;
} // a common ancestor that participates in shortest ancestral path; -1 if no such path
public int ancestor(Iterable<Integer> v, Iterable<Integer> w) {
length(v, w);
return anc;
} // do unit testing of this class
public static void main(String[] args) { }
}
WordNet:
wordnet涉及到符号图的问题,开始用ST<String, Integer>来完成noun到id的索引,后来发现一个noun可能对应多个id,于是改为ST<String, Bag<Integer>>。
需要检查有向图是否合格:1.不能有环。通过类DirectedCycle完成。 2.只能有一个root。经参考别人的博客发现一个很巧妙的方法,如果一个顶点是根,那么它不指向其它顶点,所以它不会出现在hypernyms每行的第一个id。
方法sap需要通过id得到noun,用数组的话不能提前知道数组大小,于是参考网上用ArrayList<String>完成id到noun的索引。
import edu.princeton.cs.algs4.*;
import java.util.ArrayList; public class WordNet {
private ST<String, Bag<Integer>> st;
private ArrayList<String> idList;
private Digraph G; // constructor takes the name of the two input files
public WordNet(String synsets, String hypernyms) {
if(synsets == null || hypernyms == null) throw new IllegalArgumentException(); st = new ST<String, Bag<Integer>>();
idList = new ArrayList<String>(); int count = 0;
In in1 = new In(synsets);
while(in1.hasNextLine()) {
String[] a = in1.readLine().split(",");
String[] a2 = a[1].split(" "); for(int i = 0; i < a2.length; i++) {
if(st.contains(a2[i])) st.get(a2[i]).add(Integer.parseInt(a[0]));
else {
Bag<Integer> b = new Bag<Integer>();
b.add(Integer.parseInt(a[0]));
st.put(a2[i], b);
}
}
count++;
idList.add(a[1]);
} G = new Digraph(count);
In in2 = new In(hypernyms);
boolean[] isNotRoot = new boolean[count];
int rootNumber = 0; while(in2.hasNextLine()) {
String[] a = in2.readLine().split(",");
isNotRoot[Integer.parseInt(a[0])] = true;
for(int i = 1; i < a.length; i++)
G.addEdge(Integer.parseInt(a[0]), Integer.parseInt(a[i]));
} for(int i = 0; i < count; i++) {
if(!isNotRoot[i]) rootNumber++;
}
DirectedCycle d = new DirectedCycle(G);
if(rootNumber > 1 || d.hasCycle()) throw new IllegalArgumentException();
} // returns all WordNet nouns
public Iterable<String> nouns() {
return st.keys();
} // is the word a WordNet noun?
public boolean isNoun(String word) {
if(word == null) throw new IllegalArgumentException();
return st.contains(word);
} // distance between nounA and nounB (defined below)
public int distance(String nounA, String nounB) {
if(nounA == null || nounB == null || !isNoun(nounA) || !isNoun(nounB))
throw new IllegalArgumentException();
SAP s = new SAP(G);
Bag<Integer> ida = st.get(nounA);
Bag<Integer> idb = st.get(nounB); return s.length(ida, idb);
} // a synset (second field of synsets.txt) that is the common ancestor of nounA and nounB
// in a shortest ancestral path (defined below)
public String sap(String nounA, String nounB) {
if(nounA == null || nounB == null || !isNoun(nounA) || !isNoun(nounB))
throw new IllegalArgumentException();
SAP s = new SAP(G);
Bag<Integer> ida = st.get(nounA);
Bag<Integer> idb = st.get(nounB); int root = s.ancestor(ida, idb);
return idList.get(root);
} // do unit testing of this class
public static void main(String[] args) { }
}
Outcast:
public class Outcast {
private WordNet wordnet;
// constructor takes a WordNet object
public Outcast(WordNet wordnet) {
this.wordnet = wordnet;
}
// given an array of WordNet nouns, return an outcast
public String outcast(String[] nouns) {
int length = nouns.length;
int[][] distance = new int[length][length];
for(int i = 0; i < length; i++) {
for(int j = i; j < length; j++) {
distance[i][j] = wordnet.distance(nouns[i], nouns[j]);
}
}
int maxDistance = 0;
int sum = 0;
int num = 0;
for(int i = 0; i < nouns.length; i++) {
sum = 0;
for(int j = 0; j < nouns.length; j++) {
if(i < j)
sum += distance[i][j];
else
sum += distance[j][i];
}
if(sum > maxDistance) {
maxDistance = sum;
num = i;
}
}
return nouns[num];
}
// see test client below
public static void main(String[] args) {
}
}
coursera 算法二 week 1 wordnet的更多相关文章
- Coursera 算法二 week2 Seam Carving
这周作业设计到的算法是有向无环图的最短路径算法,只需要按照顶点的拓扑顺序去放松顶点即可.而在这个题目中拓扑顺序就是按照行的顺序或列的顺序. 用到的数据结构为一个二维数组picture同来存储每个像素的 ...
- Coursera 算法二 week 5 BurrowsWheeler
本打算周末完成这次作业,但没想到遇到了hard deadline,刚开始看不懂题意,后来发现算法4书上有个类似的问题,才理解了题意.最后晚上加班,上课加班,还好在11:35也就是课程结束前25分钟完成 ...
- Coursera 算法二 week 3 Baseball Elimination
这周的作业不需要自己写算法,只需要调用库函数就行,但是有些难以理解,因此用了不少时间. import edu.princeton.cs.algs4.FlowEdge; import edu.princ ...
- Coursera 算法二 week 4 Boggle
这次的作业主要用到了单词查找树和深度优先搜索. 1.在深度优先搜索中,在当前层的递归调用前,将marked数组标记为true.当递归调用返回到当前层时,应将marked数组标记为false.这样既可以 ...
- TensorFlow 入门之手写识别(MNIST) softmax算法 二
TensorFlow 入门之手写识别(MNIST) softmax算法 二 MNIST Fly softmax回归 softmax回归算法 TensorFlow实现softmax softmax回归算 ...
- 分布式共识算法 (二) Paxos算法
系列目录 分布式共识算法 (一) 背景 分布式共识算法 (二) Paxos算法 分布式共识算法 (三) Raft算法 分布式共识算法 (四) BTF算法 一.背景 1.1 命名 Paxos,最早是Le ...
- Floyd算法(二)之 C++详解
本章是弗洛伊德算法的C++实现. 目录 1. 弗洛伊德算法介绍 2. 弗洛伊德算法图解 3. 弗洛伊德算法的代码说明 4. 弗洛伊德算法的源码 转载请注明出处:http://www.cnblogs.c ...
- Dijkstra算法(二)之 C++详解
本章是迪杰斯特拉算法的C++实现. 目录 1. 迪杰斯特拉算法介绍 2. 迪杰斯特拉算法图解 3. 迪杰斯特拉算法的代码说明 4. 迪杰斯特拉算法的源码 转载请注明出处:http://www.cnbl ...
- Prim算法(二)之 C++详解
本章是普里姆算法的C++实现. 目录 1. 普里姆算法介绍 2. 普里姆算法图解 3. 普里姆算法的代码说明 4. 普里姆算法的源码 转载请注明出处:http://www.cnblogs.com/sk ...
随机推荐
- Logstash过滤插件
filter初级 Logstash安装 ### 设置YUM源 # rpm --import https://artifacts.elastic.co/GPG-KEY-elasticsearch # t ...
- bzoj2724: [Violet 6]蒲公英(分块)
传送门 md调了一个晚上最后发现竟然是空间开小了……明明算出来够的…… 讲真其实我以前不太瞧得起分块,觉得这种基于暴力的数据结构一点美感都没有.然而今天做了这道分块的题才发现分块的暴力之美(如果我空间 ...
- jmeter-提取器之正则表达式提取器
在接口测试中,有很多的接口参数值是需要从上一个接口的返回值中获取的,这个时候就可以用正则表达式提取器啦 例如: 接口1 /user/login 返回{ "user_ticket" ...
- 洛谷P2025 脑力大人之监听电话
题目描述 话说埃菲尔铁塔小区的房子只有一栋,且只有一层,其中每一家都装有一个监听器,具体地,如果编号为第i家的人给编号第\(j\)家的人打了电话,\(i \leq j\),当然,也会有些人无聊地自己给 ...
- ch8 -- useLK
useLK 光流法跟踪FAST角点 执行 ./useLK ../../data 运行程序. 光流法需要include<opencv2/video/tracking.hpp>,用到列表 ...
- Linux之数据库
crm 1.一定得会用linux发行版 centos 熟悉各种linux命令 2.你的确保linux服务器可以上网 , 一定得有ip地址,且确保dns解析正常 /etc/resolv.conf 3.上 ...
- string中执行sql语句
Spring(JdbcTemplate.class)中的queryForMap().queryForObject().queryForLong().queryForInt()等方法都会去调用publi ...
- jQuery Plugin Poshy Tip 使用 统一提示信息
项目到了后期,发现前端的提示信息不统一,解决思路如下: 1.回顾系统中tip出现的场景:表单验证提示信息.数据列表中随填随显 2.确定问题域:多条提示信息层叠.信息显示风格不统一 3.结论:找出一款合 ...
- 024 Swap Nodes in Pairs 交换相邻结点
给定一个链表,对每两个相邻的结点作交换并返回头节点.例如:给定 1->2->3->4,你应该返回 2->1->4->3.你的算法应该只使用额外的常数空间.不要修改列 ...
- hdu3949(线性基,求第k小的异或和
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3949 XOR Time Limit: 2000/1000 MS (Java/Others) Me ...