我正在尝试在Java / Processing中创建一个马尔可夫链,它将读取一本书,然后能够以概率的方式将其删除。编程是一种爱好......
我认为这样做的方法是使用HashMap,并在其中存储Word对象。我可以使用String轻松完成此操作,但在每个独特的Word中,它需要有另一个HashMap,它将为后面的单词存储更多的Word对象,依此类推,直到我们制作出具有足够复杂程度的模型。
问题是我似乎无法通过String name
检查Word对象是否已经在Map中。
通过环顾四周,我可以看到我可能需要一个比较器 - 但我看到的所有例子都使用compare
或compareTo
,当我认为我需要一些东西时那更像是equals
?我不需要任何与排序有关的事情,订单将在程序的第二部分中解决。
下面的代码非常可怕 - 我一直在讨论这个问题很长时间但我找不到足够愚蠢的解释让我理解它。
在Pseudo中:
read book
If the Word is not in the Map, put it in there
If the Word is in the Map, iterate the key
Check the Words that follow this Word, and check in the same way if they are within the first Word’s Map, adding as necessary… repeat…
完成后
Using the Integer values as probabilities, pick a word
from that Word’s Map, find a Word that is probable to follow it
repeat until desired length is achieved
代码:
///markovs
import java.util.HashSet;
import java.util.Comparator;
HashMap<Word, Integer> book;
void setup()
{
book = new HashMap<Word, Integer>();
String[] rows = loadStrings("crash.txt");
for (int i = 0; i < rows.length; i++)
{
if (trim(rows[i]).length() == 0)
{
continue;
}
String[] pieces = split(rows[i], " ");
for (int j = 0; j<pieces.length; j++)
{
Word temp = new Word(pieces[j]);
//c++;
if (book.compare(temp)) {
println("this worked for once");
//iterate here
} else {
book.put(temp, 1);
println("didn’t work");
//book.add(temp);
book.put(temp, 1);
}
}
}
println(book.size());
//println(c);
//println(book);
}
class WordComparator implements Comparator<Word> {
@Override
public int compare(Word w1, Word w2) {
String w1name = w1.name;
String w2name = w2.name;
if (w1name.equals(w2name)) {
return 1;
} else {
return 0;
}
}
}
class Word
{
String name;
int value=1;
int depth;
HashMap<String, Integer> list;
Word(String name_)
{
this.name = name_;
}
int compareTo(Word w) {
if (w.name.equals(this.name)) {
return 0;
} else {
return -1;
}
}
Word(Word w)
{
this.depth = w.depth+1;
}
void nextWord(String word)
{
}
void count() {
value++;
}
void makeHash()
{
list = new HashMap<String, Integer>();
}
}
答案 0 :(得分:0)
要将对象用作HashMap中的键,您需要覆盖两个方法:equals()
和hashCode()
。我不确定您的目的是什么,但只使用name
变量的简单示例如下所示:
public boolean equals(Object other){
if(other instanceof Word){
return this.name.equals(((Word)other).name);
}
return false;
}
public int hashCode(){
return name.hashCode();
}
但是,如果您仍然只是使用name
变量,那么您可能正在寻找 multimap ,这只是一个包含Map的Map。
HashMap<String, HashMap<String, Integer>> bookMap;
此外,虽然HashMap
不使用compareTo
功能,但您实施它的方式似乎已关闭。首先,您需要在类上实现Comparable:
class Word implements Comparable<Word>{
其次,compareTo
函数应返回3个值中的一个:负数,零或正数。现在你只返回零或负面,这没有任何意义。
我认为你可能最好退后一步,描述一下你实际上要做的事情,因为你的代码现在包含了许多令人困惑的逻辑。
答案 1 :(得分:0)
对于比较,您可以覆盖Object的继承equals方法,例如:
@ Override
boolean equals(Object o) {
return o instanceof Word
? o.name.equals(name) : false;
}
答案 2 :(得分:-1)
请注意使用您自己的类型作为HashMap
的键,在本例中为Word
。如果您在.hashCode()
上提供.equals()
和Word
的明智实施,那么效果会很好。
此处看起来您可以使用String
代替。 String
已经具有所需的方法实现。如果您确实想使用Word
,可以使用String中的那些方法。 e.g。
class Word {
String letters;
public int hashCode() {
return letters.hashCode();
}
public boolean equals(Object o) {
if (o == null || o.getClass() != getClass()) return false;
return letters.equals(((Word) o).letters);
}
}
您不需要compare
或compareTo
,只需要这两个。