【问题标题】:Anagrams finding in java在java中查找字谜
【发布时间】:2019-07-07 21:24:27
【问题描述】:

我遇到了一个问题。我有一个由String[]={"eat", "tea", "tan", "ate", "nat", "bat"} 组成的字符串数组,现在,我应该将那些具有相同字母的单词分开并组成一个组。 eat,tea,ate 每个单词都有相同的字母,所以这是一个组。第 2 组应为 tan,nat,第 3 组应为 bat。所以我必须列出一个列表来存储这些组。

我的做法:

为了解决这个问题,我首先找出每个字母的 ascii 值,然后将这些 ascii 值添加到一个单词中。像eat 一样找出e,a,t 的ascii 值并添加它们。我采用这种方法是因为如果字母在单词中重复,那么它们必须具有相同的 ascii 总和。之后,我将它们分组为相同的 Ascii 总和,并找出哪些单词具有这些总和,然后它们属于同一组。

我的进步 我找出 ascii 总和并将它们放入哈希图中。但后来我无法对相同的值进行分组。由于我未能对 ascii 值进行分组,因此我找不到单词。我不知道如何进行。

我也关注这个帖子

post1 post2

但是那里的方法和我的方法不一样。而且问题和我的不一样。我在这里讨论的是一种不同的方法,它取决于 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

【问题讨论】:

  • “健康的讨论总是受欢迎的。”
  • 您是否尝试过使用其他变量。因此,您将初始单词放入该变量。现在遍历所有单词。对于每个单词,对于您检查的每个字母是否在您保存的单词中 - 如果您错过了继续。 (如果字母可能在一个单词中出现多次,则每个字母可能需要一些计数器)
  • 相关(老实说,我很想将其视为骗子:stackoverflow.com/q/15045640/1079354
  • @JoeC 有时我观察到,当有人在这里提问时。他或她得到了这样的答案我们不解决家庭作业。所以,我认为,写下一个完整的代码可能会超出规则。所以我鼓励讨论。

标签: java arraylist hashmap


【解决方案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;
    }
}

该程序适用于诸如此类的小规模事物,但请考虑以下输入数据:

{"a", "@!"}

这些字符串的总和都是97。

由于您使用 ASCII 值来查找字谜,您可能会遇到这样的情况。在您开始使用小写字母和大写字母之前,这并不是一个特别紧迫的问题。只需 String.ToUpperCase() 即可轻松解决此问题,并将符号映射到巨大的数字,您就可以开始了。

【讨论】:

  • 所有单词都小写。
  • @Encipher 绝对。我为要存储的组创建了一个 ArrayList 的 ArrayList。然后我创建了一个 HashMap,它以一个 Integer(字符串的总和)作为键,一个 String 的 ArrayList 作为组。然后,我遍历我的字符串数组中的所有单词,并将每个字符加到一个 sum 变量中。然后我检查了我的 HashMap 是否已经包含了总和。如果确实将其添加到指定的组。如果没有,则使用密钥和创建一个新组。然后我将所有 HashMap 值添加到一个可选的 ArrayList 中。如果我需要详细说明特定领域,请告诉我。
【解决方案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]}

我已经修复了提供的 cmets 和编辑。

【讨论】:

  • 有些方法是错误的,你不会从某些输入中得到正确的结果。如果你得到 200 的总和,你现在是如何使我加 100 + 100 或加 90 + 110 的?
【解决方案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);
}

【讨论】:

    猜你喜欢
    • 2022-01-21
    • 2013-09-20
    • 2016-03-18
    • 2011-12-07
    • 2014-04-13
    • 2010-10-28
    • 2012-10-11
    • 2011-09-19
    • 2013-01-11
    相关资源
    最近更新 更多