长期存储和恢复变化
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
中存储的值太多,或者minValue
和maxValue
之间的范围太大时,它们就不适合了。
这就像在知道该单元格的内存偏移量时查找 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
从这里,您应该能够推断出范围为 [minValue
、maxValue
] 的一般情况,其中每个组件都有 maxValue - minValue + 1
个可能的值,但是如果您需要更多详细信息,请告诉我。
我的 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
中存储的值太多,或者minValue
和maxValue
之间的范围太大时,它们就不适合了。
这就像在知道该单元格的内存偏移量时查找 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
从这里,您应该能够推断出范围为 [minValue
、maxValue
] 的一般情况,其中每个组件都有 maxValue - minValue + 1
个可能的值,但是如果您需要更多详细信息,请告诉我。