逻辑排序大写字母和数字的混合字符串

时间:2013-10-01 13:38:48

标签: java algorithm sorting

我有一串大写字母和数字,我必须'逻辑'排序并存储在数据库的字段中。我已经将数据库中的更新/更改/查询部分弄清楚了。我很难对这个字符串进行逻辑排序。

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

给定这组字符串 AB1 AB2 AB3 A11 AB10

我需要这些像这样的alpha排序

A11 AB1 AB2 AB3 AB10

为了实现这一点,我相信我需要爆炸字符串。因为目前尝试进行α分类产生A11 AB1 AB10 AB2 AB3

编辑:我需要能够存储一个爆炸字符串和一个非爆炸字符串,以便能够与其他程序一起排序。

以下是我认为需要分解和存储以便对alpha进行排序的方法

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;
    }                   
}

6 个答案:

答案 0 :(得分: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]

我不确定这是最有效的方法,但它可以完成工作。

答案 1 :(得分: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 : "");
    }
}

您可以将当前字符串转换为此类,并根据需要对其进行排序和转换

答案 2 :(得分: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。

答案 3 :(得分: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]);

答案 4 :(得分:0)

这是我的代码。我确信它可以简化,这是我有一个大脑孩子需要写的那些停电时刻之一。如果数字字符串长度超过5个字符,这将无效...

更新:不那么难看

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;

答案 5 :(得分: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),' ','')),
             .....
            )

在我看来,这是一个更简单的逻辑,更少的代码,更容易测试/调试,有助于降低缺陷风险,并使人们更容易维护。当然,您的里程可能会因您的数据库而异。但这种方法似乎值得考虑。