I have a class, Matrix, and try to overload the + operator in this class.
The problem is in matrix1 and matrix2, I can't create a clone of this to object. I already even tried to make it using a few for loops but it throws an OutOfMemoryException.
public static Matrix<T> operator +(Matrix<T> matrix1, Matrix<T> matrix2)
{
Matrix<T> m1 = matrix1;
Matrix<T> m2 = matrix2;
Matrix<T> result = new Matrix<T>();
if (m1.Cols != m2.Cols || m1.Rows != m2.Rows)
{
if (m1.Rows > m2.Rows)
m2.Rows = m1.Rows;
else if (m1.Rows < m2.Rows)
m1.Rows = m2.Rows;
if (m1.Cols > m2.Cols)
m2.Cols = m1.Cols;
else if (m1.Cols < m2.Cols)
m1.Cols = m2.Cols;
}
for (int i = 0; i < m1.Rows; i++)
{
result.Add(new List<T>());
for (int j = 0; j < m1.Cols; j++)
{
result[i].Add(new T());
result[i][j] = Sum<T>(m1[i, j], m2[i, j]);
}
}
result.Cols = m1.Cols;
return result;
}
I done it in this way
public static List<List<T>> ListClone(List<List<T>> data)
{
var new_data= new List<List<T>>();
foreach (var list in data)
{
new_data.Add(ListClone(list));
}
return new_data;
}
public static List<T> ListClone(List<T> list)
{
var new_list = new List<T>();
foreach(var i in list)
{
new_list.Add((T)i);
}
return new_list;
}
public static Matrix<T> operator +(Matrix<T> matrix1, Matrix<T> matrix2)
{
var m1 = new Matrix<T>();
m1.Cols = matrix1.Cols;
m1.Rows = matrix1.Rows;
m1.Data = ListClone(matrix1.data);
var m2 = new Matrix<T>();
m2.Cols = matrix2.Cols;
m2.Rows = matrix2.Rows;
m2.Data = ListClone(matrix2.data);
Matrix<T> result = new Matrix<T>();
if (m1.Cols!=m2.Cols || m1.Rows!=m2.Rows)
{
if (m1.Rows > m2.Rows)
m2.Rows = m1.Rows;
else if (m1.Rows < m2.Rows)
m1.Rows = m2.Rows;
if (m1.Cols > m2.Cols)
m2.Cols = m1.Cols;
else if (m1.Cols < m2.Cols)
m1.Cols = m2.Cols;
}
for (int i = 0; i < m1.Rows; i++)
{
result.Add(new List<T>());
for (int j = 0; j < m1.Cols; j++)
{
result[i].Add(new T());
result[i][j] = Sum<T>(m1[i, j], m2[i, j]);
}
}
result.Cols = m1.Cols;
return result;
}
but maybe someone have better idiea how to do this easer?
First up, don't make a matrix using a List<List<T>>. Just use a List<T> and figure out the access operators yourself.
Second, why do you allow the user to set the Row or Column count? Make the matrix immutable and fix the sizes at construction.
public class Matrix<T> : ICloneable
where T : struct, IComparable, IFormattable, IConvertible, IComparable<T>, IEquatable<T>
{
private readonly int _rows;
private readonly int _columns;
private readonly IList<T> _data;
public Matrix(int rows, int columns)
{
_rows = rows;
_columns = columns;
_data = new List<T>(Rows * Columns);
}
private Matrix(int rows, int columns, IList<T> data)
{
_rows = rows;
_columns = columns;
_data = new List<T>(data);
}
public int Rows
{
get { return _rows; }
}
public int Columns
{
get { return _columns; }
}
public T Element(int row, int column)
{
return _data[row * column];
}
public object Clone()
{
return new Matrix<T>(Rows, Columns, _data);
}
}
The other operators I leave as an exercise
Related
Here is example of how to sort array of objects by it's fields. I need to create function which will do same thing but WITHOUT Linq, Generics or any other classes.
p.s You can add methods in Test class to compare fields.
using System;
using System.Linq;
class Test {
public int Count;
public int Sum;
}
class Program {
static void Main() {
Test a1 = new Test() {
Count = 1 ,
Sum = 20
};
Test a2 = new Test() {
Count = 2 ,
Sum = 10
};
Test a3 = new Test() {
Count = 3 ,
Sum = 30
};
var arr = new Test[] { a1, a2, a3};
var result = arr.OrderBy(n => n.Count).ToList();
foreach (var item in result) {
Console.WriteLine(item.Count);
}
}
static void MyOrder() {
//function which will sort passed array of objects by fields
}
}
One method is to use Array.Sort() static method. But if you want to use it, you class must implement IComparable interface, for example:
class Test : IComparable
{
public int Count;
public int Sum;
public int CompareTo(object obj)
{
if (!(obj is Test))
throw new ArgumentException("You can't compare two objects of different types!");
var test = (Test)obj;
if (test.Count < this.Count) return 1;
else if (test.Count > this.Count) return -1;
else return 0;
}
}
And then code would become:
var arr = new Test[] { a1, a3, a2 };
Array.Sort(arr);
EDIT:
If you want to change ordering field at runtime, you can use IComparer interface as folloing:
public class Test
{
public int Count;
public int Sum;
}
public class TestComparerBySum : IComparer<Test>
{
public int Compare(Test x, Test y)
{
if (x.Sum > y.Sum) return 1;
else if (x.Sum < y.Sum) return -1;
else return 0;
}
}
public class TestComparerByCount : IComparer<Test>
{
public int Compare(Test x, Test y)
{
if (x.Count > y.Count) return 1;
else if (x.Count < y.Count) return -1;
else return 0;
}
}
And use it in code like this:
var arr = new Test[] { a3, a2, a1 };
Array.Sort(arr, new TestComparerBySum());
Array.Sort(arr, new TestComparerByCount());
Consider the following Enum:
Enum AnimalType
{
Dog = 1,
Cat = 2,
Bird = 4,
Wolf = 8
}
Now suppose we want to find all possible flag combinations where Dog is active, for example.
I divised the following method to do this:
public static int[] testss(int value)
{
var animalTypes = (AnimalType)value;
List<int> possibleValues = new List<int>();
possibleValues.Add(value);
int totalEnumValues = Enum.GetNames(typeof(AnimalType)).Length;
List<int> helper = new List<int>();
int cnt = 0;
for (int i = 1; i < totalEnumValues; i++)
{
foreach (Enum val in Enum.GetValues(animalTypes.GetType()))
{
if (cnt >= i)
break;
if (i == 1)
{
if ((AnimalType)val != (AnimalType)value)
{
possibleValues.Add((int)(AnimalType)val + value);
}
}
else
{
if ((AnimalType)val != (AnimalType)value && (cnt < i))
{
helper.Add((int)(AnimalType)val);
cnt += 1;
}
}
}
if (cnt > 0)
{
possibleValues.Add(helper.Sum() + value);
helper = new List<int>();
cnt = 0;
}
}
return possibleValues.ToArray();
}
This method will build an array with all the possible numeric representations containing a given flag as input.
It works only partially, if you test it for Dog (1) for example, you'll see that 2 values are missing from the possibleValues array.
Can you help me realizing where I went wrong?
You could use the [Flags] enum attribute, then an extension method. Something like this:
[Flags]
enum AnimalType
{
Dog = 1,
Cat = 2,
Bird = 4,
Wolf = 8
}
static class Program
{
static void Main(string[] args)
{
var test = AnimalType.Dog.AllContaining();
}
public static int[] AllContaining(this AnimalType thisAnimal)
{
List<int> retVal = new List<int>();
var possibleEnums = Enum.GetValues(typeof(AnimalType)).Length;
var maxValue = (int)Math.Pow(2, possibleEnums);
for (int i = 0; i < maxValue; i++)
{
if (((AnimalType)i).HasFlag(thisAnimal))
{
retVal.Add(i);
}
}
return retVal.ToArray();
}
}
It spins through all possible integer values of the enum, and sees if the 'flag' for the supplied animal is present. If it is, it adds to the return array.
Assuming there's not a lot of enum values, you can try:
private static void Main(string[] args)
{
var type = AnimalType.Wolf;
foreach (var x in GetAllPossibleCombinationWith(type))
{
Console.WriteLine(x);
}
Console.ReadLine();
}
public static IEnumerable<AnimalType> GetAllPossibleCombinationWith(AnimalType type) // Bird
{
var maxValue = Enum.GetValues(typeof(AnimalType)).Cast<int>().Max();
var combinationValue =2* maxValue - 1;
for (int i = 0; i < combinationValue; i++)
{
var val = (AnimalType) i;
if ((val & type) == type) yield return val;
}
}
[Flags]
public enum AnimalType
{
Dog = 1,
Cat = 2,
Bird = 4,
Wolf = 8,
Fish = 16
}
It assumes there's no "hole" in the flags values.
I recently designed a data structure similar to 'Queue' and 'Stack' for a special purpose, with a fixed maximum number of objects in it and when it is full and inserted, the first inserted object drops out.
The Code:
public class AssemblyLine<T>
{
private long length;
public long Length { get { return this.length; } }
private T[] data;
private long Pointer = 0;
private long count = 0;
public long Count { get { return this.count; } }
public void Insert(T obj)
{
this.Data[Pointer] = obj;
this.Next();
if (this.count < this.length)
this.count++;
}
public T[] GetLastX(long x)
{
long p = this.Pointer;
if (x > this.count)
x = this.count;
T[] result = new T[x];
for (int i = 0; i < x; i++)
{
Previous();
result[i] = Grab();
}
this.Pointer = p;
return result;
}
public T[] GetFirstX(long x)
{
long p = this.Pointer;
if (x > this.count)
x = this.count;
long gap = this.length - this.count;
this.Pointer = (this.Pointer + gap) % this.length;
T[] result = new T[x];
for (int i = 0; i < x; i++)
{
result[i] = Grab();
Next();
}
this.Pointer = p;
return result;
}
public void Clear()
{
this.data = new T[this.length];
this.count = 0;
}
private void Next()
{
this.Pointer++;
if (this.Pointer > this.length - 1)
this.Pointer = 0;
}
private void Previous()
{
this.Pointer--;
if (this.Pointer < 0)
this.Pointer = this.length - 1;
}
private T Grab()
{
return this.data[this.Pointer];
}
public AssemblyLine(long Length)
{
this.length = Length;
this.data = new T[Length];
}
}
Now I am curious if its possible to get that connected to Linq, providing something like this:
AssemblyLine<int> myAssemblyLine = new AssemblyLine(100);
// Insert some Stuff
List<int> myList = myAssemblyLine.Where(i => i > 5).ToList();
Any idea someone?
Almost all LINQ extension methods are declared on IEnumerable<T>, so as soon as your class implements that interface, you'll get it for free.
There are just couple methods that use non-generic IEnumerable, like Cast or OfType, but if you can get your class implement generic IEnumerable<T> it will be much better, because users won't have to call Cast<T> first, to get IEnumerable<T> and access all the other methods (as is right now the case for some legacy collections).
You have to implement IEnumerable<T> for .Where(). See Adding LINQ to my classes.
Once you implement IEnumerable<T> and all required methods, you will have access to these methods: http://msdn.microsoft.com/en-us/library/vstudio/system.linq.enumerable_methods(v=vs.100).aspx
I have a generic class defined like this
class MyGenericClass<T> where T : ICompareable
{
T[] data;
public AddData(T[] values)
{
data = values;
}
}
In mainForm, I create 3 random numbers, and add them as values, lets say 1, 2 and 3. So my T[] data; will look like this: [0]1 [1]2 [2]3
What I want to do is to remove 1 of these values from the array, how do I do that when I'm using generics. Lets say I want to remove 3 from the array so it would look like this[0]1 [1]2
Why don't you use a generic List (List<T>) instead of the array as a private member of your class to hold the data ?
As it is a private member, the 'outside world' cannot access the list, and you will have a much easier life since a List allows you to Add and Remove items easily.
class MyGenericClass<T> where T : ICompareable
{
private List<T> data = new List<T>();
public AddData(params T[] values)
{
data.AddRange (values);
}
public RemoveData( T value )
{
data.Remove (value);
}
public RemoveData( params T[] values )
{
for( int i = 0; i < values.Length; i++ )
{
data.Remove (values[i]);
}
}
}
Once you've done this, you can use the Add member-method of the List to add items, and the Remove member method to remove items. Simple as that.
I've used the params keyword in the AddData method so that you can do this:
var x = new MyGenericClass<int>();
x.AddData(1);
x.AddData(2, 3, 4);
x.AddData(somIntegerList.ToArray());
Change your class to look like this (I also implemented Frederik's suggestion of using a List instead of a array.
class MyGenericClass<T> where T : ICompareable
{
List<T> data;
public AddData(T value)
{
data.Add(value);
}
public RemoveData(T value)
{
data.Remove(value);
}
}
If for some reasaon, you insist on using an array, the remove method may look something like this
public RemoveData(T value)
{
data = data.Where( e => e.CompareTo(value) != 0).ToArray();
}
I kind of had the same question, because I was writing a dynamically sized array to practice creating generic classes.
I found that you can either: move all of the elements down and then set the last element equal to default(T), or create a new array of size-1 to be filled with the remaining elements.
Ex:
public class Array<T>
{
private T[] _array { get; set; }
private int _max { get; set; }
private int _size { get; set; }
public Array()
{
_max = 10;
_array = new T[_max];
_size = 0;
}
public T Remove(int i)
{
if (i >= _size || i < 0) return default(T);
var tmp = _array[i];
for (var j = i; j < _size-1; ++j)
{
_array[j] = _array[j + 1];
}
_array[_size - 1] = default(T);
_size--;
return tmp;
}
}
Or...
public T Remove(int i) {
var tmp = new T[_size-1];
for(var j=0; j < i; ++j)
{
tmp[j] = _array[j];
}
var result = _array[i];
for(var j=i+1; j < _size-1; ++j)
{
tmp[j] = _array[j];
}
_array = null;
_array = tmp;
return result;
}
Basically, I have a collection of objects each implement a member of Type IValueCollection.
public interface IValueCollection : IEnumerable<decimal>
{
decimal this[int index] { get; set; }
}
MeasurementCollection.Values is of type IValueCollection.
With the logic below I want to pivot a collection of IValueCollection and wrote the extension method below.
public static IEnumerable<IValueCollection> PivotValues(this MeasurementCollection items)
{
if(items.IsQuantized())
{
int s = (int)items.First().Template.Frequency;
int c = items.Count;
for (int n = 0; n < s; n++)
{
IValueCollection v = new MeasurementValueCollection(c);
for (int m = 0; m < c; m++)
v[m] = items.ElementAt(m).Values[n];
yield return v;
}
}
}
should do
{{1,2,3}{4,5,6}{7,8,9}} results in {{1,4,7},{2,5,8},{3,6,9}}
However I think there is some nicer, slimmer and more readable expression to do this
can somebody point me in the right direction?
edit
info about underlying classes
interface IValueCollection : IEnumerable<decimal>
class MeasurementCollection : ICollection<IMeasurement>
interface IMeasurement
{
IMeasurementTemplate Template { get; }
......
}
interface IMeasurementTemplate
{
.....
MeasurementFrequency Frequency { get; }
}
I would, personally, force the evaluation of your collection in advance, and use it as an array. Right now, each time you call ElementAt, you're going to evaluate the IEnumerable<T> again, causing a lot of repeated searching.
By forcing it to evaluate to an array in advance, you simplify the entire process. Something like:
public static IEnumerable<IValueCollection> PivotValues(this MeasurementCollection items)
{
if(items.IsQuantized())
{
int elementLength = (int)items.First().Template.Frequency;
var itemArray = items.ToArray();
for (int n = 0; n < itemArray.Length; n++)
{
IValueCollection v = new MeasurementValueCollection(elementLength);
for (int m = 0; m < elementLength; m++)
{
v[m] = itemArray[m].Values[n];
}
yield return v;
}
}
else
yield break; // Handle the case where IsQuantized() returns false...
}
If you control MeasurementValueCollection, I would add a constructor which takes an IEnumerable<decimal> as input, as well. You could then do:
public static IEnumerable<IValueCollection> PivotValues(this MeasurementCollection items)
{
if(items.IsQuantized())
{
var elements = Enumerable.Range(0, (int)items.First().Template.Frequency);
var itemArray = items.ToArray();
foreach(var element in elements)
yield return new MeasurementValueCollection(
itemArray.Select(
(item,index) => itemArray[index].Value[element]
)
);
}
else
yield break; // Handle the case where IsQuantized() returns false...
}