[英]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.