长期存储和恢复变化

Storing and Restoring Variations in a Long

我的 n 值在相同的修复最小值和最大值范围内。

// value range
int minValue = 0;
int maxValue = 100;
int valueCount = 3; // number of values

// Example 1
int a = 0;
int b = 0;
int c = 0;

// Example 2
int a = 100;
int b = 100;
int c = 100;

// Example 3
int a = 12;
int b = 80;
int c = 27;

示例 1 和 2 显示了这 3 个值的最小和最大变化,其中示例 3 显示了一些随机值。

具有给定最小值和最大值的这 3 个值的所有变化的可能数量是 100 * 100 * 100 = 1.000.000。

所以如果我定义 0 代表示例 1 的变化,1.000.000 代表示例 2 的变化。我如何计算代表示例 3 的值?

或者更好的是,我如何遍历所有可能的变化以及如何恢复它们。

for(int i = 0; i <= 1000000; i++)
{
    int[] values = GetValues(i, minValue, maxValue, valueCount);
}

所以我正在寻找的是像上面的 GetValues() 方法一样工作的东西。

您必须乘以 101,而不是 100,因为您的范围(从 0 到 100)包含 101 个数字。范围 1 到 100 或 0 到 99 包含 100 个数字。

所以你的最大值不是1000000而是1030301

将您的值存储在 long 中(在您的示例中也可以是 int):

long stored = c * 101 * 101 + b * 101 + a;

恢复它:

int restoredA = stored % 101;
int restoredB = stored / 101 % 101;
int restoredC = stored / 101 / 101;

如果你的函数是:

int[] GetValues(long stored, int minValue, int maxValue, int valueCount);
{
    // TODO: Do some parameter checking.
    int[] results = new int[valueCount];
    int rangeSize = maxValue - minValue + 1;
    for(int i = 0; i < valueCount; i++)
    {
        results[i] = rangeSize % diff + minValue;
        stored = stored / diff; 
    }
    return results;
}

当然,当long中存储的值太多,或者minValuemaxValue之间的范围太大时,它们就不适合了。

这就像在知道该单元格的内存偏移量时查找 n 维数组的索引。

public static IEnumerable<int> GetValues(long i, int minValue, int maxValue, int valueCount)
{
    var range = maxValue - minValue + 1;

    for (int j = 0; j < valueCount; j++)
    {
        yield return (int)(i % range + minValue);
        i = i / range;
    }
}

正如我在评论中提到的,您提供的示例是错误的。

1030301个变化,因为每个项目可以有101个不同的值(从0到100)和总数变化是 101*101*101 = 11030301.

您可以将熟悉的以 10 为基数的数字系统视为您要执行的操作的一个简单示例。假设您要将 [0, 9] 范围内某处的三个值存储为单个数字,例如 2、5 和 7。您只需将其写为数字 257,它表示以下总和十的连续幂的倍数,因为十是每个数字可以具有的唯一值的数量。

257 = 2 * 102 + 5 * 101 + 7 * 100

以同样的方式,您可以将除 10 以外的任何基数的值打包在一起。在您给出的示例中,每个数字的允许范围是 [0, 100],其中包含 101 个不同的整数,因此您d 将您的打包值构造为 101 的连续幂的倍数之和,如下所示:

x = a * 1012 + b * 1011 + c * 1010

从这里,您应该能够推断出范围为 [minValuemaxValue] 的一般情况,其中每个组件都有 maxValue - minValue + 1 个可能的值,但是如果您需要更多详细信息,请告诉我。