【问题标题】:Descending sort of substrings by occurence - Java按出现降序排序子字符串 - Java
【发布时间】:2011-10-16 04:33:22
【问题描述】:

免得说我有字符串:

 String test= "AA BB CC BB BB CC BB";

我想做的是像这样创建字符串数组:

 String[]{"BB", "CC", "AA"}

由于 B 发生了 4 次,C 发生了 2 次,而 A 只发生了 1 次。

这个问题的解决方案是什么样的?

【问题讨论】:

标签: java string sorting substring


【解决方案1】:
String test = "AA BB CC BB BB CC BB";
System.out.println(Arrays.deepToString(sort(test)));

输出:[BB, CC, AA]

代码:

public static String[] sort(String test) {
    String[] strings = test.split(" ");
    HashMap<String,Integer> map = new HashMap<String,Integer>();
    for (String s : strings) {
        Integer i = map.get(s);
        if (i != null) {
            map.put(s, i+1);
        } else {
            map.put(s, 1);
        }
    }

    TreeMap<Integer,String> sort = new TreeMap<Integer,String>(Collections.reverseOrder());
    for (Entry<String,Integer> e : map.entrySet()) {
        sort.put(e.getValue(), e.getKey());
    }

    return sort.values().toArray(new String[0]);
}

【讨论】:

    【解决方案2】:

    你可以做的是这样的事情(粗略的代码):

    String[] myOccurences = test.split(" ");
    

    然后:

    HashMap<String,Integer> occurencesMap = new HashMap<String,Integer>()
    
    for( String s : myOccurences ){
        if( occurencesMap.get( s ) == null ){
            occurencesMap.put(s, 1);
        } else {
            occurencesMap.put(s, occurencesMap.get(s)++ );
        }
    }
    

    编辑:实际排序(再次粗略的代码和未检查):

    List<String> mapKeys = new ArrayList<String>(occurencesMap.keySet()); // Keys
    List<Integer> mapValues = new ArrayList<Integer>(occurencesMap.values()); // Values
    
    TreeSet<Integer> sortedSet = new TreeSet( mapValues ); // Sorted according to natural order                
    Integer[] sortedValuesArray = sortedSet.toArray();
    
    HashMap<String,Integer> lhMap = new LinkedHashMap<String,Integer>(); // LinkedHashMaps conserve order
    
    for (int i=0; i<size; i++){
        lhMap.put(mapKeys.get(mapValues.indexOf(sortedArray[i])), sortedValuesArray[i]);
    }
    
    mapKeys = new ArrayList<String>(occurencesMap.keySet()); // Keys again, this time sorted
    Collections.sort(mapKeys, Collections.reverseOrder()); // Reverse since original ascending
    
    String[] occurencesSortedByDescendingArray = mapKeys.toArray();
    

    欢迎评论。

    【讨论】:

    • 这只是生成一个包含每个标记计数的映射,然后它不会根据这些计数生成已排序的 String 数组。
    • +1,不过我没票了。我正在写这篇文章(用伪代码,因为几个月来我没有在 Java 中做过任何事情)并在提交答案之前进行了检查,看到了这个。很好的解决方案。
    • 缺少排序。只是在重读问题时注意到。感谢您指出这一点。
    • 添加了排序代码。我第一次在没有打开编译器的情况下实际输入了一些东西:p
    【解决方案3】:

    如果你想使用番石榴:

    Lists.transform(
      Ordering
        .natural()
        .onResultOf(new Function<Multiset.Entry<String>, Integer>() {
            public Integer apply(Multiset.Entry<String> entry) {
              return entry.getCount();
            }
          })
        .reverse()
        .sortedCopy(
            ImmutableMultiset.copyOf( Splitter.onPattern("\\s+").split(test) ).entrySet()
          ),
      new Function<Multiset.Entry<String>, String>() {
        public String apply(Multiset.Entry<String> entry) {
          return entry.getElement();
        }
      }
    );
    

    【讨论】:

    • 我必须试试这个 Guava 库 :)
    【解决方案4】:

    我不确定是否存在用于此确切目的的方法。

    但是,您可以使用String.split() 方法将单个字符串拆分为字符串数组。从那里,您可以找到唯一的字符串(通过手动检查或将它们全部添加到一个集合中,这将检查重复项)。每次添加元素并且它不是集合的一部分时,跟踪(并增加每个唯一字符串的唯一计数器)。然后创建一个根据这个计数排序的数组。

    映射是保存字符串/计数的理想选择,因为它会将一组唯一字符串作为键,并将每个字符串的计数作为值。

    【讨论】:

    • 已经发布了一个带有实际代码的答案,它确实做到了这一点,然后是获取该地图并将其转换为排序字符串数组的实际非平凡步骤
    • 而且它是在我写作的时候发布的!我通常对编写纯代码问题的答案持谨慎态度,因为我是一名学生,而且我知道有多少同学使用这个网站。
    • ty1824 的答案在我开始写东西的时候还没有发布。另外,我错过了关于排序的部分,这实际上是最重要的部分并且已经更新。 P.S:我也是一个学生,虽然可能年纪更大(在夜校完成学位)。感谢您尝试回答这样的问题。
    猜你喜欢
    • 1970-01-01
    • 2014-12-12
    • 2017-01-09
    • 1970-01-01
    • 1970-01-01
    • 2022-07-29
    • 2017-02-06
    • 2021-03-01
    • 1970-01-01
    相关资源
    最近更新 更多