code: private int[] getCharWeightedRank_Alphabet(int[] buckets, int q) {
  
          int alphabetSize = alphabet.size;
          int[] charWeight = new int[alphabetSize];
          int bucketsInLevel2Bucket = kbs_power_Ulong(alphabetSize, q - 2);
          int tmpBucketFactor = bucketsInLevel2Bucket * (alphabetSize + 1);
          int i;
          charWeight[0] = alphabet.charFreq[0];
          charWeight[0] -= buckets[bucketsInLevel2Bucket - 1];
          for (i = 1; i < alphabetSize - 1; i++) {
              charWeight[i] = alphabet.charFreq[i];
              charWeight[i] -= buckets[i * tmpBucketFactor + bucketsInLevel2Bucket - 1]
                  - buckets[i * tmpBucketFactor - 1];
          }
          charWeight[alphabetSize - 1] = alphabet.charFreq[i];
          charWeight[alphabetSize - 1] -= buckets[(alphabetSize - 1) * tmpBucketFactor
              + bucketsInLevel2Bucket - 1]
              - buckets[(alphabetSize - 1) * tmpBucketFactor - 1];
  
          int[] targetCharArray = new int[alphabetSize];
          for (i = 0; i < alphabetSize; i++) {
              targetCharArray[i] = i;
          }
          /* insertion sort by charWeight */
          for (i = 1; i < alphabet.size; i++) {
              int tmpWeight = charWeight[i];
              int j = i;
              while (j > 0 && tmpWeight < charWeight[targetCharArray[j - 1]]) {
                  targetCharArray[j] = targetCharArray[j - 1];
                  j--;
              }
              targetCharArray[j] = i;
          }
          int[] charRank = new int[alphabetSize + 1];
          for (i = 0; i < alphabetSize; i++) {
              charRank[targetCharArray[i]] = i;
          }
          return charRank;
      }
docs: Sorts the alphabet regarding some weight according to cc bucket size and alphabet
  frequency Only works for mapped string with alphabet [0,alphaSize]
  
  @param buckets - the bucket table
  @param q       - the initial q-gram size
  @return the rank of each character