如何将一个数组中混乱的单词与Java中另一个数组中正确的拼写单词相匹配?

时间:2015-03-16 14:13:22

标签: java arrays

假设我有两个字符串数组,一个包含字母混乱的单词,另一个包含正确拼写单词的数组(例如,第一个数组中的aabann与第二个数组中的banana相匹配)。 )

除了将乱码字的每个排列与正确单词数组中的每个单词进行比较的强力方法之外,使用相当简单的代码进行此操作的初学者方法是什么?

5 个答案:

答案 0 :(得分:2)

试试这个

    package com.se;

import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

public class JumbledWords {

    public void doTask(){

        String[] words = { "apple", "banana", "kiwi", "Water", "Football", 
                "Ocean", "Game", "Fear", "Frost", "Crocodile", 
                "Rabbit", "Road", "Blockbuster", "Cruise", "Light", "aba"};


        String[] jumbledWords = { "aabann", "wiki", "plepa", "Water", "Football", 
                "ncaOe", "maGe", "Frae", "tFors", "rCoodciel", 
                "baRitb", "doRa", "btBulockser", "urCise", "itLgh", "bab"};

        Map<String, String> foundWords = new HashMap<String, String>();

        for(String jwItem : jumbledWords){

            char[] wordChars = jwItem.toCharArray();
            Arrays.sort(wordChars);

            for(String w : words){
                char[] jwChars = w.toCharArray();
                Arrays.sort(jwChars);

                String str1 = new String(wordChars);
                String str2 = new String(jwChars);

                if(str1.equalsIgnoreCase(str2)){
                    foundWords.put(w, jwItem);
                }
            }
        }

        System.out.println(foundWords);
    }

    public static void main(String[] args) {

        Date date1 = new Date();


        JumbledWords jw = new JumbledWords();
        jw.doTask();

        Date date2 = new Date();
        System.out.println("Time Taken: " + (date2.getTime() - date1.getTime()));
    }
}

但这是区分大小写的。

<强>更新

对于不区分大小写的匹配,我已将word = word.toLowerCase();放在getCharacterList方法中。

更新2

删除了转换为ArrayList,直接将代码应用于数组。

更新3

之前的代码有一点bug。现在代码已得到纠正。它现在更紧凑。

答案 1 :(得分:1)

首先尝试我会使用levenshtein距离算法来找到索引之间的最低变化量;)

你可以找到一个impl。这个算法在apache commons lang StringUtils中 http://commons.apache.org/proper/commons-lang/javadocs/api-3.3.2/index.html

如果这还不够,你可以做这样的事情。

使用像metaphor或soundex这样的语音算法来生成两个数组的语音字符串值,而不是使用levenshtein来比较它们。 phonetik算法会缩短字符串并将它们带入更加语音的语音语言中,其中levenshtein距离越低的可能性越大。

这是拼写等等的方式。

答案 2 :(得分:0)

假设我的假设是正确的,我会使用以下策略。

我的假设:第二个数组中的一个字符串与第一个数组中的条目匹配,否则会有多个答案。

策略: 对于数组和其中的每个单词,找到与其计数一起使用的确切字符/文字。 然后在两个数组之间进行比较,并检查两者中哪一个在字符方面与它们的计数完全匹配。

那会给出答案

答案 3 :(得分:0)

我会将每个字符串转换为包含整个单词的Word和每个字符的映射,并将其计数,然后只需比较它,示例应该是这样的:

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class Main {

    public static void main (String[] args) {
        List<Word> messed = new ArrayList<Word>();
        messed.add(new Word("aabann"));
        messed.add(new Word("mosue"));
        messed.add(new Word("atomich"));

        List<Word> correct = new ArrayList<Word>();
        correct.add(new Word("mouse"));
        messed.add(new Word("athomic"));
        correct.add(new Word("banana"));

        for (Word messedWord : messed) {
            System.out.println(messedWord.getOriginalWord());
            for (Word correctWord : correct) {
                if (correctWord.compareTo(messedWord) == 0) {
                    System.out.println(correctWord.getOriginalWord());
                }
            }
        }
    }
}

class Word implements Comparable<Word> {

    Map<String, Integer> characters;

    String originalWord;

    public Word(String originalWord) {
        this.originalWord = originalWord;

        characters = new HashMap<String, Integer>();
        for (int i = 0; i < originalWord.length(); i++) {
            String key = String.valueOf(originalWord.charAt(i));
            Integer counter = characters.get(key);
            if (counter == null) {
                characters.put(key, 1);
            } else {
                characters.put(key, counter.intValue() + 1);
            }
        }
    }

    public Map<String, Integer> getCharacters () {
        return characters;
    }

    @Override
    public int compareTo (Word arg0) {
        if (arg0.getCharacters().size() != this.getCharacters().size()) {
            return -1;
        }
        for (String character : this.getCharacters().keySet()) {
            if (this.getCharacters().get(character).intValue() != arg0
                    .getCharacters().get(character).intValue()) {
                return -1;
            }
        }
        return 0;
    }

    public String getOriginalWord () {
        return originalWord;
    }
}

输出是每个混乱的单词并且拼写正确:

aabann
banana
mosue
mouse
atomich
athomic

答案 4 :(得分:0)

我提出了一种基于键来比较字符串的解决方案。 密钥将根据字符及其在单词中的计数生成。 例如:

word: banana -> key: a3b1n2
word: aabann -> key: a3b1n2

如果键匹配则执行字符串。 下面是支持上述方法的Java代码。

import java.util.Arrays;
import java.util.Map;
import java.util.HashMap;

public class WordCompare
{
    public static String getKey(String str) {
      char[] arr = str.toLowerCase().toCharArray();
      Arrays.sort(arr);
      return new String(arr);
    }

    public static void main(String[] args)
    {
       String[] correct = { "apple", "banana", "kiwi", "Abba"};
       String[] mixedup = { "aabann", "wiki", "plepa", "Baba"};

       Map<String, String> lookup = new HashMap<>(correct.length);
       for (String str : correct) {
         lookup.put(getKey(str), str);
       }

       for (String mix : mixedup) {
         String key = getKey(mix);
         String match = lookup.get(key);
         System.out.format("%s = %s\n", mix, match);
       }
    }

}