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

6 に答える 6

1

「'A1B1' のようなものがどのように機能するかはわかりません...」というこの発言は、問題の複雑さをいくぶん増大させます。以下は、すべてのケースで機能するはずです。

方法:

文字列をトークンに分割します。トークンは、文字または連続した数字のいずれかです。各数字トークンを先頭のスペースで 5 文字まで埋めます。トークンを連結して、展開された文字列を作成します。

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

-アル。

于 2013-10-02T07:29:28.003 に答える
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 : "");
    }
}

現在の文字列をこのクラスに変換し、必要に応じて並べ替えて元に戻すことができます

于 2013-10-01T14:18:15.170 に答える
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]);
于 2013-10-01T13:50:43.643 に答える
0

これが私のコードです。合理化できると確信しています。それは、私が脳の子供を抱えていて、書く必要があった停電の瞬間の1つでした. 数字の文字列が 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;
于 2013-10-02T12:25:35.610 に答える
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),' ','')),
             .....
            )

私の見解では、これはより単純なロジックであり、コードが少なく、テスト/デバッグが容易であり、欠陥のリスクを軽減し、誰かが保守しやすくなっています。もちろん、走行距離はデータベースによって異なる場合があります。しかし、このアプローチは検討する価値があるようです。

于 2014-02-02T04:01:01.413 に答える