我是一名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
(包含main()函数,我创建object
)和在课堂A中,我有constructor
。
现在我想要实现的目标是,我正在尝试制作&#34;符号&#34;作为通用数据类型,我的意思是在32/64位架构上符号可能是int
/ uint
/ long
等。另请注意我正在阅读{{1 } {strong>在Binary File
,二进制符号的格式为(11010101等)。
我真的很感激,如果有人可以通过编辑来纠正我的算法,从而实现我的目标,即将符号设置为sole argument
()类型,因为我昨天被卡住了。非常感谢你。
编辑:完整代码:
"generic"
错误是:(对于调试我尝试在构造函数中打印check1和check2,但它只打印&#34; check1&#34; not&#34; check2&#34;)。请直到输出结束:
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, "");
}
}
}
答案 0 :(得分:2)
您必须将转换函数和数字类型的大小传递给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))
如果进一步约束type参数以实现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;
}
}
}
}
}