I am new to C# and I do not understand this example with Priority Queue
First comes struct
public struct pqItem
{
public int priority;
public string name;
}
then modified class
public class PQueue : Queue
{
public PQueue : base() {}
public override object Dequeue()
{
object [] items;
int x, min, minindex;
items = this.ToArray();
min = (pqItem)items[0].priority;
for(int x = 1; x <= items.GetUpperbound(0); x++)
if ((pqItem)items[x].Priority < min)
{
min = (pqItem)items[x].Priority;
minindex = x;
}
I do not understand how struct indexing works here.
min = (pqItem)items[0].priority;
Why not (pqItem).items[0]?The code is from McMillan's boook Data structures and algorithms.
Related
I am Trying to make a Game Engine in C# and OpenGL using OpenGL.NET. I have abstracted the Basic OpenGL Objects like VAO, VBO, etc. I Have a BufferLayout Class which specifies the Data present in the Vertex Buffer. The method in the VertexArray class that adds a buffer is this:
public void AddBuffer(uint index, ref VertexBuffer buffer)
{
Bind();
buffer.Bind();
uint i = index;
foreach (BufferElement element in buffer.Layout.Elements)
{
Gl.VertexAttribPointer(
i++,
element.GetComponentCount(),
Globals.ShaderDataTypeToOpenGLBaseType(element.Type),
element.Normalized,
buffer.Layout.Stride,
element.Offset
);
}
m_Buffers.Add(buffer);
}
This method has 2 Overloads: One which takes an IntPtr as the Offset and another which takes in an object.
This is the overload which takes in an object. But for some reason, the element.Offset is not working as expected. As I am only using a positions attribute for this test, it works when I replace element.Offset with null.
Here is BufferLayout.cs
public enum ShaderDataType
{
None,
Float, Float2, Float3, Float4,
Mat3, Mat4,
Int, Int2, Int3, Int4,
}
public class BufferElement
{
internal string Name;
internal ShaderDataType Type;
internal int Size;
internal int Offset;
internal bool Normalized;
public BufferElement(ShaderDataType type, string name, bool normalized = false)
{
Name = name;
Type = type;
Size = Globals.ShaderDataTypeSize(type);
Offset = 0;
Normalized = normalized;
}
internal void SetOffset(int offset) => Offset = offset;
public int GetComponentCount()
{
switch (Type)
{
case ShaderDataType.Float: return 1;
case ShaderDataType.Float2: return 2;
case ShaderDataType.Float3: return 3;
case ShaderDataType.Float4: return 4;
case ShaderDataType.Mat3: return 3 * 3;
case ShaderDataType.Mat4: return 4 * 4;
case ShaderDataType.Int: return 1;
case ShaderDataType.Int2: return 2;
case ShaderDataType.Int3: return 3;
case ShaderDataType.Int4: return 4;
}
return 0;
}
}
internal sealed class BufferLayout
{
public List<BufferElement> Elements { get; private set; }
public int Stride { get; private set; }
public BufferLayout(BufferElement[] e)
{
Elements = new List<BufferElement>();
Elements.AddRange(e);
CalculateOffsetsAndStride();
}
private void CalculateOffsetsAndStride()
{
int offset = 0;
Stride = 0;
for (int i = 0; i < Elements.Count; i++)
{
Elements[0].SetOffset(offset);
offset += Elements[0].Size;
Stride += Elements[0].Size;
}
}
}
The overload which takes an object is meant for compatibility profile OpenGL contex and the object has to be an object containing the vertex array data.
If you want to set an offset, then you have to create an IntPtr. e.g:
var offset = new IntPtr(element.Offset);
Gl.VertexAttribPointer(
i++,
element.GetComponentCount(),
Globals.ShaderDataTypeToOpenGLBaseType(element.Type),
element.Normalized,
buffer.Layout.Stride,
offset
);
Note, the offset and the stride parameter have to be specified in bytes.
I'm trying to do a Radix sort in a Linked list class. I found radix sort algorithm for array and am trying to change it to work with my linked list. However, I'm a bit struggling. The code I'm trying to change is taken from http://www.w3resource.com/csharp-exercises/searching-and-sorting-algorithm/searching-and-sorting-algorithm-exercise-10.php I tested the code with an array and it worked. Does anybody have any ideas how to make radix sort work in a linked list?
//abstract class
abstract class DataList
{
protected int length;
public int Length { get { return length; } }
public abstract double Head();
public abstract double Next();
public abstract void Swap(int a, int b);
public void Print(int n)
{
Console.Write("{0} ", Head());
for (int i = 1; i < n; i++)
Console.Write("{0} ", Next());
Console.WriteLine();
}
}
//linked list class
class LinkedList : DataList
{
class MyLinkedListNode
{
public MyLinkedListNode nextNode { get; set; }
public int data { get; set; }
public MyLinkedListNode(int data)
{
this.data = data;
}
public MyLinkedListNode()
{
this.data = 0;
}
}
MyLinkedListNode headNode;
MyLinkedListNode prevNode;
MyLinkedListNode currentNode;
public LinkedList(int n, int min, int max)
{
length = n;
Random rand = new Random();
headNode = new MyLinkedListNode(rand.Next(min, max));
currentNode = headNode;
for (int i = 1; i < length; i++)
{
prevNode = currentNode;
currentNode.nextNode = new MyLinkedListNode(rand.Next(min, max));
currentNode = currentNode.nextNode;
}
currentNode.nextNode = null;
}
public LinkedList()
{
headNode = new MyLinkedListNode();
currentNode = headNode;
}
public override double Head()
{
currentNode = headNode;
prevNode = null;
return currentNode.data;
}
public override double Next()
{
prevNode = currentNode;
currentNode = currentNode.nextNode;
return currentNode.data;
}
public override void Swap(int a, int b)
{
prevNode.data = a;
currentNode.data = b;
}
//my radix sort
public void radixSort()
{
int j = 0;
LinkedList tmp = new LinkedList();
for (int shift = 31; shift > -1; --shift)
{
//I try to go trough old list
MyLinkedListNode current = headNode;
while (current != null)
{
bool move = (current.data << shift) >= 0;
//I found this expression somewhere and I'm trying to use it to form a new Linked list (tmp)
if (shift == 0 ? !move : move)
;
else
{
if (tmp.headNode == null)
tmp.headNode = currentNode;
else
{
tmp.currentNode.nextNode = current;
//infinite loop happens on the commented line
//tmp.currentNode = tmp.currentNode.nextNode;
j++;
}
current = current.nextNode;
}
}
}
}
Following the C# radix sort example, you need an array of ten lists. Move nodes from the original list into the ten lists, appending a node with least signfificant digit == '0' into array_of_lists[0], '1' into array_of_list[1], and so on. After the original list is emptied, then concatenate the array of lists back into the original list and repeat for the next to least significant digit. Repeat the process until all the digits are handled.
You could use a larger base, such as base 16, where you would use an array of 16 lists. You can then select each "digit" using a shift and an and .
I'm looking for an implementation of a three dimensional circular buffer in C# .NET that allows me to extract slices of the buffer.
I tried the multidimensional array but it doesn't allow me to get a specific slice of the buffer.
I also tried to implement a version using jagged array, but i have find some problems in understanding how to initialzie the matrix, and also in slice extraction.
Thanks for the help.
[EDIT 1]
The buffer will be used to store data from reltime sensors, it will be fixed in width height and the depth (time which be the circular part) will be defined by the user.
The slices i need will be a fixed size matrix (width and heigh with the data of a given time).
[EDIT 2]
The only implementation that i could implement that works. With the jagged array i'm still stuck at the declaration (i find it chaotic)
public class CircularBufferMatrix<T>
{
private readonly T[,,] _buffer;
public CircularBufferMatrix(int width, int height, int depth)
{
Width = width;
Height = height;
Depth = depth;
_buffer = new T[width, height, depth];
}
public T this[int x, int y, int z]
{
set { _buffer[x, y, z%Depth] = value; }
get { return _buffer[x, y, z%Depth]; }
}
#region Getters
public int Width { get; }
public int Height { get; }
public int Depth { get; }
#endregion
}
I would split these in two classes. You want something like a CircularBuffer class, which handles the reading and writing. The other could be an implementation of the 2D array you want to store. The reason of splitting these, is because you want to Read/write frames separately.
For example:
Circular buffer implementation:
public class CircularBuffer<T>
{
private T[] _buffer;
private int IncRollover(int value)
{
value++;
if (value >= _buffer.Length)
value = 0;
return value;
}
public CircularBuffer(int count)
{
_buffer = new T[count];
}
public bool Write(T element)
{
// if the writeindex (after increasing) equals the readindex, the buffer is full
var newWriteIndex = IncRollover(WriteIndex);
if (newWriteIndex == ReadIndex)
return false;
_buffer[WriteIndex] = element;
WriteIndex = newWriteIndex;
return true;
}
public bool TryRead(out T element)
{
if (ReadIndex == WriteIndex)
{
element = default(T);
return false;
}
element = _buffer[ReadIndex];
ReadIndex = IncRollover(ReadIndex);
return true;
}
public IEnumerable<T> ReadAll()
{
T element;
while (TryRead(out element))
yield return element;
}
public int ReadIndex { get; private set; }
public int WriteIndex { get; private set; }
}
This will take care of reading and writing induvidual 'frames'/slices. You can expand this class if you like to read on Index.
note: The write will return false if the buffer is full
This could be an implementation of the 2d buffers stored within the Circular buffer:
public class MyWhateverBuffer<T>
{
private CircularBuffer<T[,]> _buffer;
public int Width { get; private set; }
public int Height { get; private set; }
public int Depth { get; private set; }
public MyWhateverBuffer(int width, int height, int depth)
{
Width = width;
Height = height;
Depth = depth;
_buffer = new CircularBuffer<T[,]>(depth);
}
public T[,] New()
{
return new T[Width, Height];
}
public bool Add(T[,] buffer)
{
return _buffer.Write(buffer);
}
public bool TryRead(out T[,] buffer)
{
return _buffer.TryRead(out buffer);
}
public IEnumerable<T[,]> ReadAll()
{
return _buffer.ReadAll();
}
}
This class can be used like:
MyWhateverBuffer<double> myBuffer = new MyWhateverBuffer<double>(100, 100, 100);
var oneSlice = myBuffer.New();
oneSlice[10, 10] = 3.5;
oneSlice[50, 10] = 23.5;
oneSlice[10, 20] = 43.5;
myBuffer.Add(oneSlice);
var anotherSlice = myBuffer.New();
anotherSlice[10, 10] = 13.5;
anotherSlice[50, 10] = 23.5;
anotherSlice[10, 20] = 43.5;
var result = myBuffer.Add(anotherSlice);
if(!result)
{
// the buffer was full..
}
// Read the results from the buffer.
foreach(var slice in myBuffer.ReadAll())
{
Trace.WriteLine(slice[10, 10]);
}
You should always check if the buffer could be added. You don't want to lose info.
Side note:
The most profit gains with a Circular buffer is declaring the elements ones. Like big arrays will be reused every time.
If I understand your requirements correctly, you want a circular buffer consisting of items that are two dimensional arrays of data and the data from one item is never repeated in other items. C# doesn't have a cicular buffer type but you can always create one yourself:-
public class CircularBuffer <T> // make it generic
{
public class Iterator
{
public void MoveForward ();
public void MoveBackward ();
public T Item { get { } };
CicrcularBuffer <T> m_container;
LinkedListNode <T> m_current_item;
}
public void Add (T item);
public Iterator GetIterator ();
LinkedList<T> m_data;
}
Then create a class to contain your data:-
public class SensorData
{
// contains the two dimension data
}
And use it like:-
var buffer = new CircularBuffer <SensorData> ();
var iterator = buffer.GetIterator ();
var item = iterator.Item;
iterator.MoveForward ();
Obviously, there's a lot to be filled in but it should get you started.
Having trouble with 'System.AccessViolationException' while developing a WindowsPhone8 app and don't know how to deal with it. Here is GitHub repo.
Exception appears when app tries to access (assign value 5) int field of an object ("value") of a class ("SudokuCell") in a class ("SudokuSection") in a class ("SudokuField").
testSudokuField.AddValueToSingleCell(5, new Tuple<int, int>(i, j)); // class MainPage
public class SudokuField
{
public SudokuSection[,] Sections;
public SudokuHorizontal[] Horizontals;
public SudokuVertical[] Verticals;
public bool solved;
public void AddValueToSingleCell(int value, Tuple<int, int> coords) // Item1 - horizontal, Item2 - vertical
{
var temp = InterpretCoordsForSection(coords);
this.Sections[temp.Item1 - 1, temp.Item2 - 1].ChangeCellValue(value, temp.Item3, temp.Item4);
this.Horizontals[coords.Item1 - 1].cells[coords.Item2 - 1].value = value;
this.Verticals[coords.Item2 - 1].cells[coords.Item1 - 1].value = value;
}
public class SudokuSection
{
public SudokuCell[,] cells;
// --------- Constructors
public SudokuSection()
{
this.cells = new SudokuCell[3, 3];
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
this.cells[i, j] = new SudokuCell();
}
public void ChangeCellValue(int value, int x, int y)
{
this.cells[x-1, y-1].ChangeValue(value);
}
}
public class SudokuCell
{
public int value; // Exect value of a cell
public SortedSet<int> acceptableValues; // A of acceptable values of a single cell
// --------- Constructors
public SudokuCell() // Empty constructor
{
this.acceptableValues = new SortedSet<int>();
}
public SudokuCell(int value) // Constructor for a cell with an exect value
{
this.value = value;
}
// --------- Methods
public void ChangeValue(int value)
{
this.value = value;
}
}
I tried to explain the issue maximally understandable. Will be grateful if you just point me to a solution.
Exception http://cs609829.vk.me/u33859447/docs/890ffbe19d74/question1.png?extra=UlBQBDfFTVi4oKt83aRDNfDrQcjh6AeNYv0aUQ1MmwDHWILYUR3EXmP82OylatDnm0BiT5wZBKYvqEcmQfLqLZX6bpJ7aCo
Absolutely stupid mistake: testSudokuField = new SudokuField();
I have a generic type called Vector<T>, I created it as so, cause the T might be float or Complex :
public class Vector<T>
{
#region Properties
public ulong Length
{
get
{
return _length;
}
}
public VectorType VectorType
{
get
{
return _vectorType;
}
}
#endregion
#region Indexers
public T this[ulong index]
{
get
{
return _data[index];
}
set
{
_data[index] = value;
}
}
#endregion
#region Constructors
public Vector(VectorType vectorType, T[] data)
{
if (!((data is float[]) || (data is Complex[])))
{
throw new InvalidDataException("Data must be array of float or array of Complex");
}
_data = new T[_length = (ulong)data.Length];
for (ulong i = 0; i < _length; i++)
{
_data[i] = data[i];
}
_vectorType = vectorType;
}
public Vector(VectorType vectorType, Vector<T> vector)
{
_data = new T[_length = vector.Length];
for (ulong i = 0; i < _length; i++)
{
_data[i] = vector[i];
}
_vectorType = vectorType;
}
#endregion
#region Methods
//Unity Matrix, this vector has 1/N everywhere
public static Vector<float> e(VectorType vectorType, ulong length)
{
var data = new float[length];
for (ulong i = 0; i < length; i++)
{
data[i] = (float)1 / length;
}
var vectorE = new Vector<float>(vectorType, data);
return vectorE;
}
public float Sum()
{
float sum = 0;
if (_data is float[])
{
sum = (_data as float[]).Sum();
}
else
{
if (_data is Complex[])
{
for (ulong i = 0; i < _length; i++)
{
sum += (float)
Math.Sqrt(Math.Pow((_data[i] as Complex?).Value.Real, 2) +
Math.Pow((_data[i] as Complex?).Value.Imaginary, 2));
}
}
}
return sum;
}
public bool CheckIfSochasitc()
{
return Math.Abs(Sum() - 1) < float.Epsilon;
}
public void Normalize()
{
var sum = Sum();
if (_data is float[])
{
for (ulong i = 0; i < _length; i++)
{
float x = ((float) _data[i])/sum;
_data[i] = (T)x;
}
}
}
#endregion
#region Operators
//I omitted the code inhere to avoid overload
#endregion
#region Fields
private ulong _length;
private readonly VectorType _vectorType;
private T[] _data;
#endregion
}
public enum VectorType
{
Row,Column
}
My problem is that I have a generic array (if I can call it so) :
private T[] _data;
And I have the Normalize() method:
public void Normalize()
{
var sum = Sum();
if (_data is float[])
{
for (ulong i = 0; i < _length; i++)
{
//Here is the problem
_data[i] = ((_data[i] as float?) / sum);
}
}
}
This doesn't work saying can't cast float to T tried to search but couldn't find helpful aide, any clarification I'd be thankful.
Update :
The Sum() method always returns a float
It's not clear why you're converting to float? at all (or why you're using ulong as the index variable type...) but you just need to cast the result back to T - otherwise you can't assign it back into an array of type T[]. Additionally, you need to cast to object (in order to convert back to T:
float x = ((float) (object) data[i]) / sum;
data[i] = (T) (object) x;
You can use float? for the first line, with as, to avoid boxing - but then you need to get the non-nullable value:
float x = (data[i] as float?).Value / sum;
Both are pretty ugly :(
As noted in comments though, this sort of thing is usually an indication of the design not really being properly generic at all. We don't know what type Sum() returns, but you should consider just how "general" your type is to start with.
May be you can try this
if (typeof(_data) == float[])
{
for (ulong i = 0; i < _length; i++)
{
_data[i] = ((_data[i] as float?) / sum);
}
}