I want to find range between closest value of this elements.
Delta value between elements. And it would be positive number because its modulus.
class Element {
double DeltaValue;
double ElementValue;
public Element(double n) {
ElementValue = n;
}
static void Main() {
list<Element> ListElements = new list<Elements>;
ListElements.Add(3);
ListElements.Add(10);
ListElements.Add(43);
ListElements.Add(100);
ListElements.Add(30);
ListElements.Add(140);
for(int i = 0; i < ListElements.Count; i++) {
ListElements[i].DeltaValue = //and problem is here
//example as for ListElements[2].DeltaValue will be 13; because 43-30=13;
}
//example as for ListElements[2].DeltaValue will be 13; because 43-30=13;
Just sort the array in increasing order and the smallest difference between the previous and the next element of the current element will solve your problem. Here for last element you can just look at the difference of its previous element.
Should be able to do it in one line with linq via the following:
public static int GetClosestVal(this int[] values, int place)
{
return values.OrderBy(v => Math.Abs(v - values[place])).ToArray()[1];
}
The following outputs 30
var testArray = new [] {3, 10, 43, 100, 30, 140};
Console.Write(testArray.GetClosestVal(2));
Basically speaking you sort by the absolute difference between each item and the chosen item, then grab the second item in the list since the first will always be the item itself (since n-n=0)
Thus the sorted list should be [43, 30, 20, 3, 100, 140]
I'm not sure, whether I understand your question right. If I have, then the following code snippet can help you:
class Program
{
static void Main(string[] args)
{
Elements ListElements = new Elements();
ListElements.ElementValue.Add(3);
ListElements.ElementValue.Add(10);
ListElements.ElementValue.Add(43);
ListElements.ElementValue.Add(100);
ListElements.ElementValue.Add(30);
ListElements.ElementValue.Add(140);
ListElements.CreateDeltaValues();
for (int i = 0; i < ListElements.DeltaValue.Count; i++)
{
Console.WriteLine("ListElement["+i+"]: " + ListElements.DeltaValue[i]);
//example as for ListElements[2].DeltaValue will be 13; because 43-30=13;
}
Console.ReadKey();
}
}
public class Elements
{
public List<double> DeltaValue = new List<double>();
public List<double> ElementValue = new List<double>();
public void CreateDeltaValues()
{
this.ElementValue.Sort();
for (int i = 1; i < this.ElementValue.Count; i++)
{
var deltaValue = this.ElementValue[i] - this.ElementValue[i-1];
this.DeltaValue.Add(deltaValue);
}
}
}
It's a console application, but this code should work also for other app models.
This code generates the following output:
Related
Please check the code below. I am trying to set value to a random property of a int list. Problem is that even after i set 5 to a random list this value getting inserted to that property. What am I doing wrong here?
var TransactionList = new List<int>();
for (int i = 0; i < 59; i++)
{
TransactionList.Add(0);
}
var randTransaction = TransactionList.OrderBy(x => Guid.NewGuid()).FirstOrDefault();
//here i am trying to set 5 value to a random TrnasactionList but this not being set
randTransaction = 5;
Try like below. new Random().Next(0, 59); will return value between 0 and 59. Or you can better set it like new Random().Next(0, TransactionList.Count); for it to be dynamic with list.
new Random().Next(minValue, maxValue); The maxValue for the upper-bound in the Next() method is exclusive—the range includes minValue, maxValue-1, and all numbers in between.
var TransactionList = new List<int>();
for (int i = 0; i < 59; i++)
{
TransactionList.Add(0);
}
// var index = new Random().Next(0, 59);
// Below will work for dynamic length of list.
var index = new Random().Next(0, TransactionList.Count);
TransactionList[index] = 5;
If you don't mind the original list getting sorted you could do this:
class Program
{
static void Main(string[] args)
{
var transactionList = new List<int>();
for (int i = 0; i < 59; i++)
{
//I initialized the list with i instead of 0 to better see sorting in place
transactionList.Add(i);
}
transactionList.Sort(new RandomComparer());
//changed it to 99 to spot it more easily
transactionList[0] = 99;
foreach (var i in transactionList)
Console.WriteLine(i);
}
}
public class RandomComparer : IComparer<int>
{
private Random _random = new Random();
public int Compare(int x, int y)
{
return _random.Next(-1, 2);
}
}
See it in action:
https://dotnetfiddle.net/NKuPdx
randTransaction is "int" data type, which is primitive data type.
if you want to set randTransaction that reflect to it's object, just set the object it self
I have this function that call itself to find all the possible combination with the array of int. The problem is that the program calculate the first combination and then, when the recursion continues, the List of combination still contains that value and i don't understand why.
public static void Permutation(List<int> items, int h, List<int> actualCombination)
{
if (h == actualCombination.Count)
{
results[results.Count] = actualCombination;
}
else
{
for (int i = 0; i < items.Count; i++)
{
actualCombination.Add(items[i]);
List<int> temp = new List<int>(items);
temp.Remove(items[i]);
Permutation(temp, h, actualCombination);
}
return;
}
}
after that, i call the function in main. In my case the second parameter specify the combination length."Results" is a Dictionary composed by int as key and List as value that is used to save all the combination.
static void Main(string[] args)
{
Permutation(new List<int> { 1, 2, 3 }, 3, new List<int>());
Console.ReadKey();
}
I solved the problem by copying the List before of the function add.
Well, first of all, I am not sure whether my title in this question delivered what I want to ask or not. I just do not sure how to describe my problem in one sentence, hopefully the title would not cause any misleading.
If I have a list. Inside the list contain 100 data : list<100>
If I put this list inside a 1 second timer tick and do like this:
myList.RemoveRange(0, 2);
This mean, every 1 second, the data length inside the list will be -2;
This mean, every 1 second, it will be <98> , <96> , <94> .... <0>
Now my problem is...I still have a list, but the list will contain an array: list<array[100]>
Now, what I want is, every 1 second, the data length inside the array inside the list will be -2. But I am not sure know how to do this...
what I want is, every 1 second <array[98]> , <array[96]> , <array[96]> ... <array[0]>
And so, if the list contain <array0[100] , array1[100], array2[100]>
if i put this list inside a loop, every 1 second, it should be
array0[98] , array0[96] ... array0[0]
array1[98] , array1[96] ... array1[0]
array2[98] , array2[96] ... array2[0]
Update:
List<int[]> myList = new List<int[]>();
object myLock = new object();
Random rand = new Random();
public Form1()
{
timer1second.Start();
}
private void SomeMethod()
{
int[] myData = new int [100]
for (int i = 0; i < 100; i++)
{
//generate some random number to store inside myData[]
myData[i] = rand.Next(1 , 10);
}
lock (myLock)
{
myList.Add(myData); //mean List[0] = myData[100]
}
}
private void timer1second_Tick(object sender, EventArgs e)
{
lock (myLock)
{
//do something here in myList to get the myData[100 - 2]
//so that every 1 second tick, the data length inside the MyData will be -2
}
}
Convert the Array item into a List.
Then remove the range from the List
Convert it back to an Array.
Insert it back into the List
Here is a sample:
int currentIndex = 0;
var myList = new List<int[]>();
var intArray = new int[100];
myList.Add(intArray);
// Convert to List.
var newIntArrayList = myList[currentIndex].ToList();
// Remove the ranges
// Index would be based on you logic
newIntArrayList.RemoveRange(0, 2);
//Replace the list with the new arry
myList[currentIndex] = newIntArrayList.ToArray();
Update : Array.Resize should also help.
int currentIndex = 0;
int arrayLength = 100;
var myList = new List<int[]>();
var intArray = new int[100];
myList.Add(intArray);
// Get the array
var array = myList[currentIndex];
// Resize
Array.Resize(ref array, arrayLength-2);
//Replace the list with the update array
myList[currentIndex] = array;
List<int> myList = new List<int>();
for (int i = 1; i < 101; i++)
{
myList.Add(i);
}
for (int i = 100; i > 0; i--)
{
System.Threading.Threading.Sleep(1000);
myList.RemoveAt(i);
i -= 1;
myList.RemoveAt(i);
}
Resizing lists and arrays is an expensive operation. Would you consider a custom data structure for your needs with convinient interface and optimized underlying structure? So every tick you will only increment and integer value representing offset:
class Data
{
const int Step = 2;
List<int[]> data;
List<int> cursors;
public Data()
{
data = new List<int[]>();
}
public void AddArray(int[] array)
{
data.Add(array);
cursors.Add(array.Length);
// or cursors.Add(0), depending on your needs
}
public void Tick()
{
for (int i = 0; i < cursors.Count; i++)
{
cursors[i] -= Step;
// or cursors[i] += Step, depending on your needs
}
}
public IEnumerable<int> GetValuesAtIndex(int index)
{
for (int i = 0, i < data[index].Length; i++)
{
if (i > cursors[index]) // or i < cursors[index]
{
yield return data[index][i];
}
}
}
}
I want help with getting the subsets of an array in C#.
All other examples could not help me much.
I want to get all the subsets of a particular size of an array.
for example if input array is {1,2,3,4} and i want all subsets of size 3,
all the unique subsets {1,2,3},{1,2,4},{2,3,4},{1,3,4} must be returned.
I am new to C# and any kind of help is much appreciated.
Check this article. This is described in detail with examples in all sorts of programming languages. I don't feel the need to copy others solutions so I will leave this as a link for you to choose from the MANY examples which should help you
Algorithm to return all combinations of k elements from n
Sounds suspiciously like a homework assignment....
Since I presume the size is variable, you'll want to use recursion. Something like:
static void Main(string[] args)
{
int[] originalList = new int[] { 1, 2, 3, 4 };
Stack<int> currentList = new Stack<int>();
List<int[]> listOfSubsets = new List<int[]>();
BuildListOfSubsets(originalList, listOfSubsets, 3, 0, currentList);
}
private static void BuildListOfSubsets(int[] originalList, List<int[]> listOfSubsets, int sizeOfSubsetList, int currentLevel, Stack<int> currentList)
{
if (currentList.Count == sizeOfSubsetList)
{
int[] copy = new int[sizeOfSubsetList];
currentList.CopyTo(copy, 0);
listOfSubsets.Add(copy);
}
else
for (int ix = currentLevel; ix < originalList.Length; ix++)
{
currentList.Push(originalList[ix]);
BuildListOfSubsets(originalList, listOfSubsets, sizeOfSubsetList, ix + 1, currentList);
currentList.Pop();
}
}
The result will be in the listOfSubsets list. See if you can find an optimization to leave the for loop early.
If you are looking for a LINQ solution, try this:
int[] originalList = { 1,2,1 };
var srcl = originalList.ToList();
List<List<int>> ans = Enumerable.Range(0, srcl.Count).SelectMany(start => Enumerable.Range(1, srcl.Count - start).Select(count => srcl.GetRange(start, count))).ToList();
If you are looking for a simpler solution, without Recursion, then this will help:
(This is a common solution to print all the subsets, to print specific scenarios, like having only subsets with length as 3, use the innermost loop)
class Program
{
static void Main(string[] args)
{
int[] arr = { 1, 2, 3, 4, 5 };
int length = arr.Length;
for (int start = 0; start < length; start++)
{
for (int end = start; end < length; end++)
{
Console.Write("{");
// printing the subset, use this to add any condition,
// like create a array and match the length, or anything
for (int print = start; print <= end; print++)
{
Console.Write(arr[print]);
}
Console.WriteLine("}");
}
}
}
}
I am trying to develop an optimization function that will determine which elements in list of doubles when added together will be less than a specified threshold values. The elements can be used multiple times.
For example if my list of elements is
{1,3,7,10}
and my threshold is 20 I would expect my result to be
1
3
7
10
10, 10
10, 7
10, 7, 3
10,7,1
10,7,1,1
10,7,1,1,1
7,7
7,7,3
7,7,1
7,7,1,1
7,7,1,1,1
...
I expect that the answer to this question will probably be a recursive call and probably could be found in a textbook, but I don't know how to properly phrase the question to find the answer. Help from this group of experts would be appreciated.
This program works, and seems to be the simplest solution. All results are sorted ascending.
private static final HashSet<ArrayList<Double>> lists =
new HashSet<ArrayList<Double>>(); // all of the combinations generated
private static final double[] elements = {10, 7, 3, 1};
public static void main(String[] args) {
combine(20, new ArrayList<Double>());
for (ArrayList<Double> set : lists) {
System.out.println(set);
}
}
private static void combine(final double limit, ArrayList<Double> stack) {
// iterates through the elements that fit in the threshold
for (double item : elements) {
if (item < limit) {
final ArrayList<Double> nextStack = new ArrayList<Double>(stack);
nextStack.add(item);
// a sort is necessary to let the HashSet de-dup properly
Collections.sort(nextStack);
lists.add(nextStack);
combine(limit - item, nextStack);
}
}
}
This type of combinatoric problem, though, generates many results. If you are more concerned with performance than code readability and simplicity, I can optimize further.
c#:
static void Main(string[] args)
{
Run();
}
static public void Run()
{
Combine(20, new List<Double>());
foreach (List<Double> set in lists)
{
Debug.Print(set.ToString());
}
}
private static HashSet<List<Double>> lists =
new HashSet<List<Double>>(); // all of the combinations generated
private static double[] elements = { 10, 7, 3, 1 };
private static void Combine(double limit, List<Double> stack)
{
// iterates through the elements that fit in the threshold
foreach (double item in elements)
{
if (item < limit)
{
List<Double> nextStack = new List<Double>(stack);
nextStack.Add(item);
// a sort is necessary to let the HashSet de-dup properly
nextStack.Sort();
lists.Add(nextStack);
Combine(limit - item, nextStack);
}
}
}
I'm not sure if the Sort() is needed for detecting correctly duplicate entries but this code should work:
private List<int[]> CombinedElementsInArrayLessThanValue(int[] foo, int value)
{
List<int[]> list = new List<int[]>();
for (int i = 0; i < foo.Length; i++)
{
List<int> start = new List<int>();
start.Add(foo[i]);
start.Sort();
int[] clone = start.ToArray();
if (start.Sum() < value && !list.Contains(clone))
{
list.Add(clone);
CombinedElementsInArrayLessThanValue(foo, value, start, list);
}
}
return list;
}
private void CombinedElementsInArrayLessThanValue(int[] foo, int value, List<int> partial, List<int[]> accumulate_result)
{
for (int i = 0; i < foo.Length; i++)
{
List<int> clone = new List<int>(partial);
clone.Add(foo[i]);
clone.Sort();
int[] array = clone.ToArray();
if (clone.Sum() < value && !accumulate_result.Contains(array))
{
accumulate_result.Add(array);
CombinedElementsInArrayLessThanValue(foo, value, clone, accumulate_result);
}
}
}
Process one item in the list at a time, and let the recursion handle one item completely in order to shorten the "depth" of the recursion.
public static List<int[]> Combine(int[] elements, int maxValue)
{
LinkedList<int[]> result = new LinkedList<int[]>();
List<int> listElements = new List<int>(elements);
listElements.Sort();
Combine(listElements.ToArray(), maxValue, new int[0], result);
return result.ToList();
}
private static void Combine(int[] elements, int maxValue, int[] stack, LinkedList<int[]> result)
{
if(elements.Length > 0 && maxValue >= elements[0])
{
var newElements = elements.Skip(1).ToArray();
for (int i = maxValue / elements[0]; i > 0; i--)
{
result.AddLast(stack.Concat(Enumerable.Repeat(elements[0], i)).ToArray());
Combine(newElements, maxValue - i*elements[0], result.Last(), result);
}
Combine(newElements, maxValue, stack, result);
}
}