问题描述
我卡在一个问题上。
我有一个 String 数组,它由String[]={"eat", "tea", "tan", "ate", "nat", "bat"}
现在,我应该分离那些具有相同字母的单词它并组成一个组。
eat,tea,ate
他们每个单词都有相同的字母,所以这是一个组。
Group 2 应该是tan,nat
,Group3 应该是bat
。
所以我必须制作一个列表来存储这些组。
我的做法:
为了解决这个问题,我首先找出每个字母的 ascii 值,然后将这些 ascii 值添加到单词中。
像eat
一样找出e,a,t
的ascii值并添加它们。
我采用这种方法是因为如果单词中的字母重复,那么它们必须具有相同的 ascii sum。
之后,我将它们分组为相同的 Ascii 总和,并找出哪些单词具有这些总和,然后它们属于同一组。
我的进步是找出 ascii 总和并将它们放入哈希图中。 但是后来我无法对相同的值进行分组。 由于我未能对 ascii 值进行分组,因此我无法找出单词。我不知道如何进行。
我也关注这个帖子
但是那里的做法和我的做法不一样。 而且问题和我的不一样。 我在这里讨论一种不同的方法,它取决于 ASCII 值。
我的代码:
public List<List<String>> groupAnagrams(String[] strs) {
ArrayList<Character>indivistr=new ArrayList<>();
ArrayList<Integer>dup=new ArrayList<>();
HashMap<Integer,Integer>mappingvalues=new HashMap<>();
for(int i=0;i<strs.length;i++){
int len=strs[i].length();
int sum=0;
for(int j=0;j<len;j++){
indivistr.add(strs[i].charAt(j));
int ascii=(int)strs[i].charAt(j);
sum=sum+ascii;
}
mappingvalues.put(i,sum);
}
}
另一种方法是在 Arraylist 中传输映射键并在 ArrayList 中映射值。 类似的东西,
ArrayList<Integer>key_con=new ArrayList< (mappingvalues.keySet()); ArrayList<Integer>val_con=new ArrayList<>(mappingvalues.values());
然后使用两个循环并将相同的值放入另一个列表中。
for(int k=0;k<val_con.size();k++){
for(int k1=k+1;k1<val_con.size();k1++){
if(val_con.get(k).equals(val_con.get(k1))){
dup.add(val_con.get(k1));
}
}
现在,如果我打印 dup 输出将是[314, 314, 314, 323]
这是部分正确的。
应该是314,314,314,323,323,311
1楼
这应该让你开始。
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
public class Main {
public static void main(String args[]) throws Exception {
String[] words ={"eat", "tea", "tan", "ate", "nat", "bat"};
for(List<String> list : groupAnagrams(words))
System.out.println(list);
}
public static List<ArrayList<String>> groupAnagrams(String[] words) {
List<ArrayList<String>> wordGroups = new ArrayList<ArrayList<String>>();
HashMap<Integer, ArrayList<String>> map = new HashMap<Integer, ArrayList<String>>();
for(String word : words) {
int sum = 0;
for(char c : word.toCharArray())
sum += c;
if(map.containsKey(sum))
map.get(sum).add(word);
else {
ArrayList<String> list = new ArrayList<String>();
list.add(word);
map.put(sum, list);
}
}
for(ArrayList<String> list : map.values())
wordGroups.add(list);
return wordGroups;
}
}
该程序将适用于诸如此类的小规模事物,但请考虑以下输入数据:
{“一种”, ”@!”}
这些字符串的总和都是 97。
由于您使用 ASCII 值来查找字谜,因此您可能会遇到这样的情况。
在您开始弄乱小写字母和大写字母之前,这并不是一个特别紧迫的问题。
简单的修复只是一个String.ToUpperCase()
并将符号映射到巨大的数字,你就可以开始了。
2楼
基于 asci 方法,我制作了一个工作代码
public static void main(String[] args) {
String[] values ={"eat", "tea", "tan", "ate", "nat", "bat"};
Map<Integer, List<String>> resultMap = new HashMap<Integer, List<String>>();
for (String value : values) {
char[] caharacters = value.toLowerCase().toCharArray();
int asciSum = 0;
for (char character : caharacters) {
asciSum = asciSum + (int)character;
}
System.out.println(asciSum);
if(resultMap.containsKey(asciSum)) {
resultMap.get(asciSum).add(value);
}else {
List<String> list = new ArrayList<String>();
list.add(value);
resultMap.put(asciSum, list);
}
}
System.out.println(resultMap);
}
这将给出结果
{323=[tan, nat], 311=[bat], 314=[eat, tea, ate]}
但是如果我们遇到具有相同 asci 值和的差异字符,例如 10+11 = 20+1 下面的代码将在基于排序字符串的地方工作,我们制作结果映射
public static void main(String[] args) {
String[] values ={"eat", "tea", "tan", "ate", "nat", "bat"};
Map<String, List<String>> resultMap = new HashMap<String, List<String>>();
for (String value : values) {
char[] caharacters = value.toLowerCase().toCharArray();
Arrays.sort(caharacters);
String sortedValue = new String(caharacters);
System.out.println(sortedValue);
if(resultMap.containsKey(sortedValue)) {
resultMap.get(sortedValue).add(value);
}else {
List<String> list = new ArrayList<String>();
list.add(value);
resultMap.put(sortedValue, list);
}
}
System.out.println(resultMap);
}
这将返回
{aet=[eat, tea, ate], abt=[bat], ant=[tan, nat]}
我已经修复了提供的评论和编辑。
3楼
这是我的想法,首先我会创建一个类来存储原始字符串及其排序版本:
class Anagram {
String s;
String sorted;
}
然后我将输入映射到我的Anagram
列表:
List<Anagram> collect = Arrays.stream(strs)
.map(a -> new Anagram(a, Arrays.stream(a.split(""))
.sorted()
.reduce(String::concat).get()))
.collect(Collectors.toList());
然后我只是按排序字符串对获得的列表进行分组:
Map<String, List<Anagram>> groupBy = collect
.stream()
.collect(Collectors.groupingBy(Anagram::getSorted));
现在您有了带有分组字谜的列表,只需从中提取原始字符串:
List<List<String>> result = new ArrayList<>();
for(List<Anagram> list : collect1.values()) {
List<String> myList = list.stream().map(Anagram::getS).collect(Collectors.toList());
result.add(myList);
}