字母数字排序

时间:2016-06-06 11:21:50

标签: java sorting

我有一个像

这样的字符串列表
00785-LT-SUN(4)-SE-FD-1511  
00785-LT-SUN(4)-SE-FD-151  
00785-LT-SUN(4)-SE-FD-152  
00785-LT-SUN(4)-SE-FD-1513

对这些字符串应用常规排序时,它们按

排序
00785-LT-SUN(4)-SE-FD-151  
00785-LT-SUN(4)-SE-FD-1511  
00785-LT-SUN(4)-SE-FD-1513
00785-LT-SUN(4)-SE-FD-152

而不是

00785-LT-SUN(4)-SE-FD-151  
00785-LT-SUN(4)-SE-FD-152
00785-LT-SUN(4)-SE-FD-1511  
00785-LT-SUN(4)-SE-FD-1513

我通过以下步骤部分实施了解决方案:

  
      
  1. 分隔所有字符,数字和特殊字符。
  2.   
private static final Pattern VALID_PATTERN =   
               Pattern.compile ( "[0-9]+|[A-Z]+|[-()/.,:;]+|[\\s]+" );  
  
      
  1. 将原始字符串的每个单独标记添加到列表
  2.   
private List<String> parse(String toParse) {
        List<String> chunks = new LinkedList<> ();
        Matcher matcher = VALID_PATTERN.matcher(toParse);
        while (matcher.find()) {
            chunks.add( matcher.group() );
        }
        return chunks;
    }
  

3.表示字符串的每个列表都会添加到列表中

for (int i = 0 ;i < chunks.size () ;i++)
    listListString .add ( parse ( chunks.get ( i ) ) );
  

4.在特定列上应用的实际排序

public List<List<String>> Compare (List<List<String>> var_listArrayList ,
                                        int Col )
    {
        final int col_num = Col;
//this method can be overloaded to sort integers
            Collections.sort ( var_listArrayList,

                           new Comparator< List< String > > ( )
                           {

                               @Override
                               public
                               int compare ( List< String > a,
                                             List< String > b )
                               {

                                   return a.get ( col_num )
                                           .compareTo ( b.get ( col_num ) );
                               }
                           } );

        return var_listArrayList ;
    }
  

实际问题:
  尽管完成了上述所有步骤,结果仍然没有达到预期的效果。

可能的解决方案是按照以下步骤进行:

static final Comparator< StringEncapsulator > ORDER_BY_COLS = new Comparator< StringEncapsulator >() {
    public int compare(StringEncapsulator a1, StringEncapsulator a2) {
        int i = ORDER_BY_COL1.compare(a1,a2);
        if(i == 0){
            i = ORDER_BY_COL2.compare(a1,a2);
            if(i == 0){
                i = ORDER_BY_COL3.compare(a1,a2);
                :
                :
                :
            }
        }
        return i;
    }
};  //the class here represents the encapsulated structure of the string

但解决方案有一些困难。

  • 字符串可能并不总是具有相同的格式,这意味着我必须为遇到的每种类型的字符串创建不同类型的类。
  • 这个问题的递归方法更容易实现,而不是硬编码整个Comparator函数。

3 个答案:

答案 0 :(得分:0)

为什么不用一个看起来像这样的比较器来对列表进行排序:

new Comparator<String> ( )
{
  @Override
  public
  int compare (String a, String b)
  {
    String[] myAArray = a.split("-");
    Integer myAInt = Integer.parseInt(myAArray [myAArray.length - 1]);

    String[] myBArray = b.split("-");
    Integer myBInt = Integer.parseInt(myBArray [myBArray.length - 1]);

    return myAInt > myBInt ;
  }
}

答案 1 :(得分:0)

您当前的设计是“程序性的” - 您编写的代码用于处理“固定”(不灵活)的数据结构。考虑在这里使用“真正的OO”设计。

重点是:是的,您的数据是以具有某些属性的“原始字符串”形式出现的。但是:这并不意味着您总是必须将数据视为字符串。

相反,您可以建模表示此类数据的类。这也可以分离不同的问题:一个类负责解析传入的字符串并将它们转换为特定的对象;然后你可以在每个这样的类中实现一个合理的equals()方法。

这样你就可以使你的字符串的各种属性成为代表它的类的“完全限定”属性;而不是做所有这些隐含的“字符串中有'列';需要以这种方式/那种方式处理”。

答案 2 :(得分:0)

一个想法,而不是一个完整的解决方案:如果您愿意调查(或者已经在使用)外部库,Apache Commons Collections提供ComparatorChain,它可以帮助您将链接在一起每个块的比较器。这当然是假设您在整个过程开始之前知道输入字符串的确切布局。