我在字节数组中逐字节地读取.pst(File Structure)文件,现在我想将数据分成两部分,如偶数和奇数,并将其存储在另外两个文件中偶数和一个奇数。下面是我坚持的代码
byte[] array = File.ReadAllBytes("PST_Sample.pst");
for (int index = 0; index < even.Length; index++)
{
//Console.WriteLine(index + " : " + array[index]);
if ((array[index] % 2) == 0)
{
even[index] = array[index];
}
else
{
odd[index] = array[index];
}
}
在FOR循环中我尝试过array.length,even.length没什么用。
答案 0 :(得分:1)
array
比even
和odd
数组长两倍
请尝试使用以下代码:
for (int index = 0; index < even.Length; index++)
{
even[index] = array[index * 2];
odd[index] = array[index * 2 + 1];
}
答案 1 :(得分:1)
将源数组中的索引增加2,并将目标数组中的索引增加1。这允许您将一个字节分配给odd
和even
数组,而无需进行额外的偶数/奇数测试。
for (int src = 0, dst = 0; src < array.Length; src += 2, dst++)
{
even[dst] = array[src];
odd[dst] = array[src + 1];
}
如果数组长度为奇数,则odd[]
必须短于even[]
。此外,必须特别注意避免遇到超出范围异常的索引。
解决方案还使用奇数数组长度并避免在循环中进行额外测试:
byte[] array = { 0, 1, 2, 3, 4 };
bool isOdd = array.Length % 2 == 1;
byte[] even = new byte[(array.Length + 1) / 2];
byte[] odd = new byte[array.Length / 2];
int length = isOdd ? array.Length - 1 : array.Length;
for (int src = 0, dst = 0; src < length; src += 2, dst++) {
even[dst] = array[src];
odd[dst] = array[src + 1];
}
if (isOdd) { // If array length is odd, the last index is even (= length - 1).
// Assign the last remaining entry.
even[even.Length - 1] = array[array.Length - 1];
}
答案 2 :(得分:0)
你的测试是错误的。您正在测试数据中的字节,而不是索引。它应该是:
for (int index = 0; index < array.Length; index++)
{
//Console.WriteLine(index + " : " + array[index]);
if ((index % 2) == 0)
{
even[index/2] = array[index];
}
else
{
odd[(index - 1)/2] = array[index];
}
}
答案 3 :(得分:0)
如果您只是在寻找解决方案而不一定是如何修复代码,那么最简单的方法就是使用LINQ。
byte[] array = new byte[]
{
55, 56, 57, 58, 89, 90, 91, 92
};
var even = array.Where((b, i) => i % 2 == 0);
var odd = array.Except(even);
如果您需要even
且odd
为byte[]
,则只需在每行添加.ToArray()
。
如果你想将这些值交织在一起,那么这里有一个扩展方法(如果你只是想要一个普通的方法,请删除static
和this
)。我借用并修改了this问题的接受答案,即使一个集合比另一个集合大,也可以交错。
public static IEnumerable<T> Interleave<T>(this IEnumerable<T> first, IEnumerable<T> second)
{
using (var firstEnumerator = first.GetEnumerator())
using (var secondEnumerator = second.GetEnumerator())
{
var firstMoved = firstEnumerator.MoveNext();
var secondMoved = secondEnumerator.MoveNext();
while (firstMoved || secondMoved)
{
if (firstMoved)
yield return firstEnumerator.Current;
if (secondMoved)
yield return secondEnumerator.Current;
firstMoved = firstEnumerator.MoveNext();
secondMoved = secondEnumerator.MoveNext();
}
}
}
答案 4 :(得分:0)
你的主阵列是结果两个的两倍。您的代码中可能存在2或3个设计错误,具体取决于您的数据
第一个缺陷是您同时为所有阵列使用相同的索引。因此,对于偶数阵列或奇数阵列,您在for
的每次传递中都会跳过一个存储器单元,因为您的限制是偶数阵列的大小,所以只能在主阵列的中途进行。
第二个缺陷是,根据您的数据,您的偶数和奇数数组可能需要不同的大小,因为如果您有46个奇数和20个偶数,您仍然可以得到数组的大小每一个33
第3个缺陷,可能是最关键的:结合第一个和第二个缺陷,你肯定会得到一个超出范围的索引异常。如果您有25个偶数和67个奇数,因为您使用相同的索引,您的代码将一直有效,直到您到达index >= 25
,您将获得一个超出索引的索引,因为偶数数组的最后一个索引为32
我还建议您使用列表而不是数组,因为它们旨在存储任意数量的数据。
在这里,您可以编写代码以避免这些缺陷:
byte[] array = File.ReadAllBytes("PST_Sample.pst");
List<byte> even = new List<byte>();
List<byte> odd = new List<byte>();
for (int index = 0; index < array.Length; index++)
{
if ((array[index] % 2) == 0)
{
even.Add(array[index]);
}
else
{
odd.Add(array[index]);
}
}
File.WriteAllBytes("even_file.pst", even.ToArray());
File.WriteAllBytes("odd_file.pst", odd.ToArray());