- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我是一名 C# 初学者,正在尝试读取二进制文件中的符号。我在 c# 中使用 ReadByte() 以唯一参数读取了这个二进制文件。通过这样做
using(var stream = new BinaryReader(System.IO.File.OpenRead(args[0])))
然后我做了
while (stream.BaseStream.Position < stream.BaseStream.Length)
{
int symbol = stream.ReadByte();
//And then i do my stuff
}
什么到这里一切都很好。
但我的下一步是制作通用类型的符号 "<T>"
.所以我的算法是:
namespace Final
{
public Class A <T> where T: IComparable <T>
{
public Class Node
{
public T symbol; //This symbol has to be generic type because symbol may be int/long/uint etc. on 32/64 bit archtecture.
public Node next;
public int freq;
}
public Node Front;
public A(string[] args) //it's a constructor
{
Front = null;
using(var stream = new BinaryReader(System.IO.File.OpenRead(args[0])))
{
while (stream.BaseStream.Position < stream.BaseStream.Length)
{
Func < byte, T > converter = b = > new T(b);
byte byteValue = stream.ReadByte();
T processingValue = converter(byteValue); //here is the problem
Node pt, temp;
pt = Front;
while (pt != null)
{
if (pt.symbol == processingValue) //here is the problem
{
pt.freq++;
break;
}
temp = pt;
pt = pt.next;
}
}
}
stream.Close();
}
}
public class MyClass
{
public static void Main(string[] args)
{
A <T> ObjSym = new A <T> (args); //object creation
}
}
}
请注意有three class
Class A
, Class Node
(包含符号)和 Class MyClass
(包含我创建 object
的 main() 函数)并且在类 A 中我有我的 constructor
.
现在我从昨天开始努力实现的是,我试图将“符号”作为通用数据类型,我的意思是符号可能是 int
/uint
/long
等在 32/64 位架构上。另请注意,我正在阅读 Binary File
中的符号。 <强>在 sole argument
和二进制符号的形式(11010101 等)。
如果有人可以通过编辑算法来更正我的算法以实现我将符号设为 "generic"
的目标,我将不胜感激。 () 类型,从昨天开始我就被卡住了。非常感谢。
编辑:完整代码:
using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
namespace shekhar_final_version_Csharp
{
// public class Huffman<K> where K : IComparable<K>
public class Huffman < T > where T: struct, IComparable < T > , IEquatable < T >
{
public int data_size, length, i, is_there;
public class Node
{
public Node next, left, right;
public T symbol;
public int freq;
public int is_processed;
}
public Node front, rear;
///////////////////////////////////////////////
// public Huffman(string[] args)
public Huffman(string[] args, Func < byte[], int, T > converter)
{
front = null;
rear = null;
int size = Marshal.SizeOf(typeof (T));
// Console.WriteLine("Size: {0} ", size);
using(var stream = new BinaryReader(System.IO.File.OpenRead(args[0])))
{
while (stream.BaseStream.Position < stream.BaseStream.Length)
{
byte[] bytes = stream.ReadBytes(size);
T processingValue = converter(bytes, 0);
{
Node pt, temp;
bool is_there = false;
pt = front;
while (pt != null)
{
if (pt.symbol.Equals(processingValue))
{
pt.freq++;
is_there = true;
break;
}
temp = pt;
pt = pt.next;
}
if (is_there == false)
{
temp = new Node();
temp.symbol = processingValue;
temp.freq = 1;
temp.left = null;
temp.right = null;
temp.next = null;
temp.is_processed = 0;
if (front == null)
{
front = temp;
}
else
{
// Console.WriteLine("Symbol : {0} frequency is : {1}", pt.symbol, pt.freq);
temp.next = front;
front = temp;
}
}
}
Console.WriteLine("check1");
}
Console.WriteLine("check2");
stream.Close();
//////////////////////////////
}
}
public void Print_tree( Node treee)
{
Node pt = treee;
while (pt != null)
{
Console.WriteLine("Symbol : {0} frequency is : {1}", pt.symbol, pt.freq);
pt = pt.next;
}
}
/////////////////////////////
public Node find_two_smallest(ref Node pmin1, ref Node pmin2)
{
Node temp = front;
Node temp6 = front;
Node address = null;
Node min1;
min1 = new Node();
min1.freq = int.MaxValue;
Node min2;
min2 = new Node();
min2.freq = int.MaxValue;
while (temp != null)
{
if (temp.is_processed == 0)
{
if (temp.freq < min2.freq)
{
min1 = min2;
min2 = temp;
}
else if (temp.freq < min1.freq && temp.freq != min2.freq)
{
min1 = temp;
}
temp = temp.next;
}
else if (temp.is_processed == 1)
{
temp = temp.next;
}
}
pmin1 = min1;
pmin2 = min2;
// Below is the code to find the address of first minimum arriving on traversal of List which will be "front" for next execution.
while (temp6 != null)
{
if (temp6.freq == min1.freq || temp6.freq == min2.freq)
{
address = temp6;
break;
}
temp6 = temp6.next;
}
return address;
}
///////////////////////////////////////////////////////////////////
public int count_remaining()
{
int remaining = 0;
Node pt = front;
while (pt != null)
{
if (pt.is_processed == 0)
{
remaining += 1;
}
pt = pt.next;
}
return remaining;
}
////////////////////////////////////////////////////////////////////////////
public void huffman_node_processing()
{
Node temp, temp2;
temp2 = front;
while (temp2 != null)
{
if (temp2.next == null)
{
rear = temp2;
break;
}
temp2 = temp2.next;
}
int remaining;
int counter = 0;
remaining = count_remaining();
// You can un-comment these console.writeline(..); which are commented below if you want to see how the addition of nodes taking place(which nodes are added),
//I have commented it inorder to give direct and clear output.
while (front != rear)
{
if (counter == 0)
{
temp = new Node();
Console.WriteLine("first element1 {0} ", front.freq);
Console.WriteLine("second element1 {0} ", front.next.freq);
temp.freq = front.freq + front.next.freq;
front.is_processed = 1;
front.next.is_processed = 1;
temp.is_processed = 0;
temp.left = front;
temp.right = front.next;
temp.next = null;
rear.next = temp;
front = front.next.next;
Console.WriteLine("tempcheck1 {0} ", temp.freq);
rear = rear.next;
remaining = count_remaining();
if (remaining == 1)
{
break;
}
}
if (rear.freq == front.freq)
{
//Console.WriteLine("first element2 {0} ", front.freq);
//Console.WriteLine("second element2{0} ", front.next.freq);
temp = new Node();
temp.freq = front.freq + rear.freq;
rear.is_processed = 1;
front.is_processed = 1;
temp.is_processed = 0;
temp.left = front;
temp.right = rear;
temp.next = null;
rear.next = temp;
front = front.next;
//Console.WriteLine("temp check2 {0} ", front.freq);
rear = rear.next;
remaining = count_remaining();
if (remaining == 1)
{
break;
}
}
if (rear.freq > front.freq)
{
Node pmin1 = null;
Node pmin2 = null;
Node address = find_two_smallest(ref pmin1, ref pmin2);
temp = new Node();
Console.WriteLine("pmin1check3 {0} ", pmin1.freq);
Console.WriteLine("pmin2check3 {0} ", pmin2.freq);
temp.freq = pmin1.freq + pmin2.freq;
pmin1.is_processed = 1;
pmin2.is_processed = 1;
temp.is_processed = 0;
temp.left = pmin2;
temp.right = pmin1;
temp.next = null;
rear.next = temp;
front = address;
Console.WriteLine("tempcheck3 {0} ", temp.freq);
rear = rear.next;
remaining = count_remaining();
if (remaining == 1)
{
break;
}
}
if (rear.freq < front.freq)
{
Node pmin1 = null;
Node pmin2 = null;
Node address = find_two_smallest(ref pmin1, ref pmin2);
temp = new Node();
//Console.WriteLine("pmin1check4 {0} ", pmin1.freq);
//Console.WriteLine("pmin2check4 {0} ", pmin2.freq);
temp.freq = pmin1.freq + pmin2.freq;
pmin1.is_processed = 1;
pmin2.is_processed = 1;
temp.is_processed = 0;
temp.left = pmin2;
temp.right = pmin1;
temp.next = null;
rear.next = temp;
front = address;
//Console.WriteLine("tempcheck4 {0} ", temp.freq);
rear = rear.next;
remaining = count_remaining();
if (remaining == 1)
{
break;
}
}
counter++;
}
}
////////////////////////////////////////////
public void GenerateCode( Node parentNode, string code)
{
if (parentNode != null)
{
GenerateCode(parentNode.left, code + "0");
if (parentNode.left == null && parentNode.right == null)
Console.WriteLine("Symbol : " + parentNode.symbol + " frequency is : " + code);
GenerateCode(parentNode.right, code + "1");
}
}
}
public class MyClass
{
public static void Main(string[] args)
{
// Huffman<K> ObjSym = new Huffman<K>(args); //object creation
Huffman < long > ObjSym = new Huffman < long > (args, BitConverter.ToInt64);
Console.WriteLine("\nReading the Binary file......");
ObjSym.Print_tree(ObjSym.front);
ObjSym.huffman_node_processing();
Console.WriteLine("\nThe encoding of symbols are :");
ObjSym.GenerateCode(ObjSym.rear, "");
}
}
}
错误是:(为了调试,我尝试在构造函数中打印 check1 和 check2,但它只打印“check1”而不是“check2”)。请直到输出结束:
hp@ubuntu:~/Desktop/Internship_Xav/templatescplus$ mono test.exe toto.bin
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
check1
Unhandled Exception: System.ArgumentException: Destination array is not long enough to copy all the items in the collection. Check array index and length.
at System.BitConverter.PutBytes (System.Byte* dst, System.Byte[] src, Int32 start_index, Int32 count) [0x00000] in <filename unknown>:0
at System.BitConverter.ToInt64 (System.Byte[] value, Int32 startIndex) [0x00000] in <filename unknown>:0
at shekhar_final_version_Csharp.Huffman`1[System.Int64]..ctor (System.String[] args, System.Func`3 converter) [0x00000] in <filename unknown>:0
at shekhar_final_version_Csharp.MyClass.Main (System.String[] args) [0x00000] in <filename unknown>:0
[ERROR] FATAL UNHANDLED EXCEPTION: System.ArgumentException: Destination array is not long enough to copy all the items in the collection. Check array index and length.
at System.BitConverter.PutBytes (System.Byte* dst, System.Byte[] src, Int32 start_index, Int32 count) [0x00000] in <filename unknown>:0
at System.BitConverter.ToInt64 (System.Byte[] value, Int32 startIndex) [0x00000] in <filename unknown>:0
at shekhar_final_version_Csharp.Huffman`1[System.Int64]..ctor (System.String[] args, System.Func`3 converter) [0x00000] in <filename unknown>:0
at shekhar_final_version_Csharp.MyClass.Main (System.String[] args) [0x00000] in <filename unknown>:0
hp@ubuntu:~/Desktop/Internship_Xav/templatescplus$
最佳答案
您必须将转换函数和数字类型的大小传递到 A
的构造函数中:
public A(string[] args, int size, Func<byte[], int, T> converter) { ... }
A<long> ObjSym = new A<long>(args, sizeof(long), BitConverter.ToInt64)
您可以使用 Marshal.SizeOf
而不是直接传递大小:
int size = Marshal.SizeOf(typeof(T));
然后就可以从阅读器中读取需要的字节数并进行转换了:
byte[] bytes = stream.ReadBytes(size);
T processingValue = converter(bytes, 0);
您可以使用 Equals
检查符号:
if (pt.symbol.Equals(processingValue))
如果进一步约束类型参数以实现 IEquatable<T>
,则可以在相等性检查期间避免装箱:
public class A<T> where T : struct, IComparable <T>, IEquatable<T>
{
public class Node
{
public T symbol;
public Node next;
public int freq;
}
public Node Front;
public A(string[] args, Func<byte[], int, T> converter)
{
int size = Marshal.SizeOf(typeof(T));
Front = null;
using(var stream = new BinaryReader(System.IO.File.OpenRead(args[0])))
{
while (stream.BaseStream.Position < stream.BaseStream.Length)
{
byte[] bytes = stream.ReadBytes(size);
T processingValue = converter(bytes, 0);
Node pt, temp;
pt = Front;
while (pt != null)
{
if (pt.symbol.Equals(processingValue))
{
pt.freq++;
break;
}
temp = pt;
pt = pt.next;
}
}
}
}
}
关于c# - 使用 ReadByte() 读取泛型类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22544131/
我是一名优秀的程序员,十分优秀!