Multidimensional List of ints C# - c#

First of all i searched through the questions and I haven't found the thing I need , maybe it doesn't exist haha but i'll give it a shot.I am new to C# and I am coming from C++, got highschool experience.
In C++ I had Vector<int> T[]; so I could create a list with a size that it wasn't know; and make something like this and not wasting space; to be more exact
T[0][....];
T[1][...];
1 2 3 4 5
1 2 3
2 4 1 5
0 0 0 0 0 0
I am trying to do this in C# and It doesn't seem to work; I have tried this so far:
public class myints
{
public int x { get; set; }
}
public List<myints[]> T = new List<myints[]>();
T[i].Add(new myints() { x = i });
I wanna be able to add stuff and then use Count() in a for to see how many elemts I have in a T[i]. like T[i].size()... Is this possible?
the program says System.Array does not contain a definition for Add

This example creates a list with a number of sublists of varying length and should serve as a good starting point for what you want to do.
List<List<int>> mainlist = new List<List<int>>();
List<int> counter = new List<int>() { 5, 4, 7, 2 };
int j = 0;
// Fill sublists
foreach(int c in counter)
{
mainlist.Add(new List<int>(c));
for(int i = 0; i < c; i++ )
mainlist[j].Add(i);
j++;
}
You could also add initialized lists to the main list
List<List<int>> mainlist = new List<List<int>>();
mainlist.Add(new List<int>() { 1, 5, 7 });
mainlist.Add(new List<int>() { 0, 2, 4, 6, 8 });
mainlist.Add(new List<int>() { 0, 0, 0 });

Related

How to get permutations with odd transpositions?

I have an algorithm with all possible permutations, can i get permutations with only odd transpositions. Or simplify the algorithm to find only such permutations. For example, array {1,2,3,4}. If I move one element I will get only one transposition, and it odd tansposition: {2,1,3,4}, {3,2,1,4}, {4,2,3,1}, {1,3,2,4}, {1,4,3,2}, {1,2,4,3}.
class Program
{
static void Main(string[] args)
{
int[] arr = new int[] { 1, 2, 3, 4 };
ShowAllCombinations(arr);
Console.Read();
}
public static void ShowAllCombinations<T>(IList<T> arr, string current = "")
{
if (arr.Count == 0)
{
Console.WriteLine(current);
return;
}
for (int i = 0; i < arr.Count; i++)
{
List<T> lst = new List<T>(arr);
lst.RemoveAt(i);
ShowAllCombinations(lst, current + arr[i].ToString());
}
}
}
This algorithm gives all permutations, but not only odd ones.
Your ShowAllCombinations method is inconvenient, the string should stay a list so you can process the elements.
Once you have a complete list of elements, you can "unpermute" back to the natural order and count the number of swaps. This assumes unique elements (no repetitions) and that the list is one-based. Note that this method permutes the list, will want to create a copy somewhere.
public void SwapCount(List<int> arr)
{
var swapCount = 0;
// double for loop, compare the value at the outer position
// to the value at the inner position.
for (var i=0; i<arr.Count; i++)
{
// Start at the index after the outer loop
for (var j=i+1; j<arr.Count; j++)
{
// If the inner value is what the outer value
// is supposed to be then swap it.
if (arr[j] == i+1)
{
var t = arr[i];
arr[i] = arr[j];
arr[j] = t;
swapCount++;
}
}
}
Console.WriteLine($"swap count: {swapCount}");
}
output
> SwapCount(new List<int>() { 1, 2, 3, 4 })
swap count: 0
> SwapCount(new List<int>() { 2, 1, 3, 4 })
swap count: 1
> SwapCount(new List<int>() { 1, 3, 2, 4 })
swap count: 1
> SwapCount(new List<int>() { 1, 3, 4, 2})
swap count: 2
>
This is ~ O(n^2), but I'm assuming performance is not so important here. You can find more efficient algorithms here: Parity of permutation with parallelism

Sorting pair of integers

I have a list with ~100k of integer pairs like these ones:
0, 12
0, 14
0, 1
0, 8
0, 2
0, 4
0, 3
1, 5
1, 11
1, 8
1, 2
2, 7
2, 9
2, 4
2, 5
2, 13
3, 12
3, 10
3, 4
3, 6
...
I need to sort them like
0, 1
0, 2
0, 3
0, 4
0, 8
0, 12
0, 14
1, 2
1, 5
1, 8
1, 11
2, 4
2, 5
2, 7
2, 9
2, 13
3, 4
3, 6
...
Currently I am doing:
myList.Sort(comparer);
when the comparer is defined as:
class EdgeIntersectComparer : IComparer<EdgeIntersect>
{
public int Compare(EdgeIntersect l1, EdgeIntersect l2)
{
if (l1.V1 < l2.V1)
return -1;
if (l1.V1 > l2.V1)
return 1;
if (l1.V2 < l2.V2)
return -1;
if (l1.V2 > l2.V2)
return 1;
return 0;
}
}
What can I do to improve execution speed? Is there any smarter approach to the problem?
Thanks.
EDIT:
Tested myList.OrderBy(e => e.V1).ThenBy(e => e.V2) and it's slower.
You had commented in a deleted post that V1 is already sorted.
In addition by V1 the list is already sorted.
I did a test using data already ordered by V1, but with V2 initialized with random numbers. I found this faster than your method:
myList = myList.GroupBy(x => x.V1).SelectMany(x => x.OrderBy(y => y.V2)).ToList();
This only works if V1 is already sorted.
Just as a possible option you coult try an Array instead of a List. (it depends on your context). If you can't:
Asuming:
public class Pair
{
public int First { get; private set; }
public int Second { get; private set; }
public Pair(int first, int second)
{
this.First = first;
this.Second = second;
}
}
And how the List is already ordered by the first item, maybe something like this? not sure if this will be faster:
public static List<Pair> FullOrderedList(List<Pair> SemiOrderedList)
{
List<Pair> FList = new List<Pair>();
List<Pair> demi = new List<Pair>();
int MaxNumber = SemiOrderedList.Count;
int compared = 0;
for (int i = 0; i < MaxNumber; i++)
{
int first = SemiOrderedList[i].First;
if (compared == first)
{
demi.Add(SemiOrderedList[i]);
}
else
{
compared++;
FList.AddRange(demi.OrderBy(x => x.Second));
demi.Clear();
}
}
return FList;
}
A small speed increase can be gained by optimizing your comparer:
if (l1.V1 == l2.V1)
{
if (l1.V2 > l2.V2) return 1;
else return -1;
}
else if (l1.V1 < l2.V1)
return -1;
else return 1;
max 2 statements to check, rather than your 4.

How to generate random INT that cannot be a value in a List<int>?

I'm trying to do the following.
Let's say I have a List, and I want to generate a new int in a specific range, but the value cannot be already defined in the List.
List<int> PredefinedIntsList = new List<int>() { 1, 3, 4, 8, 9 };
Random rnd = new Random();
int NewRandomValue = rnd.Next(0, 10);
rnd.Next (obviously) comes up with 1, 3, 4, 8 or 9. But I ONLY want it to return 2, 5, 6, 7 or 10.
Any ideas?
As always, LINQ is your friend:
[TestMethod]
public void RandomTest()
{
var except = new[] {1, 2, 3, 5};
GetRandomExcept(1, 5, except).Should().Be(4);
}
private static int GetRandomExcept(int minValue, int maxValue, IEnumerable<int> except)
{
return GetRandoms(minValue, maxValue).Except(except).First();
}
private static IEnumerable<int> GetRandoms(int minValue, int maxValue)
{
var random = new Random();
while (true) yield return random.Next(minValue, maxValue);
}
Just keep in mind that you never should call GetRandoms().ToArray() or .Max() or .OrderBy() and so on, because you will get an endless loop and generate randoms forever.
What you can do though, is call GetRandoms().Take(10).ToArray() to get the next 10 random integers in an array.
Try examining if you can use the contains() method of List class... Simple solution would be to just generate values and checking contains and rejecting values that are already in the List until you get a value that is not. Also it might be more appropriate to use the Set Class because a set can not contain two elements that are equal.
What you need to do sample from other set. Lets say P is your predefinedIntsList and A is {1,2...9}.
You need to create a list, N = A-P. You will randomly sample from this set of numbers. It can be written more elegantly I suppose but see below example.
class Program
{
static void Main(string[] args)
{
List<int> predefinedIntsList = new List<int>() { 1, 3, 4, 8, 9 };
Random rnd = new Random();
List<int> newIntsList = new List<int>();
int upperBound = 10;
for (int i = 0; i < upperBound; i++)
{
if (!predefinedIntsList.Contains(i))
{
newIntsList.Add(i);
}
}
for (int i = 0; i < 20; i++)
{
int newRandomValueIndex = rnd.Next(0, newIntsList.Count);
int newRandomValue = newIntsList[newRandomValueIndex];
Console.WriteLine(newRandomValue);
}
}
}
Output
2
0
6
7
5
5
5
7
0
7
6
6
5
5
5
0
6
7
0
7
rnd.Next (obviously) comes up with 1, 3, 4, 8 or 9. But I ONLY want it
to return 2, 5, 6, 7 or 10.
Obviously not, it will return value that is either 0, 1, 2, 3, 4, 5, 6, 7, 8 or 9 :P. If you're looking to include 10, and not 0, you want .Next(1, 11)
There are two choices that can work: either try generating values until you succeed, or if the range is small enough, generate the range, mark elemens that can't be picked, and sort them to last ones, and then pick random between [0..possibleToPickElementsCount]
The first approach would look something like this:
public static class RandomExtensions
{
public static int Next(this Random random,
int minInclusive,
int maxExclusive,
IList<int> values)
{
// this will crash if values contains
// duplicate values.
var dic = values.ToDictionary(val => val);
// this can go into forever loop,
// think about this a bit.
for(;;){
var randomNumber= random.Next(minInclusive, maxExclusive);
if(!dic.ContainsKey(randomNumber))
return randomNumber;
}
}
}
The second approach is this, however it's only to give you an idea:
public static class RandomExtensions
{
class NormalizedPair
{
public int Value {get;set;}
public PairStatus Status {get;set;}
public NormalizedPair(int value){
Value = value;
}
public enum PairStatus {
Free,
NotFree
}
}
private static Random _internalRandom = new Random();
public static int Next(this Random random,
int minInclusive,
int maxExclusive,
IList<int> values)
{
var elements = maxExclusive - minInclusive;
var normalizedArr = new NormalizedPair[elements];
var normalizedMinInclusive = 0;
var normalizedMaxExclusive = maxExclusive - minInclusive;
var normalizedValues = values
.Select(x => x - minInclusive)
.ToList();
for(var j = 0; j < elements; j++)
{
normalizedArr[j] = new NormalizedPair(j){
Status = NormalizedPair.PairStatus.Free
};
}
foreach(var val in normalizedValues)
normalizedArr[val].Status = NormalizedPair.PairStatus.NotFree;
return normalizedArr
.Where(y => y.Status == NormalizedPair.PairStatus.Free) // take only free elements
.OrderBy(y => _internalRandom.Next()) // shuffle the free elements
.Select(y => y.Value + minInclusive) // project correct values
.First(); // pick first.
}
}
Or, if you're fan of sets:
public static int Next2(this Random random,
int minInclusive,
int maxExclusive,
IList<int> values)
{
var rangeSet = new HashSet<int>(
Enumerable.Range(
minInclusive,
maxExclusive - minInclusive));
// remove gibberish
rangeSet.ExceptWith(new HashSet<int>(values));
// this can be swapped out with
// yates shuffle algorithm
return rangeSet.OrderBy(x => _internalRandom.Next())
.First();
}
Rather than write logic to determine whether the random number has already been selected I prefer to generate a second list with the items in a random order.
That is easy to do with LINQ
var originalList = new List<int>() { 1, 3, 4, 8, 9 };
Random rnd = new Random();
var secondList = originalList.OrderBy(x=>rnd.NextDouble());
The call to rnd.NextDouble returns a random seed that is used by the OrderBy method to sort each int value.
When I need to run thought the randomized items more than once, with a new sort order each time I walk the list, I will use a Queue to store the items. Then dequeue the items as needed. When the queue is empty it's time to refill.
private Queue<int> _randomizedItems;
private void RandomTest()
{
var originalList = new List<int>() { 1, 3, 4, 8, 9 };
Random rnd = new Random();
var temp = originalList.OrderBy(r=>rnd.NextDouble());
_randomizedItems = new Queue<int>(temp);
while (_randomizedItems.Count >0)
{
MessageBox.Show(_randomizedItems.Dequeue().ToString());
}
}

To find a sequence of one array into another array [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I have two array objects
int[] arr1= new int[] {1,2,5,6,7,9,3,5,6,7}
int[] arr2 = new int[] {5,6,7}
Now, how to find the no of occurrences of arr2 in arr1?
Perhaps not very elegant, but it should work.
This selects all subarrays in a having the same length of b, and checks how many are equal to b.
int[] a = {1, 2, 3, 4, 5};
int[] b = {2, 3};
int count = 0;
int bl = b.Length;
for (int i = 0; i <= a.Length - bl; i++)
{
var suba = a.Skip(i).Take(bl);
if (suba.SequenceEqual(b))
count++;
}
N.B.: this solution considers overlapping subarrays, therefore if a = {2, 2, 2} and b = {2, 2}, the count will be 2.
you may use arr2.Intersect(arr1).Count()
So in your case it will return 3, as 3 elements in arr2 are present in arr1.
If this is not what you're asking for, please clarify.
Use the intersect. This code snippet will solve your problem and print all duplicates, and show the count of each in arr1. Note that I am also using the Linq Distinct(), so that when looping common occurrences, I only check once and not more.
int[] arr1= new int[] {1,2,5,6,7,9,3,5,6,7};
int[] arr2 = new int[] {5,6,7};
var listCommon = arr1.AsEnumerable().Where(arr2.AsEnumerable().Contains);
foreach (var x in listCommon.Distinct()) {
var numberOfOccurencesInArr1 = arr1.Where(y => y == x).Count();
Console.WriteLine(x + " is : " + numberOfOccurencesInArr1.ToString() + " times in arr1");
}
Console.ReadLine();
See MSDN for more information; http://msdn.microsoft.com/en-us/library/system.linq.enumerable.intersect(v=vs.110).aspx
The listCommon will be the number of common items in both arrays.
Try This
string result = string.Empty; ;
int[] arr1 = new int[] { 1, 2, 5, 6, 7, 9, 3, 5, 6, 7 };
int[] arr2 = new int[] { 5, 6, 7 };
int count = arr2.Intersect(arr1).Count();
if (count == arr2.Length)
{
result = "Found";
}
else
{
result = "Not Found";
}
If you want to count how many occurences of an integer of the second array are present in the first array then you could write
int[] arr1 = new int[] {1,2,5,6,7,9,3,5,6,7};
int[] arr2 = new int[] {5,6,7};
Dictionary<int, int> counter = new Dictionary<int, int>();
foreach(int x in arr1)
{
if(arr2.Contains(x))
{
if(counter.ContainsKey(x))
counter[x]++;
else
counter[x] = 1;
}
}
foreach(KeyValuePair<int, int> kvp in counter)
Console.WriteLine("Key=" + kvp.Key.ToString() + " is present " + kvp.Value.ToString() + " times");
int[] arr1 = new int[] { 1, 2, 5, 6, 7, 9, 3, 5, 6, 7 };
int[] arr2 = new int[] { 5, 6, 7 };
how to find the no of occurrences of arr2 in arr1?
If you are expecting the result to be 2. Since the 5,6,7 appears twice in the arr1
try this
var res = arr1.Where(x => arr2.Contains(x)).Count()/arr2.Count();
Try this one:
var results = (from a1 in arr1
join a2 in arr2
on a1 equals a2
group arr1 by a1 into Group
select new
{
Number = Group.Key,
Times = Group.Count()
});
foreach(var result in results)
Console.WriteLine(result.Number+" "+result.Times);
Please check this solution using the following fiddle .NET fiddle
You can use ToLookup on the ints in the first count which are also in the second array. Then you just have to take the min-count of all groups since that's the greatest intersection:
var subsetGroups = arr1.Where(i1 => arr2.Contains(i1)).ToLookup(i => i);
int minGroupCount = 0;
// check if all integers from the array are in the first at all
if(arr2.All(i => subsetGroups.Contains(i)))
{
minGroupCount = subsetGroups.Min(g => g.Count()); // 2
}
Note that this approach doesn't care about the order and it also doesn't care about the number of duplicates in the second array. This might be desired or not.
As you input is arrays you can use indexing to effectively count the number of occurrences of the subarrays in the main array:
var count = 0;
for (var i = 0; i < arr1.Length - arr2.Length + 1; i += 1) {
if (arr1[i] != arr2[0])
continue;
var isSubarray = true;
for (var j = 0; j < arr2.Length; ++j)
if (arr1[i + j] != arr2[j]) {
isSubarray = false;
break;
}
if (isSubarray)
count += 1;
}
The result will be 2 because 567 is found two times in 1256793567.
If the subarray can "overlap" itself (e.g. 11 in 111) all "overlaps" will be counted (e.g. the result will be 2 for this example). If that is not the intention you simply have to advance the index i at the end of the main loop to skip the found subarray.

Push index array

I'm sure there's a word for what I,m looking for but since I don't know it I can't find the answear to my problem, what I have is a jagged array of double and I want the value at index 0 to be the value of index 1 same for the index 1 going to the 2 until the end of the array and the last index being pish to the index 0
Example :
Original
private double[][] array = { {1, 2, 3, 4}, {5, 6, 7, 8}, ...}
Become (After the modification)
I know it's seems I'm redeclaring the array that's not the point, it's just to show you what it should be after.
private double[][] array = { {4, 1, 2, 3}, {8, 5, 6, 7}, ...}
EDIT
If you know the word or somethings about what I'm looking for, could you say so in the comment I will delete the question and look further into it
This is usually called rotating. You can achieve it a for-loop, but note that since your rotating to the right, it's easier to work your way from back to front, like this:
for(var i = 0; i < array.Length; i++)
{
var len = array[i].Length;
if (len > 1) {
var last = array[i][len - 1];
for(var j = len - 1; j > 0; j--)
{
array[i][j] = array[i][j - 1];
}
array[i][0] = last;
}
}
You could easily use a List of Queue instead of a jagged array. Below an example of how your jagged array could look like and how to move elements:
var queues = new List<Queue<double>>();
//first queue (1,2,3,4)
var queue = new Queue<double>();
queue.Enqueue(4);
queue.Enqueue(3);
queue.Enqueue(2);
queue.Enqueue(1);
queues.Add(queue);
//second queue (5,6,7,8)
var queue2 = new Queue<double>();
queue.Enqueue(8);
queue.Enqueue(7);
queue.Enqueue(6);
queue.Enqueue(5);
queues.Add(queue2);
//an example of how to "rotate"
var lastItem = queues[0].Dequeue(); // (1,2,3)
queues[0].Enqueue(lastItem); // (4,1,2,3)

Categories