code: private static int guessNumDistinctiveGrams(int textLength, int gramLength) {
          switch (gramLength) {
              case 1:
                  return Math.min(80, textLength);
              case 2:
                  if (textLength < 40) return textLength;
                  if (textLength < 100) return (int)(textLength*0.8);
                  if (textLength < 1000) return (int)(textLength * 0.6);
                  return (int)(textLength * 0.5);
              case 3:
                  if (textLength < 40) return textLength;
                  if (textLength < 100) return (int)(textLength*0.9);
                  if (textLength < 1000) return (int)(textLength * 0.8);
                  return (int)(textLength * 0.6);
              case 4:
              case 5:
              default:
                  if (textLength < 100) return textLength;
                  if (textLength < 1000) return (int)(textLength * 0.95);
                  return (int)(textLength * 0.9);
          }
      }
docs: This is trying to be smart.
  It also depends on script (alphabet less than ideographic).
  So I'm not sure how good it really is. Just trying to prevent array copies... and for Latin it seems to work fine.