马尔可夫链的比较器和HashMaps

时间:2015-07-24 14:05:36

标签: java hashmap processing comparator comparable

我正在尝试在Java / Processing中创建一个马尔可夫链,它将读取一本书,然后能够以概率的方式将其删除。编程是一种爱好......

我认为这样做的方法是使用HashMap,并在其中存储Word对象。我可以使用String轻松完成此操作,但在每个独特的Word中,它需要有另一个HashMap,它将为后面的单词存储更多的Word对象,依此类推,直到我们制作出具有足够复杂程度的模型。

问题是我似乎无法通过String name检查Word对象是否已经在Map中。

通过环顾四周,我可以看到我可能需要一个比较器 - 但我看到的所有例子都使用comparecompareTo,当我认为我需要一些东西时那更像是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>();
  }
}

3 个答案:

答案 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);
    }
}

您不需要comparecompareTo,只需要这两个。