我认为关键是通过取每一边的长度与总长度的比率来确定你想要在 CutOff 点的每一边有多少分割。
在您的示例中,边是 9 和 12,每边给出(大约)1.7 和 2.2 的除法。实际数字必须是整数,因此请尝试 (1,3) 和 (2,2)。左侧 1 格表示大小必须为 9,两侧的 2 格允许您使用 6 格。
写了一些 C# 来说明这一点。不是特别优雅,但它似乎有效。
public class RangeDivider
{
public int Min;
public int CutOff;
public int Max;
public int NumDivisions;
public RangeDivider(int min, int cutOff, int max, int numDivisions)
{
Min = min;
CutOff = cutOff;
Max = max;
NumDivisions = numDivisions;
System.Diagnostics.Debug.Assert(Min < CutOff && CutOff < Max && numDivisions >= 2);
}
public int LeftSize { get { return CutOff - Min; } }
public int RightSize { get { return Max - CutOff; } }
public int WholeSize { get { return Max - Min; } }
private static int divCeil(int dividend, int divisor) { return 1 + (dividend - 1)/divisor; }
private int ReturnSize(int leftDivisions)
{
int rightDivisions = NumDivisions - leftDivisions;
if (leftDivisions > 0 && rightDivisions > 0)
{
return Math.Max(divCeil(LeftSize, leftDivisions), divCeil(RightSize, rightDivisions));
}
else
{ //Must have at least 1 division each side of cutoff
return int.MaxValue;
}
}
public int GetSize()
{
var leftDivisions = NumDivisions * LeftSize / WholeSize;
var size = Math.Min(ReturnSize(leftDivisions), ReturnSize(leftDivisions + 1));
Console.WriteLine("Min {0}, CutOff {1}, Max {2}, NumDivisions {3} gives a Division Size of {4}", Min, CutOff, Max, NumDivisions, size);
return size;
}
public static int Get(int min, int cutOff, int max, int numDivisions)
{
return new RangeDivider(min, cutOff, max, numDivisions).GetSize();
}
public static void Test()
{
Get(-7,0,57,4);
Get(-9, 0, 12, 4);
Get(-1, 0, 7, 6);
}
}
- Min -7,CutOff 0,Max 57,NumDivisions 4 给出的分区大小为 19
- Min -9,CutOff 0,Max 12,NumDivisions 4 给出的分区大小为 6
- Min -1,CutOff 0,Max 7,NumDivisions 6 给出的分区大小为 2