0

对于家庭作业,我必须创建一个可以在刽子手处作弊的程序。为了做到这一点,我需要想出一种通过单词字母位置将单词分组到家庭的方法。因此,例如,如果单词长度为 4,并且他们猜测“e”,那么“- - - e”的所有单词都将位于哈希图的 Arraylist 之一中,该模式作为键,所有“- e - -" 将在另一个相同的 hashmap 的 ArrayLists 中,以模式作为键。我的问题是,尽管我的程序能够识别模式。它仍然返回一个空集或一个包含所有单词的 ArrayList。一个多小时以来,我一直在尝试不同的事情,但我似乎无法让它们正确分组。任何帮助是极大的赞赏。

import java.util.ArrayList;
import java.lang.StringBuilder;
import java.util.HashMap;

public class EvilEngine 
{
HashMap<StringBuilder, ArrayList> families = new HashMap<StringBuilder, ArrayList>();
int k = 0;
ArrayList<String> currentList = new ArrayList();
StringBuilder blankPattern = new StringBuilder("");
StringBuilder newPattern = new StringBuilder("");


public void PatternMatcher(ArrayList wordlist, char guess, Integer wordlength)
{

    String word;
    int j = 0;
    int x = 0;
    int biggest = 0;
    StringBuilder longest = null;    

    while(x < wordlist.size())
    {
        int i = 0;
        int index = 0;
        for (i=0; i < wordlength; i++)
        {
            blankPattern = blankPattern.append("-");
        }
        boolean boo = false;
        newPattern = blankPattern;
        word = (String) wordlist.get(x);
        index = word.indexOf(guess);
        while (index >= 0) 
        {
            blankPattern.setCharAt(index, guess);
            newPattern = blankPattern;
            index = word.indexOf(guess, index + 1);
        }
        this.PatternCompiler(word,newPattern);
        blankPattern = blankPattern.delete(0,wordlength);
        x++;
    }
}
public void PatternCompiler (String word, StringBuilder pattern)
{
        if(!families.containsKey(pattern))
        {
            ArrayList<String> newPatternList = new ArrayList();
            newPatternList.add(word);
            families.put(pattern, newPatternList);
        }
        if (families.containsKey(pattern))
        {
            ArrayList<String> oldPatternList = new ArrayList();
            oldPatternList = families.get(pattern);
            oldPatternList.add(word);
            families.put(pattern, oldPatternList);
        }
        else {
            System.out.println("Error");
        }

}
public HashMap<StringBuilder, ArrayList> returnFamilies (){
    return families;
}
}
4

1 回答 1

0

虽然您的代码有几个或多或少的小问题,但我怀疑主要问题是您HashMap的键是 typeStringBuilder而不是String. HashMap使用hashCode()关键对象的功能来确定它是否已经在地图中。对于 a StringBuilder,哈希值可能只是对象的地址(使用从Object类继承的实现)。

由于newPattern是一个范围在函数之外的类级变量,当你将它传递给PatternCompiler()函数时,参数pattern只是对同一个类级对象的引用(即,将具有相同的哈希码)。而且这个对象(也不是它的哈希码)在你的代码中永远不会改变,因为它也是在类级别声明的,当你改变 的时,你永远不会改变它所引用的对象。因此,每次通过循环重新分配它不会改变任何东西(并且基本上是混乱的)。blankPatternblankPatternnewPatternwhile

要解决此问题,您需要将密钥类型HashMap设为 beString而不是StringBuilder. 该类String定义了一个hashCode()函数,该函数将根据字符串的实际内容(而不仅仅是对象的地址,如StringBuilder)返回不同的代码。(另外,如前所述,没有理由blankPattern在类级别而不是在PatternMatcher()函数内部声明,而且您根本不需要newPattern。)

虽然这是您的代码的主要问题,但另一个相当大的问题与您函数if中的第二个条件有关。PatternCompiler()在上一个if块中,如果该模式还没有一个新的 ArrayList 到族中,则将其添加到族中。所以无论如何,此时第二个if条件 ( if (families.containsKey(pattern))) 将是正确的。因为这两个块都添加word到 列表中families,所以某些单词可能会被添加两次。

祝你好运!

于 2013-04-25T05:57:38.597 回答