这周的作业可谓是一波三折,但是收获了不少,熟悉了广度优先搜索还有符号图的建立。此外还知道了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的更多相关文章

  1. Coursera 算法二 week2 Seam Carving

    这周作业设计到的算法是有向无环图的最短路径算法,只需要按照顶点的拓扑顺序去放松顶点即可.而在这个题目中拓扑顺序就是按照行的顺序或列的顺序. 用到的数据结构为一个二维数组picture同来存储每个像素的 ...

  2. Coursera 算法二 week 5 BurrowsWheeler

    本打算周末完成这次作业,但没想到遇到了hard deadline,刚开始看不懂题意,后来发现算法4书上有个类似的问题,才理解了题意.最后晚上加班,上课加班,还好在11:35也就是课程结束前25分钟完成 ...

  3. Coursera 算法二 week 3 Baseball Elimination

    这周的作业不需要自己写算法,只需要调用库函数就行,但是有些难以理解,因此用了不少时间. import edu.princeton.cs.algs4.FlowEdge; import edu.princ ...

  4. Coursera 算法二 week 4 Boggle

    这次的作业主要用到了单词查找树和深度优先搜索. 1.在深度优先搜索中,在当前层的递归调用前,将marked数组标记为true.当递归调用返回到当前层时,应将marked数组标记为false.这样既可以 ...

  5. TensorFlow 入门之手写识别(MNIST) softmax算法 二

    TensorFlow 入门之手写识别(MNIST) softmax算法 二 MNIST Fly softmax回归 softmax回归算法 TensorFlow实现softmax softmax回归算 ...

  6. 分布式共识算法 (二) Paxos算法

    系列目录 分布式共识算法 (一) 背景 分布式共识算法 (二) Paxos算法 分布式共识算法 (三) Raft算法 分布式共识算法 (四) BTF算法 一.背景 1.1 命名 Paxos,最早是Le ...

  7. Floyd算法(二)之 C++详解

    本章是弗洛伊德算法的C++实现. 目录 1. 弗洛伊德算法介绍 2. 弗洛伊德算法图解 3. 弗洛伊德算法的代码说明 4. 弗洛伊德算法的源码 转载请注明出处:http://www.cnblogs.c ...

  8. Dijkstra算法(二)之 C++详解

    本章是迪杰斯特拉算法的C++实现. 目录 1. 迪杰斯特拉算法介绍 2. 迪杰斯特拉算法图解 3. 迪杰斯特拉算法的代码说明 4. 迪杰斯特拉算法的源码 转载请注明出处:http://www.cnbl ...

  9. Prim算法(二)之 C++详解

    本章是普里姆算法的C++实现. 目录 1. 普里姆算法介绍 2. 普里姆算法图解 3. 普里姆算法的代码说明 4. 普里姆算法的源码 转载请注明出处:http://www.cnblogs.com/sk ...

随机推荐

  1. Git fatal:$'GIT_DIR' too big

    这句表示的是创建的文件的名称太长了,将你需要放置的代码的文件名字改短一些即可!

  2. ARC085E(最小割规划【最大流】,Dinic当前弧优化)

    #include<bits/stdc++.h>using namespace std;typedef long long ll;const ll inf=0x3f3f3f3f;int cn ...

  3. python之03编码学习

    编码介绍 ASCII :只能存英文和拉丁字符,一个字符占一个字节,8位 在中国的发展: gb2312:存6700多个中文      1980年 gbk1.0 :存2万多字符             1 ...

  4. mysql设置最大连接数量

    mysql>mysql -uuser -ppassword(命令行登录MySQL) mysql>show variables like 'max_connections';(查可以看当前的 ...

  5. poj3694(lca + tarjan求桥模板)

    题目链接: http://poj.org/problem?id=3694 题意: 给出一个 n 个节点 m 条边的图, 然后有 q 组形如 x, y 的询问, 在前面的基础上连接边 x, y, 输出当 ...

  6. 置换群(本蒟蒻瞎BB的)(未完)

    置换群(本蒟蒻瞎BB的)(未完) 群的定义 给定一个集合\(G=\{a, b, c...\}\)和集合\(G\)上的二元运算*,并满足: 封闭性:\(\forall a, b \in G, \exis ...

  7. 关于map 及 map 骚操作

    关于map这个东西   很冷门..................   但是,这个博客带你稍微了解一下map:   map用法:一般当作一个下表无穷大的数组   关于它的骚操作:map的鬼畜用法,可以 ...

  8. Luogu P3546 [POI2012]PRE-Prefixuffix 神奇的递推+哈希

    设$f[i]$表示切掉前$i$位和后$i$位后,即剩下$s[i+1]到s[n-i]$,的公共前后缀长度.此时我们发现,$f[i-1]$相对于$f[i]$少切了两个$char$,所以有$f[i-1]\l ...

  9. 移动端APP第一次登录和自动登录流程

    App登陆保存数据流程App因为要实现自动登陆功能,所以必然要保存一些凭据,所以比较复杂. App登陆要实现的功能: 密码不会明文存储,并且不能反编绎解密: 在服务器端可以控制App端的登陆有效性,防 ...

  10. python3 下载 以及 练习1 以及 pycharm 专业版 安装

    下载python: https://www.python.org/downloads/release/python-365/ ########sample 1 下载pycharm 社区版本,但是web ...