Checking the size of a list of arrays - c#

I have a list of string arrays:
List<string[]> parsedRaw = new List<string[]>();
This list contains lines read in from a CSV, where parsedRaw[3][5] would be the fifth item read off the third line of the CSV.
I know that I can find the number of rows in the list with:
parsedRaw.Count
But, given a row, how can I find the number of elements in that row? I'm trying to implement a test before entering a loop to read from the list, in order to avoid an "Index was outside the bounds of the array" error, where the loop is:
for (k = 0; k < nBytes; k++)
{
TheseBytes[k] = (byte)parsedRaw[i][StartInt + k];
}
I'm encountering the error on a row in the CSV that has fewer elements than the others. Before entering this loop, I need to check whether parsedRaw[i] has at least "StartInt + nBytes" elements.
Thanks for any suggestions!

A row is just a string array string[], so you can find its size using the Length property of the array.
foreach (string[] row in parsedRaw) {
for (int i = 0 ; i != row.Length ; i++) {
// do something with row[i]
}
}

The number of elements in a given row is determined by
parsedRaw[theRowIndex].Length
To fix your for loop you need to constrain the StartInt + k value to be less than the minimum of nBytes and the row length
for (k = 0; (k < nBytes) && (k + StartInt < parsedRaw[i].Length); k++)
{
TheseBytes[k] = (byte)parsedRaw[i][StartInt + k];
}

Try
List<string[]> parsedRaw = new List<string[]>();
parsedRaw.Add(new string[] {"test1", "test2"});
parsedRaw.Add(new string[] { "test1", "test2", "test3" });
int totalSize = 0;
for (int i = 0; i < parsedRaw.Count(); i++)
{
int rowSize = 0;
for (int k = 0; k < parsedRaw[i].Count(); k++)
{
rowSize += parsedRaw[i][k].Length;
}
totalSize += rowSize;
}

Related

Save the sum of each row of a matrix into an array

I have a matrix and I want to return an array containing as elements the sum of each row elements of the matrix.
int [] sum;
for (var i = 0; i < m; i++)
{
for (var j = 0; j < result.Pages[i].Actual.Count; j++)
{
sum[i] += result.Pages[i].Actual[j];
}
}
This is how I tried to do it but seems it is not working. Any ideas?
Use var m = a.GetLength(0); to get number of rows, and var n = a.GetLength(1); to get number of columns.
now that looks like a different story after you edit:
Actually the first problem would be a NullreferenceException because int[]sum is not initialized!
Anyway, so it seems that you have an array of arrays. In this case you would need the Length of the Pages array to save your results. The first loop iterates over it using i and will run until result.Pages.Length. For each i you have correctly implemented a second loop where you sum up the result.
int [] sum = new int[result.Pages.Length];
for (var i = 0; i < result.Pages.Length; i++)
{
for (var j = 0; j < result.Pages[i].Actual.Length; j++)
{
sum[i] += result.Pages[i].Actual[j];
}
}
If you collections are List's then you need to use Count instead of Length
The Linq solution would look like this:
int [] sum = result.Pages.Select(x=>x.Sum()).ToArray();
EDIT:
double? means that you have a nullable data type. This is different from the normal double. Furthermore the default value will be null That means that you need to initialize the value at position i in sum before you add up values, otherwise the result will be null.
double? [] sum = new double?[result.Pages.Length];
for (var i = 0; i < result.Pages.Length; i++)
{
sum[i] = 0;
for (var j = 0; j < result.Pages[i].Actual.Length; j++)
{
sum[i] += result.Pages[i].Actual[j];
}
}

Columns in Multidimensional Arrays c#

I have data in txt like this:
flea,0,0,1,0,0,0,0,0,0,1,0,0,6,0,0,0,6
frog,0,0,1,0,0,1,1,1,1,1,0,0,4,0,0,0,5
frog,0,0,1,0,0,1,1,1,1,1,1,0,4,0,0,0,5
I need to count the number of zeros in a chosen column, for example in the first column there are 3 zeros.
Here is my code so far:
//data patch
string[] tekst = File.ReadAllLines(#"C:\zoo.txt");
//full of array
string[] tablica = tekst;
for(int s=0;s<tablica.Length;s++)
{
Console.WriteLine(tablica[s]);
}
//----------------Show all of array---------------------------//
//----------------Giv a number of column-----------------////
Console.WriteLine("Podaj kolumne");
int a = Convert.ToInt32(Console.ReadLine());
//Console.WriteLine("Podaj wiersz");
//int b = Convert.ToInt32(Console.ReadLine());
int n = tablica.Length;
int m = tablica[a].Split(',').Length;
string[,] liczby = new string[n, m];
for (int j = 0; j < n; j++)
{
int suma = 0;
for (int i = 0; i < m; i++)
{
//somethink should be here
}
}
Any ideas for solving this?
try:
//data patch
string[] tekst = File.ReadAllLines(#"C:\zoo.txt");
//full of array - you allready have a string[], no need for a new one
//string[] tablica = tekst;
for(int s=0;s<tekst.Length;s++)
{
Console.WriteLine(tekst[s]);
}
//----------------Show all of array---------------------------//
//----------------Giv a number of column-----------------////
// try to use names with some meaning for variables, for example instead of "a" use "column" for the column
Console.WriteLine("Podaj kolumne");
int column = Convert.ToInt32(Console.ReadLine());
// your result for zeros in a given column
int suma = 0;
// for each line in your string[]
foreach ( string line in tekst )
{
// get the line separated by comas
string[] lineColumns = line.Split(',');
// check if that column is a zero, remember index is base 0
if ( lineColumns[column-1] == "0" )
suma++;
}
Console.WriteLine(suma);
EDIT: Just make sure to validate that the column they ask for, really exist in your array, AND if you do not consider the first column as the one with the name, adjust this part
lineColumns[column] // instead of lineColumns[column-1]

How can I fill a 2d array recursively?

I have a string filled with 9 numbers. I want to fill a 3x3 array with the numbers. I've managed to do it using a foreach and 2 for loops, but I feel this is quite messy. How can I modify my code to recursively enter the values into the array? This is my code currently:
int[,] matrix = new int[3, 3];
if(key.Length < 9 || key.Length > 9)
{
keyfield.GetComponent<InputField>().text = " Key Not Valid";
}
else
{
foreach(char c in key)
{
for (int k = 0; k < 3; k++)
{
for (int j = 0; j < 3; j++)
{
matrix[j, k] = c - 0;
}
}
}
}
Note, I'm working with Unity.
Well, just iterate over the chars in your key and assign them to the array, one field at a time. It's just a matter of calculating the correct columns and rows:
for (int i = 0; i < 9; ++i)
{
int row = i / 3;
int col = i % 3;
matrix[row, col] = (int)key[i];
}
Also note that neither the code in your question nor the code in my answer solves the problem in a recursive way. Recursion is given when a method calls itself directly or indirectly, which is not required to solve this particular problem.

What is the most efficient way to find the largest element in a matrix along with position? Also, the largest element in each column with position

I have written the following code but it looks to be far from efficient.
//Find largest in tempRankingData
int largestIntempRankingData = tempRankingData[0, 0];
for (int i = 0; i < count; i++)
{
for (int j = 0; j < count; j++)
{
if (tempRankingData[i, j] > largestIntempRankingData)
{
largestIntempRankingData = tempRankingData[i, j];
}
}
}
//Find position of largest in tempRankingData
List<string> positionLargestIntempRankingData = new List<string>();
for (int i = 0; i < count; i++)
{
for (int j = 0; j < count; j++)
{
if (tempRankingData[i, j] == largestIntempRankingData)
{
positionLargestIntempRankingData.Add(i + "," + j);
}
}
}
//Find largest in each column
int largestInColumn = 0;
List<string> positionOfLargestInColumn = new List<string>();
Dictionary<int, List<string>> position = new Dictionary<int, List<string>>();
for (int i = 0; i < count; i++)
{
largestInColumn = tempRankingData[0, i];
positionOfLargestInColumn = new List<string>();
for (int j = 0; j < count; j++)
{
if (tempRankingData[j, i] > largestInColumn)
{
largestInColumn = tempRankingData[j, i];
}
}
for (int j = 0; j < count; j++)
{
if (tempRankingData[j, i] == largestInColumn)
{
positionOfLargestInColumn.Add(j + "," + i);
}
}
position.Add(i, positionOfLargestInColumn);
}
So, I wanted to check about the most efficient way to do this.
Whilst you're finding the largest in each column, you could also be finding the largest overall. You can also capture the positions as you go:
//Find largest in each column
int largestInColumn = 0;
int largestOverall = int.MinValue;
List<string> positionOfLargestInColumn;
Dictionary<int, List<string>> position = new Dictionary<int, List<string>>();
List<string> positionLargestIntempRankingData = new List<string>();
for (int i = 0; i < count; i++)
{
largestInColumn = tempRankingData[0, i];
positionOfLargestInColumn = new List<string>();
positionOfLargestInColumn.Add("0," + i);
for (int j = 1; j < count; j++)
{
if (tempRankingData[j, i] > largestInColumn)
{
largestInColumn = tempRankingData[j, i];
positionOfLargestInColumn.Clear();
positionOfLargestInColumn.Add(j + "," + i);
}
else if(tempTankingData[j,i] == largestInColumn)
{
positionOfLargestInColumn.Add(j + "," + i);
}
}
position.Add(i, positionOfLargestInColumn);
if(largestInColumn > largestOverall)
{
positionLargestIntempRankingData.Clear();
positionLargestIntempRankingData.AddRange(positionOfLargestInColumn);
largestOverall = largestInColumn;
}
else if(largestInColumn == largestOverall)
{
positionLargestIntempRankingData.AddRange(positionOfLargestInColumn);
}
}
1). You can find largest element and its position in one method and retrieve.
Would be caller of your method concerned about position or actual value, is a matter of concrete case.
2) You can use `yield return' technique in your matrix search (for column based search), so do not compute all column's maximas and push them into the dictionary. Dictionaries are not that fast as arrays, if you can avoid use them, do that.
3) You can keep a matrix in single dimension, long array. Have [] access operator overload, to "emulate" matrix access. Why ? If finding maximum is something frequent you might need to do during program run, having one foreach loop is faster then having 2 nested once. In case of a big matrices, single array search can be easily parallelized among different cores.
If big matrices and/or frequent calls are not your concern, just simplify your code like in points (1), (2).
For your fist two itterations you could replace with this:
//Find largest in tempRankingData
int largestIntempRankingData = tempRankingData[0, 0];
List<KeyValuePair<double,string>> list = new List<KeyValuePair<double,string>>();
for (int i = 0; i < count; i++)
{
for (int j = 0; j < count; j++)
{
if (tempRankingData[i, j] > largestIntempRankingData)
{
largestIntempRankingData = tempRankingData[i, j];
list.Add(new KeyValuePair<double, string>(largestIntempRankingData, i + "," + j)); //Add the value and the position;
}
}
}
//This gives a list of strings in which hold the position of largestInItemRankingData example "3,3"
//Only positions where the key is equal to the largestIntempRankingData;
list.Where(w => w.Key == largestIntempRankingData).ToList().Select(s => s.Value).ToList();
You can get all these pieces of information in a single scan with a little fiddling around. Something like this (converting the rows and columns to a string is trivial and better done at the end anyway):
int? largestSoFar = null; // you could populate this with myMatrix[0,0]
// but it would fail if the matrix is empty
int largestCol = 0;
int largestRow = 0;
int?[] largestPerColumn = new int?[numOfCols]; // You could also populate this with
// the values from the first row but
// it would fail if there are no rows
int[] largestColumnRow = new int[numOfCols];
for (int i = 0; i < numOfRows; i++)
{
for (int j = 0; j < numOfCols; i++)
{
if (largestSoFar < myMatrix[i,j])
{
largestSoFar = myMatrix[i,j];
largestCol = j;
largestRow = i;
}
if (largestPerColumn[j] < myMatrix[i,j])
{
largestPerColumn[j] = myMatix[i,j];
largestColumnRow[j] = i;
}
}
}
// largestSoFar is the biggest value in the whole matrix
// largestCol and largestRow is the column and row of the largest value in the matrix
// largestPerColumn[j] is the largest value in the jth column
// largestColumnRow[j] is the row of the largest value of the jth column
If you do need to capture all the "maxima" (for want of a better word, because that's not really what you are doing) in a column, you could just change the above code to something like this:
int? largestSoFar = null; // you could populate this with myMatrix[0,0]
// but it would fail if the matrix is empty
int largestCol = 0;
int largestRow = 0;
int?[] largestPerColumn = new int?[numOfCols]; // You could also populate this with
// the values from the first row but
// it would fail if there are no rows
List<int>[] largestColumnRow = new List<int>[numOfCols];
for (int i = 0; i < numOfRows; i++)
{
for (int j = 0; j < numOfCols; i++)
{
if (largestSoFar < myMatrix[i,j])
{
largestSoFar = myMatrix[i,j];
largestCol = j;
largestRow = i;
}
if (largestPerColumn[j] < myMatrix[i,j])
{
largestPerColumn[j] = myMatix[i,j];
largestColumnRow[j].Add(i);
}
}
}
// Now largestColumnRow[j] gives you a list of all the places where you found a larger
// value for the jth column

indexOutofRange BubbleSort when using inputbox

Its been bugging me for hours because it is always returning 0 at numbers[i] and I cant figure out the problem. code worked for a different program but I had to change it so it could have a custom array size and that's when everything went wrong.
any help would be great.
Thanks in advance.
int[] numbers = new int[Convert.ToInt16(TxtArray.Text)];
int j = 0;
for (j = numbers.Length; j >= 0; j--)
{
int i = 0;
for (i = 0; i <= j - 1; i++)
{
string NumbersInput = Microsoft.VisualBasic.Interaction.InputBox("Enter Numbers to be sorted",
"Numbers Input", "", -1, -1);
numbers[i] = Convert.ToInt16(NumbersInput);
//returns 0 in if statement
if (numbers[i] < numbers[i + 1])
{
int intTemp = 0;
intTemp = numbers[i];
numbers[i] = numbers[i + 1];
numbers[i + 1] = intTemp;
}
}
}
for (int i = 0; i < numbers.Length; i++)
{
LstNumbers.Items.Add(numbers[i]);
}
private void button1_Click(object sender, EventArgs e)
{
int sizeOfArrayInt = Convert.ToInt32(arraySize.Text);
int[] array = new int[sizeOfArrayInt];
string numbers = arrayValues.Text;
string[] numbersSplit = numbers.Split(',');
int count = 0;
foreach (string character in numbersSplit)
{
int value;
bool parse = Int32.TryParse(character, out value);
if (value != null)
{
array[count] = value;
}
count++;
}
array = this.SortArray(array);
foreach (int item in array)
{
this.listBox.Items.Add(item);
}
}
private int[] SortArray(int[] arrayToSort)
{
//int[] sortedArray = new int[arrayToSort.Length];
int count = arrayToSort.Length;
for (int j = count; j >= 0; j--)
{
int i = 0;
for (i = 0; i <= j - 2; i++)
{
if (arrayToSort[i] < arrayToSort[i + 1])
{
int intTemp = 0;
intTemp = arrayToSort[i];
arrayToSort[i] = arrayToSort[i + 1];
arrayToSort[i + 1] = intTemp;
}
}
}
return arrayToSort;
}
strong text
This I got to work as a Windows Form and the output displays in the list box as each array item or individual i iteration over the array. Of course there is no error checking. Hope that helps.
Setting aside the strangeness of how you are working with text boxes, your problem with throwing an exception would happen even without them because it lies here, in your inner loop:
for (i = 0; i <= j - 1; i++)
Suppose that numbers.Length == 2. This means that j == 2. So on the first time through the outer loop, you hit the inner loop with these conditions. The first time through, i == 0. You get to the if statement:
if (numbers[i] < numbers[i + 1])
numbers[0] exists, and numbers[1] exists, so this iteration goes through fine and i is incremented.
Now i == 1. Now the loop checks its boundary condition. i <= j - 1 == true, so the loop continues. Now when you hit that if statement, it tries to access numbers[i + 1], i.e., numbers[2], which does not exist, throwing an IndexOutOfRangeException.
Edit: Came back and realized that I left out the solution (to the exception, anyway). For the bubble sort to work, your inner loop's boundary condition should be i <= j - 2, because j's initial value is == numbers.Length, which is not zero-based, while array indexes are.
Second Edit: Note that just using a List won't actually solve this problem. You have to use the right boundary condition. Trying to access list[list.Count()] will throw an ArgumentOutOfRangeException. Just because a List will dynamically resize doesn't mean that it will somehow let you access items that don't exist. You should always take time to check your boundary conditions, no matter what data structure you use.

Categories

Resources