[英]How to solve for sorted anagrams
I have a list of words as follows. 我有一个单词表,如下。
pear amleth dormitory tinsel dirty room hamlet listen silnet
I want to find out all anagrams and list them in sorted order. 我想找出所有字谜并将它们按排序顺序列出。 If nothing is found just output that word.
如果未找到任何内容,则输出该单词。 So in the above case the output should be.
因此,在上述情况下,输出应为。
amleth,hamlet dirty room,dormitory listen,silnet,tinsel pear
Below is the java code I have written for that. 以下是我为此编写的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();
}
}
}
But it's not listing the desired output. 但是它没有列出所需的输出。 The output I get is
[amleth hamlet] [dormitory dirtyroom] [tinsel lisetn]
我得到的输出是
[amleth hamlet] [dormitory dirtyroom] [tinsel lisetn]
Can someone tell me what is wrong here? 有人可以告诉我这里有什么问题吗?
This will solve your problem 这将解决您的问题
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();
}
}
}
You should increment j only when you are not removing any element because that remove() method caused problems. 仅当不删除任何元素时才应增加j,因为那个remove()方法会引起问题。
Now I would recommend you should use HashMap< String, ArrayList< String>> something like this data structure. 现在,我建议您使用HashMap <String,ArrayList <String >>这样的数据结构。 Hope this helps :)
希望这可以帮助 :)
This is how I would go about it: 这就是我要做的:
Map<Character, Integer>
that contains the characters of the word (excluding spaces) and the number of occurence - you have already done something similar Map<Character, Integer>
,其中包含单词的字符(不包括空格)和出现的次数-您已经做过类似的事情 Map<Map<Character, Integer>, List<String>>
, where the key is the map of occurences and the value is a list of all the words that match (anagrams). Map<Map<Character, Integer>, List<String>>
,其中键是出现的映射,值是所有匹配的单词(字谜)的列表。 Map::equals
will do the comparison automagically for you. Map::equals
将自动为您进行比较。 A sample implementation could look like this: 示例实现如下所示:
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);
You have made few mistakes in the code. 您在代码中犯了一些错误。 First of all you need to change the logic of storing the anagrams in the set.
首先,您需要更改将字谜存储在集合中的逻辑。 You are storing here
pair
in the set rather you should store all anagrams here. 您将这
pair
存储在这里,而不是应该将所有字谜存储在这里。 So you can have a StringBuilder
to store the anagrams
in a single
pass and after the iteration, You can add it to the set. 因此,您可以拥有一个
StringBuilder
来single
存储anagrams
,并且在迭代之后,可以将其添加到集合中。
Another mistake is in this loop: 另一个错误是在此循环中:
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);
}
}
Here you are removing an element
from the list and then incrementing j
So it is possible that after removal, all elements gets shifted ahead by 1
place so If next element is anagram
then you will miss it as you are incrementing j
. 在这里,您要从列表中删除一个
element
,然后将j
递增。因此,在删除之后,所有元素都可能会向前移1
位置,因此,如果下一个元素是anagram
那么您将在递增j
错过它。 And last mistake is that you need to check for all elements of words
list. 最后一个错误是您需要检查
words
列表的所有元素。 Because it may possible that last element is not anagram with any other element, Then it is required to be taken separately. 因为最后一个元素可能没有与任何其他元素相交,所以要求将其分开对待。
So Make few changes in solveChallenge()
function: 因此,对
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);
}
}
As per your need, I have made some changes in the program. 根据您的需要,我对该程序进行了一些更改。
Code: 码:
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();
}
}
}
Prints result: 打印结果:
[[amleth, hamlet], [dirty room, dormitory], [listen, silnet, tinsel], [pear]]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.