[英]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
存储在这里,而不是应该将所有字谜存储在这里。 因此,您可以拥有一个StringBuilder
来single
存储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.