2013-10-01 87 views
5

我有大写字母和数字组成的字符串,我必须“逻辑”排序,并存储在数据库中的字段。我已经将更新/更改/查询部分纳入了数据库。我很难在逻辑上对这个字符串进行排序。逻辑排序的大写字母和数字的混合串

这里去,我希望我能很好地解释这一点。

鉴于这一组字符串 AB1 AB2 AB3 A11 AB10

我需要这些阿尔法有点像这样

A11 AB1 AB2 AB3 AB10

为了为了实现这一点,我相信我需要爆炸字符串。因为目前正试图字母排序产生A11 AB1 AB10 AB2 AB3

编辑:我需要能够存储的分解字符串和非爆炸串能够与其它程序进行排序。

这里是我认为他们需要被分解并存储在顺序排序阿尔法

A11 - A 11 
AB1 - AB 1 
AB2 - AB 2 
AB3 - AB 3 
AB10 - AB 10 

有一些常量。该字符串将不会大于5个位置。它只会包含大写字母和数字。

这是据我已经与我的代码得到。作家阻止,所以我希望得到一些帮助。我想我需要找到它是否以字母开头,然后找到所有的连续的字母,搬完下车离开,然后去上号的工作,找到所有的连续编号,然后将这些右对齐。不知道如何像“A1B1”会工作要么...

for(int ii = 0;ii < sectionString.length() && ii< SECTIONSPACES;ii++){ 
       System.out.print(" Was previous a number? " + isPreviousANumber +   "\n"); 
try{ 
    String tmpString = sectionString.substring(ii,ii + 1); 
    int positionInCharArray = Integer.parseInt(tmpString); 
    System.out.printf(" Position " + ii + " is number " + positionInCharArray + "\n"); 
    isPreviousANumber = true;   
}catch(Exception e){ 
    System.out.printf(" Position " + ii + " number is not a number " +  sectionString.substring(ii,ii) + "\n"); 
    isPreviousANumber = false; 
    }     
} 
+0

使用类似于基数排序的数字,其数字优先于字母。 – arynaq

+0

我会复制下面我做的评论如果我可以使用java对它们进行排序,这些工作对排序它们非常有用。问题是不同的程序需要对它们进行排序并与它们兼容,我需要'爆炸'字符串并使用爆炸字符串进行排序并显示常规值。我知道不是'正常'。在数据库中会有两个字段,其中一个将被称为section和一个名为sort_section的字段。合理? – nkuebelbeck

回答

1

这句话“不知道如何像‘A1B1’会工作,要么......”有点增加了问题的复杂性。以下内容适用于所有情况。

方法:

将字符串划分为标记。令牌是字母或连续的数字运行。将每个数字标记填充到具有前导空格的五个字符。连接令牌以制作爆炸字符串。

从5个字符的原始字符中,最长的爆炸字符串将是17个字符。

生成的爆炸字符串可能会被任何程序或SQL“ORDERED BY”子句排序。

实例:

1A1A1 " 1A 1A 1" 
11A11 " 11A 11" 
1111A " 1111A" 
11111 "11111" 
A1  "A 1" 
A1B1 "A 1B 1" 
A1C  "A 1C" 
A2  "A 2" 
A2B1 "A 2B 1" 
A10  "A 10" 
A10B1 "A 10B 1" 
A11  "A 11" 
AA1  "AA 1" 
AB1  "AB 1" 
AB2  "AB 2" 
AB10 "AB 10" 
ABC  "ABC" 

伪代码:

// original = "section" string 
exploded = "" 
prevdigits = false 
for ii from 1 to length(original) { 
    ch = original[ii] 
    if (ch is a digit) then { 
     if not prevdigits then { 
     token = "" 
     prevdigits = true 
     } 
     token = token+ch 
    } else { // letter 
     if prevdigits then { 
     exploded = exploded + spaces(5-length(token)) + token 
     prevdigits = false 
     } 
     exploded = exploded + ch 
    } 
} 

-Al。

+0

我不好意思添加最后一句话。我只是想到了同样的事情,并回来更新我的代码。 – nkuebelbeck

0

我会用空格完成这些字符串5个符号后,将使Radix Sort。我们可以将所有符号作为字符进行比较。

String[] array = {"A11", "AB1", "AB2", "AB3", "AB10"}; 

    int i, j, length; 
    for (i = 0; i < array.length; i++) { 
     length = array[i].length(); 
     for (j = length; j < 5; j++) { 
      array[i] += " "; 
     } 
    } 

    Arrays.sort(array); 

    for (int k = 0; k<array.length; k++) 
     System.out.println(array[k]); 
1

这是我如何用我的基数排序的想法对其进行排序:

public static String[] radixSort(String[] strings){ 
    // Pad the strings 
    for(int i=0; i<strings.length; i++){ 
     strings[i] = String.format("%-5s", strings[i]); 
    } 

    // Radix sort them 
    for (int digit = 0; digit < 5; digit++) { 
     final int i = digit; 
     Arrays.sort(strings, new Comparator<String>() { 


      @Override 
      public int compare(String o1, String o2) { 
       return o1.charAt(i) - o2.charAt(i); 
      } 
     }); 
    } 

    // Then trim the whitespaces we used to pad 

    for (int i = 0; i < strings.length; i++) { 
     strings[i] = strings[i].trim(); 
    } 

    return strings; 
} 

随着输入

String[] strings = new String[] { "AB1", "AB2", "AB3", "A11", "AB10" }; 
    System.out.println(Arrays.toString(radixSort(strings))); 

和输出

[A11, AB1, AB2, AB3, AB10] 

我不知道这是最有效的方法,但它完成了工作。

+0

这些工作伟大的排序他们,如果我可以使用java排序他们。问题是不同的程序需要对它们进行排序并与它们兼容,我需要'爆炸'它们并使用分解的字符串进行排序并显示常规值。我知道不是'正常'。在数据库中会有两个字段,其中一个将被称为section和一个名为sort_section的字段。合理? – nkuebelbeck

+0

没有意识到第二个要求,将它们包装在另一个对象中,比如marco建议这样做,那么添加getter或使用正则表达式来分割字符串,我将它们分类为字母和数字值。 – arynaq

+0

这是我的不好,我添加到原来的文章 – nkuebelbeck

1

,你可以使用另一个类作为您的字符串中的特殊表现。是这样的:

public class AlphaNumericString implements Comparable<AlphaNumericString> { 
    public final String alphaPart; 
    public final Long numericPart; 

    public AlphaNumericString(String string) { 
     int index = 0; 
     while (index < string.length() && !Character.isDigit(string.charAt(index))) { 
      index++; 
     } 

     alphaPart = string.substring(0, index); 

     if (index < string.length()) { 
      numericPart = new Long(string.substring(index)); 
     } else { 
      numericPart = null; 
     } 
    } 

    @Override 
    public int compareTo(AlphaNumericString other) { 
     int stringCompareResult = alphaPart != null ? alphaPart.compareTo(other.alphaPart) : -1; 

     if (stringCompareResult == 0) { 
      return numericPart != null ? numericPart.compareTo(other.numericPart) : -1; 
     } else { 
      return stringCompareResult; 
     } 
    } 

    @Override 
    public String toString() { 
     return (alphaPart != null ? alphaPart : "") + (numericPart != null ? numericPart : ""); 
    } 
} 

可以把您的当前字符串到这个类,排序并将其转换回为需要

0

这是我的代码。我相信它可以精简,这是我有一个大脑孩子,需要写作的那些停电时刻之一。这是行不通的,如果这串数字是超过500个字符长...

更新:不丑

private String buildPieceSortNumber(String pieceNumber){ 
    final int INTSPACES = 5; 
    final String SPACE = " "; 
    String explodedSection = "";   
    char[] charArray = pieceNumber.toCharArray(); 
    String ints = ""; 
    for(int i = 0;i < charArray.length;i++){ 
     if(Character.isDigit(charArray[i])){ 
      //add to the int string 
      ints += charArray[i]; 
      //check if the next character in the array is a number 
      int nextChar = i + 1; 
      //make sure we don't go past the end of the string     
      if(nextChar < charArray.length){ 
       if(!Character.isDigit(charArray[nextChar])){ 
        //end of numbers, take ints string, and add padding up to five positions 
        while(ints.length() < INTSPACES){ 
         ints = SPACE + ints; 
        } 
        //add the int string to the end of the exploded string 
        explodedSection += ints;       
        //clear the int string 
        ints = ""; 
        } 
      }else{ 
       //end of numbers, take ints string, and add padding up to five positions 
       while(ints.length() < INTSPACES){ 
        ints = SPACE + ints; 
       } 
       //add the int string to the end of the exploded string 
       explodedSection += ints; 
       //clear the int string 
       ints = ""; 
      }     
     }else{ 
      explodedSection += charArray[i];                
     } 
    } 
    return explodedSection; 
0

你真的需要将数据之前把它在数据库排序?考虑让数据库为您完成工作。

假设您将值直接写入数据库。你的数据库可能允许你做类似我的事情。在DB2中,为了只获取字母,我会将所有数字转换为空格,然后删除所有空格。相同的概念可以适用于只获取数字。

SELECT replace(translate(inp, @spaces, @digits),' ','') as alpha, 
     int(replace(translate(inp, @spaces, @letters),' ','')) as nbr, 
     .... 

虽然这可能是一个规范化的数据库的方法,你可能会质疑在执行此计算,每次数据从表中检索。因此,相反,在将数据写入到表

INSERT INTO yourtable (item, alpha, nbr, .....) 
    VALUES (inp, 
      replace(translate(inp, @spaces, @digits),' ',''), 
      int(replace(translate(inp, @spaces, @letters),' ','')), 
      ..... 
      ) 

我的看法的时候做到这一点,这是简单的逻辑,更少的代码,更容易测试/调试,帮助减少缺陷的风险,并且是有人更容易保持。当然,您的里程可能会因您的数据库而异。但是这种方法似乎值得考虑。

相关问题