如何按照字符串数组中出现的单词对映射进行排序

时间:2019-05-19 07:39:09

标签: java

我正在编写一个Java程序逻辑来打印带有出现次数和行号的笔杆。下面是代码

package test;
import java.util.HashMap;
 import java.util.Scanner;
 import java.util.Set;

 public class Countcharacters {

/**
 * @param args
 */
static HashMap<String, Integer> countcharact=new HashMap<>();
static HashMap<String, String> linenumbertrack=new HashMap<>();
static int count=1;
static void countwords(String line){
    //System.out.println(line);
    String[] input=line.split("\\s");
    int j=0;
    String linenumber="";
    for(int i=0;i<input.length;i++){
        //System.out.println(input[i]);
        if(countcharact.containsKey(input[i])==true){
            j=countcharact.get(input[i]);
            linenumber=linenumbertrack.get(input[i]);
            countcharact.put(input[i],j+1);
            linenumbertrack.put(input[i],linenumber+", "+count);

        }
        else{
            countcharact.put(input[i], 1);
            linenumbertrack.put(input[i],count+"" );
        }

    }
    count++;


}
public static void main(String[] args) {
    // TODO Auto-generated method stub
   String inp="the quick brown fox jumped over the lazy dog's bowl.\nthe dog was angry with the fox for considering him lazy.";
   String[] line=inp.split("\n");
   for(int i=0;i<line.length;i++){
       Countcharacters.countwords(line[i]);
   }
    Set<String> s=countcharact.keySet();
    for(String c:s){
        System.out.println(c+" "+countcharact.get(c)+" "+"["+linenumbertrack.get(c)+"]");
    }

}

}

我得到的输出是

over 1 [1]
quick 1 [1]
lazy. 1 [2]
lazy 1 [1]
considering 1 [2]
jumped 1 [1]
was 1 [2]
for 1 [2]
angry 1 [2]
brown 1 [1]
him 1 [2]
fox 2 [1, 2]
the 4 [1, 1, 2, 2]
with 1 [2]
bowl. 1 [1]
dog's 1 [1]
dog 1 [2]

但是我有两个问题。

第一:如果看到“该”出现为4,但行数为[1,1,2,2],则应该仅为[1,2]。

2nd:我想对它们进行排序。首先应按基数降序排序,然后再按字母顺序排序。

赞:

the 4 [1,2]
fox 2 [1,2]
lazy 2 [1,2]
angry 1 [1]
bowl 1 [1]
.
.

1 个答案:

答案 0 :(得分:3)

总是最好抽象出类中的数据逻辑单元。在您的问题中,您有两个明确的单位:

  1. 出现单词(单词字符串和行号)。

        class WordOccurrence {
            private final String word;
            private final int lineNumber;
    
            ...
        }
    
  2. 有关单词的统计信息(出现次数,出现的行号集合等)。

        class WordStats {
            private List<Word> occurrences;
    
            public String getWord() { ... }
            public int getCount() { ... }
            public Set<Integer> getLines() { ... }
        }
    

通过这些类,您可以首先将text分解为Map的{​​{1}}的{​​{1}};因此对于每个不同的单词,List将包含以下条目:

  1. 等于实际WordOccurrence字的键
  2. 值等于Map中包含String对象的List的值,WordOccurrence

您可以通过以下方式实现此目标:

text

然后您可以使用以下类似的方法轻松地将此地图转换为 public static Map<String, List<WordOccurrence>> createOccurrencesMap(String text) { text = text.replaceAll("\\.", " "); // text = text.replaceAll("'s", ""); // dog's != dog ??? Map<String, List<WordOccurrence>> result = new HashMap<>(); String[] lines = text.split("\n"); for (int i = 0; i < lines.length; i++) for (String word : lines[i].split("\\s+")) result.computeIfAbsent(word, w -> new ArrayList<>()) .add(new WordOccurrence(word, i + 1)); return result; } 的{​​{1}}(使用灵活的可参数化标准进行排序):

List

就是这样!一旦将问题分解成较小的,直观上按逻辑分组的组件(类,方法,数据结构等),剩下的就是将它们全部连接起来。

以下代码是该解决方案的完整工作演示,供您使用:

WordStats

希望这会有所帮助。