I am coding an algorithm and I am using arrays of custom data and if it looks a bit strange is that I am coding the algorithm for a futures trading platform and so they may have functions that don't look standard C#.
I'm trying to Resize my arrays because I need them resized every time a new value is found to be added and then I use the SetValue sometimes to replace the last value found when a better one is found again within the next 5 values after the last value was set.
Trouble is, when I debug it in Visual Studio, it stops at line after ArrayResize and when I hover over the LastLSwDMIpriceBar[k], it shows the k = 0, just as I expected it to be, as it would be the first element in the array of one, so what Index is then outside the bounds of the array?
The way I understand and hoped the code to work is this: when the conditions met are by setting LSwDMIbool to true, the array is resized from 0 to 1 element and the element with index [0] is then set as LastLSwDMIpriceBar[k]. Am I wrong about this?
Any help would be greatly appreciated.
private int k, l;
private int[] LastLSwDMIpriceBar;
LastLSwDMIpriceBar = new int [1];
.....
if (LSwDMIbool)
{
lastLSwDMIbar = CurrentBar - 2 - LowestBar(LSwDMI, 5);
LastLSwDMI[0] = DMI(Closes[2], Convert.ToInt32(DmiPeriod)).Values[0].GetValueAt(lastLSwDMIbar);
Array.Resize(ref LastLSwDMIpriceBar, l++);
LastLSwDMIpriceBar[k] = CurrentBar - LowestBar(Lows[2], 5);
k++;
LSwDMIprice[0] = Lows[2].GetValueAt(LastLSwDMIpriceBar[k]);
}
......
if(!LSwDMIbool)
{
for (int LastBar = CurrentBar - 1; IsFirstTickOfBar && LastBar <= lastLSwDMIbar + 5; LastBar++)
LastLSwDMIpriceBar.SetValue((CurrentBar - LowestBar(Lows[2], 5)), k);
}
You may find this helpful:
https://stackoverflow.com/a/24858/12343726
I believe you want ++l instead of l++ so that the new value of l is used when resizing the array. I suspect that l is zero the first time Array.Resize is called so the array is being resized to zero.
I'm trying to Resize my arrays because I need them resized every time a new value is found to be added
Don't use an array for this!
Instead, use a List<T>.
private int k, l;
private List<int> LastLSwDMIpriceBar = new List<int>();
.....
if (LSwDMIbool)
{
lastLSwDMIbar = CurrentBar - 2 - LowestBar(LSwDMI, 5);
LastLSwDMI[0] = DMI(Closes[2], Convert.ToInt32(DmiPeriod)).Values[0][lastLSwDMIbar];
var newValue = CurrentBar - LowestBar(Lows[2], 5);
LastLSwDMIpriceBar.Add(newValue);
k++;
LSwDMIprice[0] = Lows[2][newValue];
}
......
if(!LSwDMIbool)
{
for (int LastBar = CurrentBar - 1; IsFirstTickOfBar && LastBar <= lastLSwDMIbar + 5; LastBar++)
LastLSwDMIpriceBar[k] = CurrentBar - LowestBar(Lows[2], 5));
}
Related
So I'm having some trouble with a C# program that is meant to sum the 8 highness value from a list.
The program works by declaring a variable currenthigh, which stores a value from the gradelist. It then compares itself to the value abshigh to see if it is greater than the established highest value. If it is, it sets currenthigh as the new highest value.
Once the loop has run through the list and confirmed the highest value, it adds it to the uppertotal variable and uses the ejector variable to remove it from the list. The program then iterates, this time without the previous highest value. It iterates 8 times so that in the end the top 8 values are added to uppertotal.
Trouble is, the highest variable remains in the list, despite the code having instructions to delete it, so it just adds the highest value to itself 8 times.
int currenthigh = 0;
int abshigh = 0;
int ejector = 0;
int uppertotal = 0;
for (int g = 0; g < 8; g++)
{
for (int z = 0; z < gradelist.Count; z++)
{
Console.WriteLine("PASS STARTED");
currenthigh = Convert.ToInt32((gradelist[z]));
Console.WriteLine("currenthigh" + currenthigh);
if (currenthigh > abshigh)
{
abshigh = currenthigh;
ejector = z;
}
}
Console.WriteLine("ejector" + ejector);
uppertotal = uppertotal + currenthigh;
gradelist.RemoveAt(ejector);
Console.WriteLine("PASS COMPLETE");
Console.WriteLine("RESETING");
}
Note - gradelist is a list of integers containing at least 12 items at all time.
This happens because you do not remove the highest value from gradelist. Pay attention, you put Z in ejector, but Z is an index in gradelist and when you try to remove it, you remove nothing because there is no Z in gradelist as a member! Instead of
gradelist.RemoveAt(ejector);
you should do this:
gradelist.RemoveAt(gradelist[ejector]);
But I'd recommend you completely different approach. If you just want to get your uppertotal which is the sum of top 8 members in gradlist, use this simple trick:
uppertotal += gradelist.OrderByDescending(p => p).Take(8).Sum();
Your code is extremely big for the relatively simple task.
You can select the top X of a list as follows:
top_list = gradelist.OrderByDescending(i => i).Take(X)
When working with lists/collections System.Linq is your friend
This question already has answers here:
Most efficient way to randomly "sort" (Shuffle) a list of integers in C#
(13 answers)
Closed 5 years ago.
I need to create a random array of int with certain parameters.
int[] test = new int[80];
Random random = new Random();
I need to assign 1's and 0's, randomly to the array. I know how to do that.
test[position] = Random.Next(0,2);//obviously with a for loop
But I need to have exactly 20 1's, but they need to be randomly positioned in the array. I don't know how to make sure that the 1's are randomly positioned, AND that there are exactly 20 1's. The rest of the positions in the array would be assigned 0.
I think you need to turn your thinking around.
Consider:
var cnt = 20;
while (cnt > 0) {
var r = Random.Next(0, 80);
if (test[r] != 1) {
test[r] = 1;
cnt--;
}
}
Expanding explanation based on comments from CodeCaster. Rather than generate a random value to place in the array, this code generates and index to set. Since C# automatically initializes the test array to 0 these values are already set. So all you need is to add your 1 values. The code generates a random index, tests it to see if it isn't 1, if so it sets the array element and decrements a count (cnt). Once count reaches zero the loop terminates.
This won't properly function if you need more values than 0 and 1 that is true. Of course the questions explicitly stated that these were the needed values.
"This causes horrible runtime performance". What!? Can you produce any prove of that? There is a chance that the index generated will collide with an existing entry. This chance increases as more 1's are added. Worst case is there is a 19/80 (~23%) chance of collision.
If you know you need exactly 20 of one value, a better way to go about this is to pre-populate the array with the required values and then shuffle it.
Something like this should work:
int[] array = new int[80];
for (int i = 0; i < 80; i++)
{
int val = 0;
if (i < 20)
{
val = 1;
}
array[i] = val;
}
Random rnd = new Random();
int[] shuffledArray = array.OrderBy(x => rnd.Next()).ToArray();
You can do
for (int i = 0; i < 20; i++)
{
var rand = random.Next(0,80);
if (test[rand] == 1)
{
i--;
continue;
}
test[rand] = 1;
}
Remaining are automatically zero.
I have a 2-D array (with dimensions magnitudes n by 5), which I'm picturing in my head like this (each box is an element of the array):
(http://tr1.cbsistatic.com/hub/i/2015/05/07/b1ff8c33-f492-11e4-940f-14feb5cc3d2a/12039.jpg)
In this image, n is 3. I.e, n is the number of columns, 5 is the number of rows in my array.
I want to find an efficient way to iterate (i.e walk) through every path that leads from any cell in the left most column, to any cell in right most column, choosing one cell from every column in between.
It cannot be simply solved by n nested loops, because n is only determined at run time.
I think this means recursion is likely the best way forward, but can't picture how to begin theoretically.
Can you offer some advice as to how to cycle through every path. It seems simple enough and I can't tell what I'm doing wrong. Even just a theoretical explanation without any code will be very much appreciated.
I'm coding in C#, Visual Studio in case that helps.
UPDATE:: resolved using code below from http://www.introprogramming.info/english-intro-csharp-book/read-online/chapter-10-recursion/#_Toc362296468
static void NestedLoops(int currentLoop)
{
if (currentLoop == numberOfLoops)
{
return;
}
for (int counter=1; counter<=numberOfIterations; counter++)
{
loops[currentLoop] = counter;
NestedLoops(currentLoop + 1);
}
}
This is a factorial problem and so you might run quite quickly into memory or value limits issues.
Took some code from this SO post by Diego.
class Program
{
static void Main(string[] args)
{
int n = 5;
int r = 5;
var combinations = Math.Pow(r, n);
var list = new List<string>();
for (Int64 i = 1; i < combinations; i++)
{
var s = LongToBase(i);
var fill = n - s.Length;
list.Add(new String('0', fill) + s);
}
// list contains all your paths now
Console.ReadKey();
}
private static readonly char[] BaseChars = "01234".ToCharArray();
public static string LongToBase(long value)
{
long targetBase = BaseChars.Length;
char[] buffer = new char[Math.Max((int)Math.Ceiling(Math.Log(value + 1, targetBase)), 1)];
var i = (long)buffer.Length;
do
{
buffer[--i] = BaseChars[value % targetBase];
value = value / targetBase;
}
while (value > 0);
return new string(buffer);
}
}
list will contain a list of numbers expressed in base 5 which can be used to found out the path. for example "00123" means first cell, then first cell then second cell, then third cell and finall fourth cell.
Resolved:: see the code posted in the edited question above, and the link to a recursion tutorial, where it takes you through using recursion to simulate N nested, iterative loops.
I am using c# and I have the flowing problem:
I decelerated the height variable before for cycle ant it says do not exist in the cycle.
In this part of the code I want the program to store all of the 3rd element of the "data" array except the first, so if the "data" array looks like this: 1,2,3,4,5,6,7,8,9,10,11,12... I want to get: 6,9,12...
static int[] tall()
{
int[] data = database();//recalling an array filled with numbers
int j = 0;
int[] height;
for (int i = 6; i < data.Length; )
{
i = i + 3;
j++;
height[j] = data[i];//Use of unassigned local variable 'height'
}
return height;
}
The compiler tells you what the problem is. Unfortunately, it does not tell you how to fix it.
You need to assign height to an array of int, but first you need to figure out its length. You can compute the length by subtracting the index of the initial data point (i.e. 6) from the length, dividing the result by 3, and adding 1. This can be simplified to (length-3)/3:
int[] height = new int[(data.Length-3)/3];
This assumes that data.Length is at least 4, otherwise the count is going to be negative.
You should also move the adjustment of indexes to a point after the assignment, or better yet, to the header of the loop:
// Start i at 5, because array indexes are zero-based.
for (int i = 5; i < data.Length; i+=3, j++) {
height[j] = data[i];
}
Demo.
I have this assignment where I must delete a chosen element from an array, so I came up with this code:
strInput = Console.ReadLine();
for (int i = 0; i < intAmount; i++)
{
if (strItems[i] == strInput)
{
strItems[i] = null;
for (int x = 0; x < intAmount-i; x++)
{
i = i + 1;
strItems[i - 1] = strItems[i];
}
intAmount = intAmount - 1;
}
}
The problem is that, suppose I have an array [1,2,3,4,5,], and I want to delete 1. The output would be [2,3,4,5,5]. This also happens when I choose 2, but it does not happen when I choose any other number.
What am I doing wrong?
I'm assuming you are working with a basic array of strings:
var strItems = new string[] { "1", "2", "3", "4", "5" };
In .NET, that array is always going to be 5 elements long. In order to remove an element, you are going to have to copy the remaining elements to a new array and return it. Setting the value at a position to null does not remove it from the array.
Now, with things like LINQ this is very easy (not shown here), or you could cheat using the List<> collection and do this:
var list = new List<string>(strItems);
list.Remove("3");
strItems = list.ToArray();
But I don't think that's going to teach you anything.
The first step is to find the index of the element you wish to remove. You can use Array.IndexOf to help you out. Let's find the middle element, "3":
int removeIndex = Array.IndexOf(strItems, "3");
If the element was not found, it will return a -1, so check for that before doing anything.
if (removeIndex >= 0)
{
// continue...
}
Finally you have to copy the elements (except the one at the index we don't want) to a new array. So, altogether, you end up with something like this (commented for explanation):
string strInput = Console.ReadLine();
string[] strItems = new string[] { "1", "2", "3", "4", "5" };
int removeIndex = Array.IndexOf(strItems, strInput);
if (removeIndex >= 0)
{
// declare and define a new array one element shorter than the old array
string[] newStrItems = new string[strItems.Length - 1];
// loop from 0 to the length of the new array, with i being the position
// in the new array, and j being the position in the old array
for (int i = 0, j = 0; i < newStrItems.Length; i++, j++)
{
// if the index equals the one we want to remove, bump
// j up by one to "skip" the value in the original array
if (i == removeIndex)
{
j++;
}
// assign the good element from the original array to the
// new array at the appropriate position
newStrItems[i] = strItems[j];
}
// overwrite the old array with the new one
strItems = newStrItems;
}
And now strItems will be the new array, minus the value specified for removal.
Arrays in C# are of a fixed size - once initialized you can only modify items, but you cannot add or remove items. If you want to delete an item from a collection you have two options:
1.) Create a new array that has all members of the original array minus the one you want to remove.
2.) Use a collection type that is resizable and allows to add or remove items like List<T> (List<int> in your case). This is what you would do in the "real world" if your collection is not static.
In your specific implementation i think u miss a break; statement, you should go out from the outer loop when you finish the inner loop. The assignment to null is not useful at all.
If the list is just a list of numbers why are you using strings? use integers directly if it is the case.
Your exercise seems to ask something like this, if you need to remove only one element.
public bool MyDelete(int[] array, int value) // Easy to do for strings too.
{
bool found = false;
for (int i = 0; i < array.Length; ++i)
{
if (found)
{
array[i - 1] = array[i];
}
else if (array[i] == value)
{
found = true;
}
}
return found;
}
This function will returns true if it find the specified falue, false if not.
It will move all items as you describe in your example, but of course, it will not change the size of the array.
Arrays are fixed size.
You cannot change the size of an array, simply, the language don't allows that.
Arrays are, were and will be always fixed size!
To remove an item from an array you should do something this:
public static T[] RemoveAt<T>(T[] array, int index) // hope there are not bugs, wrote by scratch.
{
int count = array.Length - 1;
T[] result = new T[count];
if (index > 0)
Array.Copy(array, 0, result, 0, index - 1);
if (index < size)
Array.Copy(array, index + 1, result, index, size - index);
return result;
}
...
strItems = RemoveAt(strItems, index);
This function will create a new array that contains all elements except the one at the index you specify.
Now, why someone would do something like this instead of using a List or a Dictionary or wathever?
Use directly a List without using an array.
Can use Except method to filter the data
AllData = {10, 30, 20, 50}
FilterData = {30, 20}
Result = AllData.Except(​FilterData)
Result will be {10, 50}
Arrays are a fixed sized, you can't shorten their length without creating a new array. All you can do is store the length of valid elements in the array (ie. after you remove 1 the length is 4).
Also, I'm not sure if the order of elements in your array is important, but if it's not you could swap the first and last elements rather than moving every element after the one that's removed forward 1 position.
An alternative to using an array is using a collection such as an ArrayList which will take care of resizing, removing and keeping a count of the amount of items in it, plus a lot more.
However, since this is homework you might have to use arrays. Either keep track of the length with a variable, as opposed to using array.length, or create a new array each time you want to change the size. If you don't have to use arrays then look at the collections you can use in C#.