簡體   English   中英

如何解決排序的字謎

[英]How to solve for sorted anagrams

我有一個單詞表,如下。

pear amleth dormitory tinsel dirty room hamlet listen silnet

我想找出所有字謎並將它們按排序順序列出。 如果未找到任何內容,則輸出該單詞。 因此,在上述情況下,輸出應為。

amleth,hamlet dirty room,dormitory listen,silnet,tinsel pear

以下是我為此編寫的Java代碼。

public class Anagram {

    private  boolean isAnagram(String s1, String s2) {

        if (s1.length() != s2.length()) {
            return false;
        }
        Map<Character, Integer> anagramMap = new HashMap<>();
        for (char ch = 'a'; ch <= 'z'; ++ch) 
             anagramMap.put(ch, 0); 
        for(int i=0; i<s1.length(); i++){
            anagramMap.put(s1.charAt(i), anagramMap.get(s1.charAt(i))+1);
        }
        for(int j=0; j<s2.length(); j++) {
            if (anagramMap.get(s2.charAt(j)) != 0) {
                anagramMap.put(s2.charAt(j), anagramMap.get(s2.charAt(j)) - 1);
            }
        }
        for(int value : anagramMap.values()) {
            if (value != 0) {
                return false;
            }
        }
        return true;
    }
    private void solveChallenge(List<String> words) {
        for(int i=0 ;i<(words.size()-1); i++) {
            Set<String> result = new TreeSet<>();
            for(int j=(i+1); j< words.size(); j++) {
                if (isAnagram(words.get(i), words.get(j))){
                    result.add(words.get(i) + " " + words.get(j));
                    System.out.println(result);
                    words.remove(j);
                }
            }
        }
    }

    public static void main(String[] args) {
        Anagram anagram = new Anagram();
        List<String> words = new ArrayList<>();
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        try {
            String line = reader.readLine();
            Integer numTestCases = Integer.parseInt(line);
            while (--numTestCases >= 0){
                words.add(reader.readLine().replaceAll("\\s+","").toLowerCase());
            }
            System.out.println(words);
            new Anagram().solveChallenge(words);
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}

但是它沒有列出所需的輸出。 我得到的輸出是[amleth hamlet] [dormitory dirtyroom] [tinsel lisetn]

有人可以告訴我這里有什么問題嗎?

這將解決您的問題

public class Anagram {

private  boolean isAnagram(String s1, String s2) {

    if (s1.length() != s2.length()) {
        return false;
    }
    Map<Character, Integer> anagramMap = new HashMap<>();
    for (char ch = 'a'; ch <= 'z'; ++ch) 
         anagramMap.put(ch, 0); 
    for(int i=0; i<s1.length(); i++){
        anagramMap.put(s1.charAt(i), anagramMap.get(s1.charAt(i))+1);
    }
    for(int j=0; j<s2.length(); j++) {
        if (anagramMap.get(s2.charAt(j)) != 0) {
            anagramMap.put(s2.charAt(j), anagramMap.get(s2.charAt(j)) - 1);
        }
    }
    for(int value : anagramMap.values()) {
        if (value != 0) {
            return false;
        }
    }
    return true;
}
private void solveChallenge(List<String> words) {
    for(int i=0 ;i<(words.size()-1); i++) {
        Set<String> result = new TreeSet<>();
        int j = i+1;
        while(j < words.size()) {
            if (isAnagram(words.get(i), words.get(j))){
                result.add(words.get(i) + " " + words.get(j));
                System.out.println(result);
                words.remove(j);
            } else {
             j++;
           }
        }
    }
}

public static void main(String[] args) {
    Anagram anagram = new Anagram();
    List<String> words = new ArrayList<>();
    BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
    try {
        String line = reader.readLine();
        Integer numTestCases = Integer.parseInt(line);
        while (--numTestCases >= 0){
            words.add(reader.readLine().replaceAll("\\s+","").toLowerCase());
        }
        System.out.println(words);
        new Anagram().solveChallenge(words);
    } catch (IOException e) {
        e.printStackTrace();
    }

}
}

僅當不刪除任何元素時才應增加j,因為那個remove()方法會引起問題。

現在,我建議您使用HashMap <String,ArrayList <String >>這樣的數據結構。 希望這可以幫助 :)

這就是我要做的:

  • 為每個單詞創建一個Map<Character, Integer> ,其中包含單詞的字符(不包括空格)和出現的次數-您已經做過類似的事情
  • 然后將它們存儲在Map<Map<Character, Integer>, List<String>> ,其中鍵是出現的映射,值是所有匹配的單詞(字謎)的列表。 Map::equals將自動為您進行比較。

示例實現如下所示:

String[] words = ("pear", "amleth", ... }'
Map<Map<Integer, Long>, List<String>> characters = new HashMap<> ();
for (String word : words) {
  //here I'm using a stream, but you can build the occurences map manually
  Map<Integer, Long> occurences = word.replaceAll("\\s+", "") //remove spaces
                   .chars().boxed()
                   .collect(Collectors.groupingBy(i -> i, Collectors.counting()));

  if (characters.containsKey(occurences)) { //anagram found !
    characters.get(occurences).add(word); //add the word to the list
  } else { //no anagram found, create the list, with only one item
    List<String> list = new ArrayList<> ();
    list.add(word);
    characters.put(occurences, list);
  }
}

//you may want to sort the lists here

characters.values().forEach(System.out::println);

您在代碼中犯了一些錯誤。 首先,您需要更改將字謎存儲在集合中的邏輯。 您將這pair存儲在這里,而不是應該將所有字謎存儲在這里。 因此,您可以擁有一個StringBuildersingle存儲anagrams ,並且在迭代之后,可以將其添加到集合中。

另一個錯誤是在此循環中:

for(int j=(i+1); j< words.size(); j++) {
    if (isAnagram(words.get(i), words.get(j))){
        result.add(words.get(i) + " " + words.get(j));
        System.out.println(result);
        words.remove(j);
    }
}

在這里,您要從列表中刪除一個element ,然后將j遞增。因此,在刪除之后,所有元素都可能會向前移1位置,因此,如果下一個元素是anagram那么您將在遞增j錯過它。 最后一個錯誤是您需要檢查words列表的所有元素。 因為最后一個元素可能沒有與任何其他元素相交,所以要求將其分開對待。

因此,對solveChallenge()函數進行一些更改:

private void solveChallenge(List<String> words) {
    for(int i=0 ;i<(words.size()); i++) {
        Set<String> result = new TreeSet<>();
        StringBuilder resultant_string = new StringBuilder(words.get(i)); //To store the all anagrams
        for(int j=(i+1); j< words.size(); j++) {
            if (isAnagram(words.get(i), words.get(j))){
                resultant_string.append(" ").append(words.get(j));
                words.remove(j);
                j--;       //If anagram found, stay on the current element
            }
        }
        result.add(resultant_string.toString());
        System.out.println(resultant_string);
    }
}

根據您的需要,我對該程序進行了一些更改。

碼:

class Anagram {

    private  boolean isAnagram(String s1, String s2) {
        s1=s1.replaceAll("\\s+","");
        s2=s2.replaceAll("\\s+","");
        if (s1.length() != s2.length()) {
            return false;
        }
        Map<Character, Integer> anagramMap = new HashMap<>();
        for (char ch = 'a'; ch <= 'z'; ++ch) 
             anagramMap.put(ch, 0); 
        for(int i=0; i<s1.length(); i++){
            anagramMap.put(s1.charAt(i), anagramMap.get(s1.charAt(i))+1);
        }
        for(int j=0; j<s2.length(); j++) {
            if (anagramMap.get(s2.charAt(j)) != 0) {
                anagramMap.put(s2.charAt(j), anagramMap.get(s2.charAt(j)) - 1);
            }
        }
        for(int value : anagramMap.values()) {
            if (value != 0) {
                return false;
            }
        }
        return true;
    }
    private void solveChallenge(List<String> words) {
        List<String> result = new ArrayList<>();
        for(int i=0 ;i<(words.size()); i++) {
            List<String> resultant_strings=new ArrayList<> ();
            resultant_strings.add(words.get(i));

            for(int j=(i+1); j< words.size(); j++) {
                if (isAnagram(words.get(i), words.get(j))){
                    resultant_strings.add(words.get(j));
                    words.remove(j);
                    j--;
                }
            }
            Collections.sort(resultant_strings);
            String resultant_string=resultant_strings.toString();
            result.add(resultant_string);
        }
        Collections.sort(result);
        System.out.println(result);
    }

    public static void main(String[] args) {
        Anagram anagram = new Anagram();
        List<String> words = new ArrayList<>();
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        try {
            String line = reader.readLine();
            Integer numTestCases = Integer.parseInt(line);
            while (--numTestCases >= 0){
                words.add(reader.readLine().toLowerCase());
            }
            System.out.println(words);
            new Anagram().solveChallenge(words);
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}

打印結果:

[[amleth, hamlet], [dirty room, dormitory], [listen, silnet, tinsel], [pear]]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM