How can I repopulate an array? - c#

I have code that populates an array:
var counters = new[] { 1,2,4,8 }
This works good but later on in my code I would like to do something like this:
counters = new[] { 2,2,3,5 }
Is there some way I can do this? I am very new to C# and still learning

The code you wrote in your question would work fine: the first line will create a new array, the second line will also create a new array and will assign the new array to the existing variable. The old integer array will be replaced (and later be garbage collected)

What is your problem? Your code is valid:
var counters = new[] { 1,2,4,8 };
counters = new[] { 2, 2, 3, 5 };

Your code will work, but it does not repopulate the array, it creates a new array.
You could do this
Array.Copy( new int[] { 2,2,3,5 }, counters, 4);

Yes, you can do as you have written.
However, note that this will create a new array, not replace the values in the old array. That makes a difference if another variable holds a reference to the same array.
Example 1
var counters = new[] { 1, 2, 4, 8 };
var counters2 = counters;
counters = new[] { 2, 2, 3, 5 };
Console.WriteLine(counters2[0].ToString()); // outputs 1
Example 2
var counters = new[] { 1, 2, 4, 8 };
var counters2 = counters;
counters[0] = 2;
counters[1] = 2;
counters[2] = 3;
counters[3] = 5; // or use Array.Copy as suggested by Henrik
Console.WriteLine(counters2[0].ToString()); // outputs 2

Related

Summing up a list of integer arrays using threads for each array in C# Console application

I have a List of int arrays. The list can be from 1 to 4 arrays.
I want to know how do i go about summing each array with individual threads and
placing the summed values into a new int array.
If the order of the new array is not important here you have a example
List<int[]> arraysList = new List<int[]>();
arraysList.Add(new int[] { 2, 3, 5 });
arraysList.Add(new int[] { 2, 3, 5, 9, 123, 5 });
arraysList.Add(new int[] { 3 });
arraysList.Add(new int[] { 9,8 });
ConcurrentBag<int> SummedValueOfEveryArray = new ConcurrentBag<int>();
Parallel.ForEach(arraysList, array =>
{
SummedValueOfEveryArray.Add(array.Sum());
});
//Your result
var result = SummedValueOfEveryArray.ToArray<int>();
//The sum of all arrays
var totalSum = SummedValueOfEveryArray.Sum();
This code will do what you ask. One side note however, this only parallelizes when .Net feels it could improve performance.
List<int[]> intlist = new List<int[]>();
int[] result = intlist.AsParallel().Select(arr => arr.Sum()).ToArray();
Given 1 to 4 arrays it may be that .Net never sees the point of parallelizing. But if you absolutely must you can force parallelization by using Parallel.For as shown below.
List<int[]> intlist = new List<int[]>();
int[] result = new int[intlist.Count];
Parallel.For(0, intlist.Count, i =>
{
result[i] = intlist[i].Sum();
});

How to write object to disk(save in a file)

I am using example code below from accord.net framework website, Any ways this code is working fine what i want to achieve is save object to the file..
I want to save DynamicTimeWarping class type object, kernel in following code to the disk(Save in a file)
DynamicTimeWarping kernel = new DynamicTimeWarping(length: 3);
I have tried using XMLSerializer but visual studio is giving error that it can not be serialized because it does not have parameterless constructor.
double[][][] sequences =
{
{
new double[] { 1, 1, 1 }, // first observation of the first sequence
new double[] { 1, 2, 1 }, // second observation of the first sequence
new double[] { 1, 4, 2 }, // third observation of the first sequence
new double[] { 2, 2, 2 }, // fourth observation of the first sequence
},
new double[][] // second sequence (note that this sequence has a different length)
{
new double[] { 1, 1, 1 }, // first observation of the second sequence
new double[] { 1, 5, 6 }, // second observation of the second sequence
new double[] { 2, 7, 1 }, // third observation of the second sequence
},
new double[][] // third sequence
{
new double[] { 8, 2, 1 }, // first observation of the third sequence
},
new double[][] // fourth sequence
{
new double[] { 8, 2, 5 }, // first observation of the fourth sequence
new double[] { 1, 5, 4 }, // second observation of the fourth sequence
}
};
int[] outputs =
{
-1,-1, // First two sequences are of class -1 (those start with {1,1,1})
1, 1, // Last two sequences are of class +1 (don't start with {1,1,1})
};
double[][] inputs = new double[sequences.Length][];
for (int i = 0; i < sequences.Length; i++)
inputs[i] = Matrix.Concatenate(sequences[i]);
// Now we have to setup the Dynamic Time Warping kernel. We will have to
// inform the length of the fixed-length observations contained in each
// arbitrary-length sequence:
//
DynamicTimeWarping kernel = new DynamicTimeWarping(length: 3);
// Now we can create the machine. When using variable-length
// kernels, we will need to pass zero as the input length:
var svm = new KernelSupportVectorMachine(kernel, inputs: 0);
/ / Create the Sequential Minimal Optimization learning algorithm
var smo = new SequentialMinimalOptimization(svm, inputs, outputs)
{
Complexity = 1.5
};
// And start learning it!
double error = smo.Run(); // error will be 0.0
// At this point, we should have obtained an useful machine. Let's
// see if it can understand a few examples it hasn't seem before:
double[][] a =
{
new double[] { 1, 1, 1 },
new double[] { 7, 2, 5 },
new double[] { 2, 5, 1 },
};
double[][] b =
{
new double[] { 7, 5, 2 },
new double[] { 4, 2, 5 },
new double[] { 1, 1, 1 },
};
int resultA = System.Math.Sign(svm.Compute(Matrix.Concatenate(a))); // -1
int resultB = System.Math.Sign(svm.Compute(Matrix.Concatenate(b))); // +1
Looks like this Class in that framework has SerializableAttribute added.
This example should do:
https://msdn.microsoft.com/en-us/library/system.serializableattribute%28v=vs.110%29.aspx

Merging arrays with common element

I want to merge arrays with common element. I have list of arrays like this:
List<int[]> arrList = new List<int[]>
{
new int[] { 1, 2 },
new int[] { 3, 4, 5 },
new int[] { 2, 7 },
new int[] { 8, 9 },
new int[] { 10, 11, 12 },
new int[] { 3, 9, 13 }
};
and I would like to merge these arrays like this:
List<int[]> arrList2 = new List<int[]>
{
new int[] { 1, 2, 7 },
new int[] { 10, 11, 12 },
new int[] { 3, 4, 5, 8, 9, 13 } //order of elements doesn't matter
};
How to do it?
Let each number be a vertex in the labelled graph. For each array connect vertices pointed by the numbers in the given array. E.g. given array (1, 5, 3) create two edges (1, 5) and (5, 3). Then find all the connected components in the graph (see: http://en.wikipedia.org/wiki/Connected_component_(graph_theory))
I'm pretty sure it is not the best and the fastest solution, but works.
static List<List<int>> Merge(List<List<int>> source)
{
var merged = 0;
do
{
merged = 0;
var results = new List<List<int>>();
foreach (var l in source)
{
var i = results.FirstOrDefault(x => x.Intersect(l).Any());
if (i != null)
{
i.AddRange(l);
merged++;
}
else
{
results.Add(l.ToList());
}
}
source = results.Select(x => x.Distinct().ToList()).ToList();
}
while (merged > 0);
return source;
}
I've used List<List<int>> instead of List<int[]> to get AddRange method available.
Usage:
var results = Merge(arrList.Select(x => x.ToList()).ToList());
// to get List<int[]> instead of List<List<int>>
var array = results.Select(x => x.ToArray()).ToList();
Use Disjoint-Set Forest data structure. The data structure supports three operations:
MakeSet(item) - creates a new set with a single item
Find(item) - Given an item, look up a set.
Union(item1, item2) - Given two items, connects together the sets to which they belong.
You can go through each array, and call Union on its first element and each element that you find after it. Once you are done with all arrays in the list, you will be able to retrieve the individual sets by going through all the numbers again, and calling Find(item) on them. Numbers the Find on which produce the same set should be put into the same array.
This approach finishes the merge in O(α(n)) amortized (α grows very slowly, so for all practical purposes it can be considered a small constant).

comparing two lists and removing missing numbers with C#

there are two lists:
List<int> list2 = new List<int>(new[] { 1, 2, 3, 5, 6 }); // missing: 0 and 4
List<int> list1 = new List<int>(new[] { 0, 1, 2, 3, 4, 5, 6 });
how do you compare two lists, find missing numbers in List1 and remove these numbers from List1? To be more precise, I need to find a way to specify starting and ending position for comparison.
I imagine that the proccess should be very similar to this:
Step 1.
int start_num = 3; // we know that comparisons starts at number 3
int start = list2.IndexOf(start_num); // we get index of Number (3)
int end = start + 2; // get ending position
int end_num = list2[end]; // get ending number (6)
now we've got positions of numbers (and numbers themselves) for comparison in List2 (3,5,6)
Step 2. To get positions of numbers in List1 for comparison - we can do the following:
int startlist1 = list1.IndexOf(start_num); // starting position
int endlist1 = list1.IndexOf(end_num); // ending position
the range is following: (3,4,5,6)
Step 3. Comparison. Tricky part starts here and I need a help with it
Basically now we need to compare list2 at (3,5,6) with list1 at (3,4,5,6). The missing number is "4".
// I have troubles with this step but the result will be:
int remove_it = 4; // or int []
Step 4. Odd number removal.
int remove_it = 4;
list1 = list1.Where(a => a != remove_it).ToList();
works great, but what will happen if we have 2 missing numbers? i.e.
int remove_it = 4 // becomes int[] remove_it = {4, 0}
Result As you have guessed the result is new List1, without number 4 in it.
richTextBox1.Text = "" + string.Join(",", list1.ToArray()); // output: 0,1,2,3,5,6
textBox1.Text = "" + start + " " + start_num; // output: 2 3
textBox3.Text = "" + end + " " + end_num; // output: 4 6
textBox2.Text = "" + startlist1; // output: 3
textBox4.Text = "" + endlist1; // output: 6
Can you guy help me out with Step 3 or point me out to the right direction?
Also, can you say what will happen if starting number(start_num) is the last number, but I need to get next two numbers? In example from above numbers were 3,5,6, but they should be no different than 5,6,0 or 6,0,1 or 0,1,2.
Just answering the first part:
var list3 = list1.Intersect(list2);
This will set list3 to { 0, 1, 2, 3, 4, 5, 6 } - { 0, 4 } = { 1, 2, 3, 5, 6 }
And a reaction to step 1:
int start_num = 3; // we know that comparisons starts at number 3
int start = list2.IndexOf(start_num); // we get index of Number (3)
int end = start + 2; // get ending position
From where do you get all those magic numbers (3, + 2 ) ?
I think you are over-thinking this, a lot.
var result = list1.Intersect(list2)
You can add a .ToList on the end if you really need the result to be a list.
List<int> list2 = new List<int>(new[] { 1, 2, 3, 5, 6 }); // missing: 0 and 4
List<int> list1 = new List<int>(new[] { 0, 1, 2, 3, 4, 5, 6 });
// find items in list 2 notin 1
var exceptions = list1.Except(list2);
// or are you really wanting to do a union? (unique numbers in both arrays)
var uniquenumberlist = list1.Union(list2);
// or are you wanting to find common numbers in both arrays
var commonnumberslist = list1.Intersect(list2);
maybe you should work with OrderedList instead of List...
Something like this:
list1.RemoveAll(l=> !list2.Contains(l));
To get the numbers that exist in list1 but not in list2, you use the Except extension method:
IEnumerable<int> missing = list1.Except(list2);
To loop through this result to remove them from list1, you have to realise the result, otherwise it will read from the list while you are changing it, and you get an exception:
List<int> missing = list1.Except(list2).ToList();
Now you can just remove them:
foreach (int number in missing) {
list1.Remove(number);
}
I'm not sure I understand your issue, and I hope the solution I give you to be good for you.
You have 2 lists:
List list2 = new List(new[] { 1, 2, 3, 5, 6 }); // missing: 0 and 4
List list1 = new List(new[] { 0, 1, 2, 3, 4, 5, 6 });
To remove from list1 all the missing numbers in list2 I suggest this solution:
Build a new list with missing numbers:
List diff = new List();
then put all the numbers you need to remove in this list. Now the remove process should be simple, just take all the elements you added in diff and remove from list2.
Did I understand correctly that algorithm is:
1) take first number in List 2 and find such number in List1,
2) then remove everything from list 1 until you find second number form list2 (5)
3) repeat step 2) for next number in list2.?
You can use Intersect in conjunction with Skip and Take to get the intersection logic combined with a range (here we ignore the fact 0 is missing as we skip it):
static void Main(string[] args)
{
var list1 = new List<int> { 1, 2, 3, 4, 5 };
var list2 = new List<int> { 0, 1, 2, 3, 5, 6 };
foreach (var i in list2.Skip(3).Take(3).Intersect(list1))
Console.WriteLine(i); // Outputs 3 then 5.
Console.Read();
}
Though if I'm being really honest, I'm not sure what is being asked - the only thing I'm certain on is the intersect part:
var list1 = new List<int> { 1, 2, 3, 4, 5 };
var list2 = new List<int> { 0, 1, 2, 3, 5, 6 };
foreach (var i in list2.Intersect(list1))
Console.WriteLine(i); // Outputs 1, 2, 3, 5.
ok, seems like I hadn't explained the problem well enough, sorry about it. Anyone interested can understand what I meant by looking at this code:
List<int> list2 = new List<int>() { 1, 2, 3, 5, 6 }; // missing: 0 and 4
List<int> list1 = new List<int>() { 0, 1, 2, 3, 4, 5, 6 };
int number = 3; // starting position
int indexer = list2.BinarySearch(number);
if (indexer < 0)
{
list2.Insert(~index, number); // don't look at this part
}
// get indexes of "starting position"
int index1 = list1.Select((item, i) => new { Item = item, Index = i }).First(x => x.Item == number).Index;
int index2 = list2.Select((item, i) => new { Item = item, Index = i }).First(x => x.Item == number).Index;
// reorder lists starting at "starting position"
List<int> reorderedList1 = list1.Skip(index1).Concat(list1.Take(index1)).ToList(); //main big
List<int> reorderedList2 = list2.Skip(index2).Concat(list2.Take(index2)).ToList(); // main small
int end = 2; // get ending position: 2 numbers to the right
int end_num = reorderedList2[end]; // get ending number
int endlist1 = reorderedList1.IndexOf(end_num); // ending position
//get lists for comparison
reorderedList2 = reorderedList2.Take(end + 1).ToList();
reorderedList1 = reorderedList1.Take(endlist1 + 1).ToList();
//compare lists
var list3 = reorderedList1.Except(reorderedList2).ToList();
if (list3.Count != 0)
{
foreach (int item in list3)
{
list1 = list1.Where(x => x != item).ToList(); // remove from list
}
}
// list1 is the result that I wanted to see
if there are any ways to optimize this code please inform me. cheers.

Extracting 'single item' from Multi Dimensional Array (c#)

Say I have the code
var marray = new int[,]{{0,1},{2,3},{4,5}};
Is it possible to get a reference to the first item - i.e. something that looked like:
var _marray = marray[0];
//would look like: var _marray = new int[,]{{0,1}};
Instead, when referencing marray from a one dimensional context, it sees marray as having length of 6
(i.e. new int[]{0,1,2,3,4,5})
Use a jagged array
var marray = new[] { new[] { 0, 1 }, new[] { 2, 3 }, new[] { 4, 5 } };
Console.WriteLine(marray[0][1]);

Categories