I am trying to separate a group of values into bins for a histogram chart. There will be 10 bins in my histogram. To sort and count the number of cases in each bin, I am using an array. The error I am getting is The operand of an increment or decrement operator must be a variable, property or indexer. idx will give me the bin number that needs to be incremented. I am just unsure of the proper way to increment it. Thank you for the suggestions and comments.
int binsize = Convert.ToInt32(xrLabel101.Text) / 10;//Max divided by 10 to get the size of each bin
this.xrChart4.Series[0].Points.Clear();
int binCount = 10;
for (int i = 0; i < binCount; i++)
{
int m = Convert.ToInt32(xrLabel104.Text);//This is the number of loops needed
string[] binct = new string[10];
for (int k = 0; k < m; k++)
{
int idx = Convert.ToInt32(currentcolumnvalue) / binsize;
binct[idx]++;//I know this is wrong. Suggestions?
}
}
This is a simple: the type returned by your expression binct[idx] does not support numerical
operation like ++, + -...
To avoid this there are at last a couple of ways:
Operator overloading
Execute the same operation on other type then this and map the result to type you want.
What you can do is:
int binsize = Convert.ToInt32(xrLabel101.Text) / 10;//Max divided by 10 to get the size of each bin
this.xrChart4.Series[0].Points.Clear();
int binCount = 10;
for (int i = 0; i < binCount; i++)
{
int m = Convert.ToInt32(xrLabel104.Text);//This is the number of loops needed
int[] binct = new int[10];
for (int k = 0; k < m; k++)
{
int idx = Convert.ToInt32(currentcolumnvalue) / binsize;
binct[idx] = binct[idx] + 1;
}
}
You're trying to increment a string which makes no sense. Make your array an array of int instead
Related
I can't find how to implement jagged array using for loop. I have tried, however only the last smaller array becomes jagged arrays item.
string[][] allSheets = new string[size][];
This is how I declare. Below is how I get allSheets[number] element.
public string[] get_Sheets(int colNum)
{
CellReference[] cr = new CellReference[rows_.Length];
ISheet sheet = wb.GetSheetAt(0);
IRow[] row = new IRow[rows_.Length];
ICell[] cell = new ICell[rows_.Length];
string[] cellResult = new string[rows_.Length];
for (int i = 0; i < cr.Length; i++)
{
cr[i] = new CellReference(rows_[i] + colNum);
row[i] = sheet.GetRow(cr[i].Row);
cell[i] = row[i].GetCell(cr[i].Col);
cellResult[i] = cell[i].ToString();
}
return cellResult;
}
My two for loops looks something like this:
for (int ii = 0; ii < size; ii++)
{
for (int jj = 2; jj < size; jj++)
{
allSheets[ii] = get_Sheets(jj);
}
}
Notice how I started jj with 2. I had to since it's how excel files work..
You could clearly see that despite everything my every allSheets[ii] would become the last possible j number in for loop. I had tried to swap the loops so i starts first, however result is the same.
I think that you should use only one loop, because you are iterating only the main array here. You do not have to handle 2 dimensions on this level. The second loop (for the other dimension) is already inside get_Sheets.
for (int ii = 0; ii < size; ii++)
{
allSheets[ii] = get_Sheets(ii + 2);
}
Note that your 2 for-loops are not executing in parallel, they are nested. The inner loop is iterating size - 2 times per each iteration of the outer loop. This means that you are getting size * (size - 2) iterations. This not what you want.
An alternative way of doing this a lesser know feature of the for-loop. (This is probably what you intended to do with the 2 loops.)
for (int ii = 0, jj = 2; ii < size; ii++, jj++)
{
allSheets[ii] = get_Sheets(jj);
}
My program is supposed to generate 24 random numbers then add them all together and display them.
I've gotten them to do everything, except I can't get the first 24 numbers to add.
I tried moving the statement that collects the numbers but it didn't work.
Im not sure how to go forward.
int x = 0;
int number = 0;
int i = 0;
while (i < listBox1.Items.Count)
{
number += Convert.ToInt32(listBox1.Items[i++]);
}
totaltextBox.Text = Convert.ToString(number);
Random ran = new Random();
for(x = 0;x <= 23; x++)
{
listBox1.Items.Add(Convert.ToString(ran.Next(0,100)));
}
fileNumbers.Text = listBox1.Items.Count.ToString();
Just replace for and while loop. if not, it cant take listBox1.Items.Count.
int x = 0;
int number = 0;
int i = 0;
Random ran = new Random();
for (x = 0; x <= 23; x++)
{
listBox1.Items.Add(Convert.ToString(ran.Next(0, 100)));
}
while (i < listBox1.Items.Count)
{
number += Convert.ToInt32(listBox1.Items[i++]);
}
totaltextBox.Text = Convert.ToString(number);
fileNumbers.Text = listBox1.Items.Count.ToString();
As mentioned in the comments, you set your totaltextbox text too early. That way the listbox is empty when you try to accumulate the values.
Try this:
Random ran = new Random();
for (var x = 0; x <= 23; x++)
{
listBox1.Items.Add(Convert.ToString(ran.Next(0, 100)));
}
var number = listBox1.Items.Cast<string>().Select(Int32.Parse).Sum();
var count = listBox1.Items.Count;
I also replaced your while loop with a LINQ-Expression. Also note, that in c# you can declare for-variables like in my example code. No need to declare them for the whole method (unless you want to use them after the for loop for whatever reason).
The other answers are correct. However I will add my solution which avoids some back and forth conversions and reduces iterations:
Random ran = new Random();
int total = 0;
for (int x = 0; x <= 23; x++)
{
int rn = ran.Next(0, 100);
total += rn;
listBox1.Items.Add(rn.ToString());
}
totaltextBox.Text = total.ToString();
I am wanting to create multiple arrays of ints(in C#). However they all must have a unique number in the index, which no other array has that number in that index. So let me try show you what I mean:
int[] ints_array = new int[30];
for (int i = 0; i < ints_array.Count(); i++)
ints_array[i] = i;
//create a int array with 30 elems with each value increment by 1
List<int[]> arrayList = new List<int[]>();
for(int i = 0; i < ints_array.Count(); i++)
arrayList.Add(ints_array[i]. //somehow sort the array here randomly so it will be unique
So I am trying to get the arrayList have 30 int[] arrays and each is sorted so no array has the same int in the same index as another.
Example:
arrayList[0] = {5,2,3,4,1,6,7,8,20,21... etc }
arrayList[1] = {1,0,5,2,9,10,29,15,29... etc }
arrayList[2] = {0,28,4,7,29,23,22,17... etc }
So would this possible to sort the array in this unique kind of way? If you need anymore information just ask and ill fill you in :)
Wouldn't it be easier to create the arrays iteratively using an offset pattern?
What I mean is that if you created the first array using 1-30 where 1 is at index 0, the next array could repeat this using 2-30 where 2 is at index 0 and then wrap back to 1 and start counting forward again as soon as you go past 30. It would be an easy and repeatable way to make sure no array shared the same value/index pair.
You can do it like that:
List<int[]> arrayList = new List<int[]>();
Random rnd = new Random();
for (int i = 0; i < ints_array.Length; i++)
{
ints_array = ints_array.OrderBy(x => rnd.Next()).ToArray();
var isDuplicate = arrayList.Any(x => x.SequenceEqual(ints_array));
if (isDuplicate)
{
while (arrayList.Any(x => x.SequenceEqual(ints_array)))
{
ints_array = ints_array.OrderBy(x => rnd.Next()).ToArray();
}
}
arrayList.Add(ints_array);
}
I think, this wouldn't be so efficient for bigger numbers than 30.But in this case it shouldn't be a problem, in my machine it takes 7 milliseconds.
Jesse's idea would be best unless you needed a pure random pattern. In that case I would recommend generating a random number, checking all your previous arrays, and then placing it in an array if it did not match any other arrays current index. Otherwise, generate a new random number until you find a fresh one. Put that into a loop until all your arrays are filled.
Use a matrix (2D-array). It is easier to handle than a list of arrays. Create a random number generator. Make sure to initialize it only once, otherwise random number generator may create bad random numbers, if created in too short time intervals, since the slow PC-clock might not have ticked in between. (The actual time is used as seed value).
private static Random random = new Random();
Create two helper arrays with shuffeled indexes for rows and columns:
const int N = 30;
int[] col = CreateUniqueShuffledValues(N);
int[] row = CreateUniqueShuffledValues(N);
Then create and initialize the matrix by using the shuffeled row and column indexes:
// Create matrix
int[,] matrix = new int[N, N];
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
matrix[row[i], col[j]] = (i + j) % N;
}
}
The code uses these two helper methods:
private static int[] CreateUniqueShuffledValues(int n)
{
// Create and initialize array with indexes.
int[] array = new int[n];
for (int i = 0; i < n; i++) {
array[i] = i;
}
// Shuffel array using one variant of Fisher–Yates shuffle
// http://en.wikipedia.org/wiki/Fisher-Yates_shuffle#The_modern_algorithm
for (int i = 0; i < n; i++) {
int j = random.Next(i, n);
Swap(array, i, j);
}
return array;
}
private static void Swap(int[] array, int i, int j)
{
int temp = array[i];
array[i] = array[j];
array[j] = temp;
}
int size = 10;
// generate table (no duplicates in rows, no duplicates in columns)
// 0 1 2
// 1 2 0
// 2 0 1
int[,] table = new int[size, size];
for (int y = 0; y < size; y++)
for (int x = 0; x < size; x++)
table[y, x] = (y + x) % size;
// shuffle rows
Random rnd = new Random();
for (int i = 0; i < size; i++)
{
int y1 = rnd.Next(0, size);
int y2 = rnd.Next(0, size);
for (int x = 0; x < size; x++)
{
int tmp = table[y1, x];
table[y1, x] = table[y2, x];
table[y2, x] = tmp;
}
}
// shuffle columns
for (int i = 0; i < size; i++)
{
int x1 = rnd.Next(0, size);
int x2 = rnd.Next(0, size);
for (int y = 0; y < size; y++)
{
int tmp = table[y, x1];
table[y, x1] = table[y, x2];
table[y, x2] = tmp;
}
}
// sample output
for (int y = 0; y < size; y++)
{
for (int x = 0; x < size; x++)
Console.Write("{0} ", table[y, x]);
Console.WriteLine();
}
I'm trying to write a code that will fill array with unique numbers.
I could write the code separately for 1, 2 and 3 dimensional arrays but number of for cycles grow to "infinity".
this is the code for 2D array:
static void fillArray(int[,] array)
{
Random rand = new Random();
for (int i = 0; i < array.GetLength(0); i++)
{
for (int j = 0; j < array.GetLength(1); j++)
{
array[i, j] = rand.Next(1, 100);
for (int k = 0; k < j; k++)
if (array[i, k] == array[i, j])
j--;
}
}
print_info(array);
}
Is it possible to do something like this for n-dimensional arrays?
My approach is to start with a 1-d array of unique numbers, which you can shuffle, and then slot into appropriate places in your real array.
Here is the main function:
private static void Initialize(Array array)
{
var rank = array.Rank;
var dimensionLengths = new List<int>();
var totalSize = 1;
int[] arrayIndices = new int[rank];
for (var dimension = 0; dimension < rank; dimension++)
{
var upperBound = array.GetLength(dimension);
dimensionLengths.Add(upperBound);
totalSize *= upperBound;
}
var singleArray = new int[totalSize];
for (int i = 0; i < totalSize; i++) singleArray[i] = i;
singleArray = Shuffle(singleArray);
for (var i = 0; i < singleArray.Length; i++)
{
var remainingIndex = i;
for (var dimension = array.Rank - 1; dimension >= 0; dimension--)
{
arrayIndices[dimension] = remainingIndex%dimensionLengths[dimension];
remainingIndex /= dimensionLengths[dimension];
}
// Now, set the appropriate cell in your real array:
array.SetValue(singleArray[i], arrayIndices);
}
}
The key in this example is the array.SetValue(value, params int[] indices) function. By building up the correct list of indices, you can use this function to set an arbitrary cell in your array.
Here is the Shuffle function:
private static int[] Shuffle(int[] singleArray)
{
var random = new Random();
for (int i = singleArray.Length; i > 1; i--)
{
// Pick random element to swap.
int j = random.Next(i); // 0 <= j <= i-1
// Swap.
int tmp = singleArray[j];
singleArray[j] = singleArray[i - 1];
singleArray[i - 1] = tmp;
}
return singleArray;
}
And finally a demonstration of it in use:
var array1 = new int[2,3,5];
Initialize(array1);
var array2 = new int[2,2,3,4];
Initialize(array2);
My strategy assigns sequential numbers to the original 1-d array to ensure uniqueness, but you can adopt a different strategy for this as you see fit.
You can use Rank property to get the total number of dimentions in your array
To insert use SetValue method
In the first two for loops you are analysing the array properly (i and j go from the start to the end of the corresponding dimension). The problem comes in the most internal part where you introduce a "correction" which actually provokes an endless loop for j.
First iteration:
- First loop: i = 0;
- Second loop: j = 0;
- Third loop: j = -1
Second iteration
- First loop: i = 0;
- Second loop: j = 0;
- Third loop: j = -1
. etc., etc.
(I start my analysis in the moment when the internal loop is used for the first time. Also bear in mind that the exact behaviour cannot be predicted as far as random numbers are involved. But the idea is that you are making the j counter back over and over by following an arbitrary rule).
What you want to accomplish exactly? What is this last correction (the one provoking the endless loop) meant to do?
If the only thing you intend to do is checking the previously stored values, you have to rely on a different variable (j2, for example) which will not affect any of the loops above:
int j2 = j;
for (int k = 0; k < j2; k++)
if (array[i, k] == array[i, j2])
j2--;
Let's we have some integer short sorted arrays and we need to find intersection equal or more then predefined constant.
Here is code and it demonstrates what i want to do better then i can explain it in words.
The problem is SPEED. My code is working very slow. It takes about 15 sec on 2000 elements array(on my slow machine). Ofcourse i can implement my own intersection method and parallize code but it give a very limited improvement. Execution time growing as N^2 or something and already for 500k arrays it takes a very very long time. So how can i rewrite algorithm for better perfomance? I am not limited c# language maybe CPU or GPU has good special instructions for such job.
Example:
Input:
1,3,7,8
2,3,8,10
3,10,11,12,13,14
minSupport = 1
Output:
1 and 2: 2, 8
1 and 3: 3
2 and 3: 3, 10
var minSupport = 2;
var random = new Random(DateTime.Now.Millisecond);
// Numbers is each array are unique
var sortedArrays = Enumerable.Range(0,2000)
.Select(x => Enumerable.Range(0,30).Select(t => random.Next(1000)).Distinct()
.ToList()).ToList();
var result = new List<int[]>();
var resultIntersection = new List<List<int>>();
foreach (var array in sortedArrays)
{
array.Sort();
}
var sw = Stopwatch.StartNew();
//****MAIN PART*****//
for (int i = 0; i < sortedArrays.Count-1; i++)
{
for (int j = i+1; j < sortedArrays.Count; j++)
{
var intersect = sortedArrays[i].Intersect(sortedArrays[j]).ToList();
if(intersect.Count()>=minSupport)
{
result.Add( new []{i,j});
resultIntersection.Add(intersect);
}
}
}
//*****************//
sw.Stop();
Console.WriteLine(sw.Elapsed);
EDIT:
Now it takes about 9 sec vs 15 sec with old algorithm on 2000 elements. Well...ofcourse it is not fast enough.
//****MAIN PART*****//
// This number(max value which array can contains) is known
var maxValue = 1000;
var reverseIndexDict = new Dictionary<int,List<int>>();
for (int i = 0; i < maxValue; i++)
{
reverseIndexDict[i] = new List<int>();
}
for (int i = 0; i < sortedArrays.Count; i++)
{
for (int j = 0; j < sortedArrays[i].Count; j++)
{
reverseIndexDict[sortedArrays[i][j]].Add(i);
}
}
var tempArr = new List<int>();
for (int i = 0; i < sortedArrays.Count; i++)
{
tempArr.Clear();
for (int j = 0; j < sortedArrays[i].Count; j++)
{
tempArr.AddRange(reverseIndexDict[j]);
}
result.AddRange(tempArr.GroupBy(x => x).Where(x => x.Count()>=minSupport).Select(x => new[]{i,x.Key}).ToList());
}
result = result.Where(x => x[0]!=x[1]).ToList();
for (int i = 0; i < result.Count; i++)
{
resultIntersection.Add(sortedArrays[result[i][0]].Intersect(sortedArrays[result[i][1]]).ToList());
}
//*****************//
EDIT:
Some improvent.
//****MAIN PART*****//
// This number(max value which array can contains) is known
var maxValue = 1000;
var reverseIndexDict = new List<int>[maxValue];
for (int i = 0; i < maxValue; i++)
{
reverseIndexDict[i] = new List<int>();
}
for (int i = 0; i < sortedArrays.Count; i++)
{
for (int j = 0; j < sortedArrays[i].Count; j++)
{
reverseIndexDict[sortedArrays[i][j]].Add(i);
}
}
for (int i = 0; i < sortedArrays.Count; i++)
{
var tempArr = new Dictionary<int, List<int>>();
for (int j = 0; j < sortedArrays[i].Count; j++)
{
var sortedArraysij = sortedArrays[i][j];
for (int k = 0; k < reverseIndexDict[sortedArraysij].Count; k++)
{
if(!tempArr.ContainsKey(reverseIndexDict[sortedArraysij][k]))
{
tempArr[reverseIndexDict[sortedArraysij][k]] = new[]{sortedArraysij}.ToList();
}
else
{
tempArr[reverseIndexDict[sortedArraysij][k]].Add(sortedArrays[i][j]);
}
}
}
for (int j = 0; j < reverseIndexDict.Length; j++)
{
if(reverseIndexDict[j].Count>=minSupport)
{
result.Add(new[]{i,j});
resultIntersection.Add(reverseIndexDict[j]);
}
}
}
// and here we are filtering collections
//*****************//
There are two solutions:
Let us suppose you have 3 sorted arrays and you have to find the intersection between them. Traverse the first array and run a binary search on the rest of the two arrays for the element in first array. If the respective binary search on two list gave positive, then increment the counter of intersection.
result = List
for element in Array1:
status1 = binarySearch(element, Array2)
status2 = binarySearch(element, Array2)
status = status & status
if status == True:
count++
if count == MAX_INTERSECTION:
result.append(element)
break
Time Complexity : N * M * Log(N),
where,
N = Number of element in the array
M = Number of arrays
This solution works only if the number in the arrays are positive integers. Calculate the maximum and the minimum number out of the total elements in all the sorted arrays. As it is sorted, we can determine it by surveying the start and end element of the sorted arrays given. Let the greatest number be max and the lowest number be min. Create an array of size max - min and fill it with zero. Let us suppose you have 3 Arrays, now start traversing the first array and and go to the respective index and increment the value in the previously created array. As mentioned below:
element is 5 in Array 1, the New_array[5]+=1
Traverse all the three sorted list and perform the operation mentioned above. At the end traverse the new_array and look for value equal to 3, these indexes are the intersection result.
Time Complexity : O(N) + O(N) + .. = O(N)
Space Complexity : O(maximum_element - minimum_element)
where,
N = number of elements in the array.