Why use an Array of more than two dimensions? - c#

I am having trouble wrapping my head around the concept of an array with more than two dimensions, why you would need one, and how you would use it.
For example, how would you go about representing the following data in a multidimesional array?
Sex: Male | Female
Hair Color: Blond | Brunette | Black
Eye Color: Blue | Brown | Green | Hazel
Instinct is telling me that I should create an array as so:
string[,,] personAttributes = new string[2,3,4]
Please show how you would you fill up this array without a loop, and then with a loop. Any expansion on concepts and usage appreciated.

I'm not going to touch your personAttributes example because I don't think a 2D array is a good idea, let alone 3D (personally I would use an array of structs).
However, multidimensional arrays are very useful when you have some kind of orthogonal data space (i.e. you have several "choices" which are independent of each other).
For instance, if you're storing the response times of 20 people over 10 tests, where each test is repeated 3 times, and the whole thing is done once a month for 12 months, you might have an array like this:
double[,,,] responseTime = new double [12,20,10,3];

At the risk of sounding trite, you use arrays of three or more dimensions when you have three or more dimensions of data. So I guess you've having trouble envisioning three dimensions of data.
How about 3-D Tic Tac Toe? Any discrete representation of three-dimensional data fits in this category.
As for attributes like hair colour and so on, I wouldn't use a multi-dimensional array for this. Use objects with properties for that and enums (eg gender as an enum) as appropriate. That'll be much more readable than an N-dimensional array.

I'd say in your example a multi-dimensional array does not make sense. A class makes much more sense in your situation. Something like an enumeration stored as a member variable would be one way you could go:
enum HAIRCOLORS { BROWN = 0, BLOND = 1 ..... };
enum SEX { FEMALE = 0, MALE = 1 };
enum EYECOLORS { GREEN, BLUE, RED .... };
class PersonAttributes
{
public SEX sex = SEX.Female;
public HAIRCOLORS hairColor = HAIRCOLORS.Brown;
public EYECOLORS eyeColor = EYECOLORS.Green;
};
etc...

Thinking of an array as an address may be helpful.
123 Main St Springfield MA
Using this example, my first array would be an array of states. Each state would hold an array of cities, than cities holds streets and finally streets holds individual addresses.
With this array we could easily create a mailing list with every address. Just loop through each array and you would be able to print out every address or whatever you need to do.
Looking at your example, I don't see multidimensional arrays as a good fit. Unless the main thing you want to do with your arrays is find subsets of your data, like people that are female / blond / blue eyes. I would follow the suggestion to use a class. When you are looking at a person object in an array you are going to need to know the index values pointing to that person to figure out those characteristics.
Another example that might be useful is internationalization of messages in an application. The arrays could be language, state (error, warning, info), message id (an array message strings).
As for filling the arrays, just a few for loops could be used if the data was sorted. Otherwise parse the your input data to identify the appropriate indices.

To model data structures that have multiple dimensions. A chess board is a good example, 1 dimension is for rank, the other is for file.
Since the categories of data in your example (gender, eye color, hair color) have no relation with other categories, it seems that this would be best represented as 3 different arrays, each with 1 dimension.
If you do want to loop over a multi-dimension array, you simply use a loop within a loop:
for (int i = 0; i < array.length; i++) {
for (int j = 0; j < array[0].length; j++) {
string data = array[i][j];
// do something with the data
}
}

The easiest way of understanding a multidimensional array is to acknowledge every array as a one dimensional array. i.e
A 3 dimensional array is one dimensional array and every element in the one dimensional is a 2 dimensional array.
confusing........?
see this example
Here marks of a student named ABC in 2 exams conduct in the same year is displayed in a 2 dimensional array subject wise.
now when there is only one student it is easy to make a 2-D array but if you have to store marks of 3 students named ABC,DEF,GHI you can't do that in a 2D array.
for this I will create a one dimensional array in which I can store the data of each student individually.
simplified.....
I will store the 2D array carrying data of each student in a one dimensional array and now that 1D is a 3 dimensional Array
Here Class Array is the 3 dimensional Array
Similarly a 4 dimensional array is also a 1 dimensional array where each element of that array is 3 dimensional array.
if you increase the number of attribute the dimension of the array will also increase and hence we can say that a multi dimensional array is used to store unrelated / orthogonal data in an organized manner.

As the others wrote, your example doesn't well suited to a 3D array. Your example seem more appropriate to a 2D data structure. One index is persons, the other index is the characteristic: sex, hair color, eye color. Or you could use some other data structure...
A simple example of a 3D array: considering storing an (uncompressed) black & white digital movie. Each frame is a 2D image X vs Y with intensity values: image (i,j). Now to have multiple frames to have a movie you could store the movie as images (i, j, k), where k changes over time. If the movie was in color, you could add a fourth dimension to store three primary colors: cimages (i, j, q, k), q=1,2,3, and have a 4D array.

Related

Storing lots of Arrays into a List on every Loop

I have a question about storing lots of arrays into a list.
First, I initialize the array and list:
int[] arr = new int[9];
List<int[]> forkarr = new List<int[]>();
then I run through a lot of for loops and modify the array each time in order to produce all possible tic tac toe variations. While looping through all those variations, if the array is a possible board then I print it, and additionally if the array meets certain criteria for being a 'fork', then I will add it to the list like this:
if (ForkCheck.fork(arr)) { forkarr.Add(arr); Console.WriteLine("It's a Fork!");}
which also prints that message letting you know that particular array is a fork.
Now, when I am printing all of the arrays, the ones that are forks are printed properly and labeled as such.
However, when I go to print out all of the int[] elements of my list forkarr like so:
foreach (int[] arry in forkarr)
{
PrintGame.print(arry);//this is my method that prints the array
Console.WriteLine();
}
for some reason each array becomes an identical:
222
222
222
(I'm using 2 as 'X' and 1 as 'O' and 0 as 'empty' btw)
And it just prints that out over and over for all the forks.
So, something is going wrong when I am adding each modification of the array as a new element in the list I think, but I'm not sure why.
Thanks for any help.
Because you are modifying the same array and adding it to the list. Each time you done with one array array you need to create a new instance like this:
arr = new int[9];
This will create a new reference which will be independent from other arrays. And modifying it's elements wont affect the others.
For more information about value vs reference types you can refer to the question below:
What is the difference between a reference type and value type in c#?

How do I take data from a text file and split it into Arrays?

I have a project where I need to split data from a text file into an array or an "array of structure" as my professor said, and I'm pretty confused as to how to go about doing it.
Basically I have data arranged like this in a text file (doesn't have to be like this.. can be one thing per line):
PR214;MR43T;RBL8;14K22
PR223;R43;RJ6;14K24
PR224;R43N;RN4;14K30
PR246;R46N;RN8;14K32
PR247;R46TS;RBL17Y;14K33
PR248;R46TX;RBL12-6;14K35
PR324;S46;J11;14K38
PR326;SR46E;XEJ8;14K40
PR444;47L;H12;14K44
The numbers in the first column (PR...) represent a CCC number. The 2nd, 3rd, and 4th columns represent part numbers for three different companies (column 2 is one company, column 3 another, etc). The user will tell me the company, and the part number under the company by selecting a radio button and then typing in the part (ie company 3, and "RJ6") and then I'm supposed to give the customer the CCC number ("PR223").
I'm not asking you guys to do my homework for me but I have a hard time grasping arrays. Could you point me in the right as to how to go about doing this?
The other answers are correct. You read in each line from the text file and insert the values into a structure defined by your data. For each new line you need to use an instance of the structure, so you do that be making an array of structures which just a group of structures.
If you are struggling understanding arrays, you really need to work on that. Think of arrays like group of boxes. Let's start with 3 boxes in row. Each is the same size and can only hold what fits inside them. You can assigned type of item (data) to the boxes but all the boxes can only hold that type of item. The boxes are numbered from 0 to 2. In some languages, you can name the boxes (an associative array) but not in C# AFAIK. So that gives you a one dimensional array.
For two dimensonal array think of a Chess board. Do you know how to record a chess match? Chess notation uses A to H for the horizontal position and 1 to 8 for the vertical position. So the white queen starts in position D1. Now if I was programming a chess game I would use and 8x8 array just like the chess board. Of course the numbering on my array will be 0-7 across the top and 0-7 up the side. The Position of the white queen in my array would then be [3][0]. So placing data in a two dimensional array is like placing piece on a chess board. The game battleship is another example of a 2 dimensional array.
Adding dimensions to your array is like adding a new coordinate to your graph. You start with X, then you add Y and they add Z. So on and so forth.
You can use the ReadLine method of a StreamReader to read your file one line at a time. Then you can use the String.Split(char[]) method to get a string array of the values in each line. If you already know how to make structures you should be set.
If you look at each line of data there's a common delimiter between the 'columns', so you want to get each line split into four separate entities. As you work line by
line and get those four discrete elements should can assign each to the appropriate part of the structure. You'll of course have one 'structure' for each line, so an array of structure here at the end.

Calculating numbers from an external file from my project (Project Euler #13)

I'm trying to find multiple ways to solve Project Euler's problem #13. I've already got it solved two different ways, but what I am trying to do this time is to have my solution read from a text file that contains all of the numbers, from there it converts it and adds the column numbers farthest to the right. I also want to solve this problem in a way such that if we were to add new numbers to our list, the list can contain any amount of rows or columns, so it's length is not predefined (non array? I'm not sure if a jagged array would apply properly here since it can't be predefined).
So far I've got:
static void Main(string[] args)
{
List<int> sum = new List<int>();
string bigIntFile = #"C:\Users\Justin\Desktop\BigNumbers.txt";
string result;
StreamReader streamReader = new StreamReader(bigIntFile);
while ((result = streamReader.ReadLine()) != null)
{
for (int i = 0; i < result.Length; i++)
{
int converted = Convert.ToInt32(result.Substring(i, 1));
sum.Add(converted);
}
}
}
which reads the file and converts each character from the string to a single int. I'm trying to think how I can store that int in a collection that is like 2D array, but the collection needs to be versatile and store any # of rows / columns. Any ideas on how to store these digits other than just a basic list? Is there maybe a way I can set up a list so it's like a 2D array that is not predefined? Thanks in advance!
UPDATE: Also I don't want to use "BigInteger". That'd be a little too easy to read the line, convert the string to a BigInt, store it in a BigInt list and then sum up all the integers from there.
There is no resizable 2D collection built into the .NET framework. I'd just go with the "jagged arrays" type of data structure, just with lists:
List<List<int>>
You can also vary this pattern by using an array for each row:
List<int[]>
If you want to read the file a little simpler, here is how:
List<int[]> numbers =
File.EnumerateLines(path)
.Select(lineStr => lineStr.Select(#char => #char - '0').ToArray())
.ToList();
Far less code. You can reuse a lot of built-in stuff to do basic data transformations. That gives you less code to write and to maintain. It is more extensible and it is less prone to bugs.
If you want to select a column from this structure, do it like this:
int colIndex = ...;
int[] column = numbers.Select(row => row[index]).ToArray();
You can encapsulate this line into a helper method to remove noise from your main addition algorithm.
Note, that the efficiency of all those patterns is far less than a 2D array, but in your case it is good enough.
In this case you can simply use an 2D array, since you actually do know in advance its dimensions: 100 x 50.
If for some reason you want to solve a more general problem, you may indeed use a List of Lists, List>.
having said that, I wonder: are you actually trying to sum up all the numbers? if so, I would suggest another approach: consider just which section part of the 50 digit numbers actually influences the first digits of their sum. Hint: you don't need the entire number.

Convert ONE two-dimensional array into TWO one-dimensional arrays

You may feel weird about what I'm asking, but it's true, convert 1 two-dimensional array into 2 one-dimensional arrays.
That was what my teacher asked, and he said he would give a perfect point for whoever answers this (I think, tricky) question. I would happy to convert any 2 or n-dimensional array into one one-dimensional array. But he said 2, so I think there must be something to do with the second array. And, he didn't tell what type of array (int, String or object), so I assume it must be done with any kind of 2-dimensional array.
This is what I will answer him if no one here figure out what he wants: Convert into a 1-dimensional array, and leave the second null (or let it have no element). But I don't think it's a good answer for such a tricky question.
EDIT: Here is my teacher question, word-by-word (he just ask at the end of the session in voice, not in the textbook, as a bonus question(with... a nice bonus reward)): Given a 2-dimensional array, convert it into two 1-dimensional arrays.
I don't know if [][] in Java and C# considered 2-dimensional array, but C# does have [, ], which is 2-dimensional array. We are studying computer algorithm, with no target IDE or language.
EDIT2: I emailed him, and he refused to give additional information (he said it was unfair for others if I have more information than them), and he didn't give any comments about jagged array idea. The only useful thing in his reply: Let [][] be considered 2-dimensional array.
I'll bite. It's possible to flatten the entire two-dimensional array into the first of the two one-dimensional arrays by simply reading and writing consistently. I.e. store row 1 then row 2, etc. sequentially in that first array. Whenever you move to the next row, store the index of that next cell (of the first one dimensional array) in the second one-dimensional array, which would essentially become a row index table.
As Jon Skeet said above, this isn't a very well-specified question; perhaps with clarified information, we could better help you.
If I understand your question properly
it's easy m8...
it's only an algorithm question.. not a programming language specific...
you can do it like this:
one array holds the values
second array holds the keys
try to find a workaround in the second array to know what keys you've got..
For example:
array_1: v0 v1 v2 null v3 v4 v5 null v6 v7 v8 null
array_2: 0 1 2 newR 0 1 2 newR 0 1 2 newR
You can represent it in one array as well... but you need a specific algorithm to figure out when you are located on Y of the matrix.
The problem is that you won't access the data instantly from memory.. this is why there are bi-dimensional arrays
Another way:
keep in array 1 the values
keep in the second array the keys as string like in the following example:
array1: value1 value2 value3 value4 value5
array2: 0,0 0,1 1,0 1,1 2,0
there are a lot of algorithms but I don't think you will find better than bi-dimensional arrays...
When you look after them you will have less performance.. ofc.. unless you keep them in hashtables.. hashing 0,0 and added as key in a hashtable and add the specified value to that key. then you will look for key "0,0"...
Flatten the 2-d array in either row-major or column-major order, storing it in one of the 1-d arrays. Store the shape {n, m} of the array in the other 1-d integer array. Given the indices for an element in the 2-d array of values, you can use the shape to calculate the index in the 1-d array of values.
The two representations are isomorphic, and both allow looking up the values in constant time. It's also similar to how a 2-d array is represented in memory.
I guess you want to transform you 2-demension array (typed RelevantType[,]) into 2 arrays (typed SomeTypeA[] and SomeTypeB[]) without losing any information?
It's not very difficult:
Have the first array be of type RelevantType[], the second one of type int[], copy the content of your 2-dimensionnal array into the first one and its first indices into the second one, and you're done.

How to get surrounding information from a cell in a table

Background
I'm looking for hints / pointers on how to approach this. When I search for table or grid, I get the UI stuff which is not what I'm looking for.
I don't know if this sounds like homework, but it is not. This is for a map of crops and I need to determine the crops planted around a particular plot of land.
Problem
I have a table of information, its 6 rows by 6 columns, but it can be any size.
I need to find a box in that table, and then get the information from all of the boxes around it.
|-1-|-2-|-3-|-4-|-5-|-6-|
|-7-|-8-|-9-|-A-|-B-|-C-|
|-D-|-E-|-F-|-G-|-H-|-I-|
|-J-|-K-|-L-|-M-|-N-|-O-|
|-P-|-Q-|-R-|-S-|-T-|-U-|
|-V-|-W-|-X-|-Y-|-Z-|-0-|
So I need to be able to pick box M and get the information for F,G,H,N,T,S,R,L
Note, if box J was needed, it is okay to return blanks or nulls for the boxes on the left that doen't exist. It does not wrap around and get the boxes from the other side of the table.
My Idea
I guess I could start with an array of arrays.
private static string[][] tableData;
So when looking for box M, I would need to get the row (i) and column (j) index for M, then the surrounding cells are as "simple" as:
| i-1, j-1 | i-1, j | i-1, j+1 |
| i, j-1 | i, j | i, j+1 |
| i+1, j-1 | i+1, j | i+1, j+1 |
And when asked for box M, I could find box M's index, then get the prior "row" and then index -1, index, and index + 1. Do that for M's row -1, M's row and then M's row + 1.
Is that a fair and good way of doing this or are there better, perhaps already built classes that I should use?
So the question: is an array of arrays the best way to handle this problem, or is there a better way?
There is nothing built in that will simply let you get "surrounding" cells in the way you describe.
A two dimensional char (or string) array looks like a good match, as you have already posted.
You can write wrap this in a class that can return a 3*3 array containing the neighbors.
The data structure that you choose is going to depend highly on the exact problem characteristics. For example, if you only have data in a small fraction of the cells and you have a lot of cells (tens of thousands or millions), you would probably want to implement a sparse array. Otherwise you can use a multi-dimensional array or jagged array.
Jagged array (the one that you mentioned):
private static string[][] tableData;
Multi-dimensional array:
private static string[,] tableData;
If you're not dealing with square plots, you might consider a completely different data structure altogether.
As well although multi-dimensional arrays may be easier to work with, jagged arrays have better performance on the CLR.
Why are multi-dimensional arrays in .NET slower than normal arrays?
Your array manipulation algorithms might drive you to choose one data structure over another too. All this said, I would recommend encapsulating your data structure inside a class so that you can more easily switch representations if needed.
(And I wouldn't use a DataTable. That's a whole lot of overhead for features that you're not using.)
C# has:
private static string[,] tableData;
Otherwise I think you approach is the correct one. Make sure you remember to consider the edges of the table though.

Categories