我有一个单词列表如下。
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]
有人可以告诉我这里有什么问题吗?
答案 0 :(得分:0)
这将解决您的问题
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&lt; String,ArrayList&lt;串GT;&GT;像这样的数据结构。希望这会有所帮助:)
答案 1 :(得分:0)
我会这样做:
Map<Character, Integer>
,其中包含单词的字符(不包括空格)和出现次数 - 您已经做过类似的事情Map<Map<Character, Integer>, List<String>>
中,其中键是出现的地图,值是所有匹配的单词列表(anagrams)。 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);
答案 2 :(得分:0)
您在代码中犯了一些错误。首先,您需要更改在集合中存储字谜的逻辑。你在这里存储pair
而不是你应该存储所有字谜。因此,您可以StringBuilder
将anagrams
存储在single
传递中,并且在迭代后,您可以将其添加到集合中。
另一个错误是在这个循环中:
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
向前移动,因此如果下一个元素为{ {1}}然后当你递增anagram
时,你会错过它。最后一个错误是您需要检查j
列表的所有元素。因为最后一个元素可能不是带有任何其他元素的anagram,所以需要单独进行。
因此,在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();
}
}
}