【问题标题】:String lines sorting by Shell Sort通过 Shell Sort 排序的字符串行
【发布时间】:2014-03-06 01:52:24
【问题描述】:

我有一个包含 50 个不同长度和内容的字符串行的文本文件。我需要读取文件并按升序排序。排序条件:句子中以字母“a”开头的单词个数。

public static void main(String[] args) throws FileNotFoundException {
    String token1 = "";
    Scanner inFile1 = new Scanner(new File("E:\\text.txt"));

    List<String> temps = new LinkedList<String>();
    inFile1.useDelimiter(". ");

    while (inFile1.hasNext()) {
       token1 = inFile1.nextLine();
       temps.add(token1);
    }
    inFile1.close();

    String[] tempsArray = temps.toArray(new String[0]);
    for (int i = 0; i < tempsArray.length; i++) {
       System.out.println(tempsArray[i]);
    }

    int cnt = 0; //number of words in the string line
    for (int i=0; i<tempsArray.length; i++) {
        int k=0; //number of words that start from the letter "а"
        System.out.println("Line № = " + i);
        StringTokenizer st = new StringTokenizer(tempsArray[i]);           
        while (st.hasMoreTokens()) {
            cnt++;
            String s= st.nextToken();
            if (s.charAt(0)=='a') {                    
                k++;               
            }             
        }
        System.out.println("Number of words = " + cnt);
        cnt=0;
        System.out.println("Number of words 'а' = " + k);  
    }       
}

我按照 Kau 的建议使用 Map。但是Map 使用唯一键。但我的 K 可以有相同的值,Map 找不到合适的字符串元素。我还能用什么Сollection

【问题讨论】:

    标签: java sorting


    【解决方案1】:

    我假设您已经有了 shell short 算法来对整数数组进行排序。设方法为shellSort(int[] a)。 您可以做的是创建一个地图,其键为 k,值作为代表线的字符串。同时,我们将创建一个包含所有 k 的整数数组。然后在 k 值的数组上调用方法 shellSort。然后从排序后的数组中读回,使用数组元素作为键在地图中查找。获取相应的地图值(即行)并将它们一一放回tempsArray,这最终应该使所有行都以所需的方式排序。 下面是代码(未经测试),仅供参考。

    public static void main(String[] args) throws FileNotFoundException {
       String token1 = "";
       Scanner inFile1 = new Scanner(new File("E:\\text.txt"));
    
       List<String> temps = new LinkedList<String>();
       inFile1.useDelimiter(". ");
    
       while (inFile1.hasNext()) {
         token1 = inFile1.nextLine();
         temps.add(token1);
       }
       inFile1.close();
    
       String[] tempsArray = temps.toArray(new String[0]);
       for (int i = 0; i < tempsArray.length; i++) {
         System.out.println(tempsArray[i]);
       }
    
       int cnt = 0; //number of words in the string line
       Map<Integer, List<String>> myMap = new HashMap<Integer, List<String>>();
       int[] countArr = new int[tempsArray.length];
       for (int i=0; i<tempsArray.length; i++) {
           int k=0; //number of words that start from the letter "а"
           System.out.println("Line № = " + i);
           StringTokenizer st = new StringTokenizer(tempsArray[i]);           
           while (st.hasMoreTokens()) {
              cnt++;
              String s= st.nextToken();
              if (s.charAt(0)=='a') {                    
                 k++;               
              }             
           }
           countArr[i] = k;
           List<String> listOfLines = myMap.get(k);
           if(listOfLines  == null){
              listOfLines = new ArrayList<String>();
              listOfLines.add(tempsArray[i]);
              myMap.put(k, listOfLines);
           } else{
              listOfLines.add(tempsArray[i]);
           }
           System.out.println("Number of words = " + cnt);
           cnt=0;
           System.out.println("Number of words 'а' = " + k);  
        }
        //Call shellsort here on the array of k values
        shellSort(countArr);
        List<String> sortedListOfLines = new ArrayList<String>();
        for(int i=0; i<countArr.length; i++){
           List<String> lineList = myMap.get(countArr[i]);
           if(lineList != null){
              sortedListOfLines.addAll(lineList);
              lineList = null;
              myMap.put(countArr[i], lineList);
           }
        }       
     }
    

    【讨论】:

    • 是的,我就是这个意思。谢谢!
    • 从地图获取时使用myMap.get(countArr[i]) 而不是myMap.get(i)。我发布的原始答案中有一个错误。我已经更正了。
    • 哦,如果有两个相同的K,Map找不到合适的行,复制两个中的一行。
    • 您可以改用Map&lt;int, List&lt;String&gt;&gt;。对于每个 K 以 K 为键插入到映射中,并将行插入到相应的 List&lt;String&gt; 中。因此,如果有多个相同的 K 值,则相应的映射值将是一个字符串列表。您将不得不做一些额外的逻辑来检查密钥是否存在。如果地图中不存在键,则创建一个新列表并插入第一行。如果确实如此,则检索现有列表并将当前行插入其中。当然,从地图中检索并放入tempsArray 的逻辑也会相应地改变。
    • 感谢您的建议。但是怎么做呢?)这必须在k排序之后进行?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-15
    • 1970-01-01
    • 1970-01-01
    • 2018-11-20
    相关资源
    最近更新 更多