How to get surrounding information from a cell in a table - c#

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.

Related

Convert DataTable to Array C#

I have the following DataTable
ItemNumber Quantity Order
1 2 3
4 3 8
7 7 9
I would like to load first two columns into 2 dimensional array. If it is not possible, at least I would like to get first column into 1 dimension array.
Of course, I can write a loop, but I wonder if it is possible to avoid loops.
Regards,
You won't necessarily be able to avoid loops in the technical sense, but you could write something like this:
DataTable table = ...;
return table.Rows.Cast<DataRow>().Select(c => new[] { c[0], c[1] });
That's an array of arrays, rather than a multidimensional array. But from what I've seen multidimensional arrays seem to be phased out as standard practice in most applications. You might also want to parse each row in that Select to being some actual type.
If you leave this as an IEnumerable<>, it will not need to loop more than the once that you use it, but if you're reading at random points a lot (using the indexer, or what have you), you might want to append .ToArray(). That decision depends on how you're using it. As a general rule, it's nice to write code that doesn't depend on random access like that, since then you don't have to read from the DataTable more than once per record.

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.

What is the fast way of getting an index of an element in an array? [duplicate]

This question already has answers here:
How to find the index of an element in an array in Java?
(15 answers)
Closed 6 years ago.
I was asked this question in an interview. Although the interview was for dot net position, he asked me this question in context to java, because I had mentioned java also in my resume.
How to find the index of an element having value X in an array ?
I said iterating from the first element till last and checking whether the value is X would give the result. He asked about a method involving less number of iterations, I said using binary search but that is only possible for sorted array. I tried saying using IndexOf function in the Array class. But nothing from my side answered that question.
Is there any fast way of getting the index of an element having value X in an array ?
As long as there is no knowledge about the array (is it sorted? ascending or descending? etc etc), there is no way of finding an element without inspecting each one.
Also, that is exactly what indexOf does (when using lists).
How to find the index of an element having value X in an array ?
This would be fast:
int getXIndex(int x){
myArray[0] = x;
return 0;
}
A practical way of finding it faster is by parallel processing.
Just divide the array in N parts and assign every part to a thread that iterates through the elements of its part until value is found. N should preferably be the processor's number of cores.
If a binary search isn't possible (beacuse the array isn't sorted) and you don't have some kind of advanced search index, the only way I could think of that isn't O(n) is if the item's position in the array is a function of the item itself (like, if the array is [10, 20, 30, 40], the position of an element n is (n / 10) - 1).
Maybe he wants to test your knowledge about Java.
There is Utility Class called Arrays, this class contains various methods for manipulating arrays (such as sorting and searching)
http://download.oracle.com/javase/6/docs/api/java/util/Arrays.html
In 2 lines you can have a O(n * log n) result:
Arrays.sort(list); //O(n * log n)
Arrays.binarySearch(list, 88)); //O(log n)
Puneet - in .net its:
string[] testArray = {"fred", "bill"};
var indexOffset = Array.IndexOf(testArray, "fred");
[edit] - having read the question properly now, :) an alternative in linq would be:
string[] testArray = { "cat", "dog", "banana", "orange" };
int firstItem = testArray.Select((item, index) => new
{
ItemName = item,
Position = index
}).Where(i => i.ItemName == "banana")
.First()
.Position;
this of course would find the FIRST occurence of the string. subsequent duplicates would require additional logic. but then so would a looped approach.
jim
It's a question about data structures and algorithms (altough a very simple data structure). It goes beyond the language you are using.
If the array is ordered you can get O(log n) using binary search and a modified version of it for border cases (not using always (a+b)/2 as the pivot point, but it's a pretty sophisticated quirk).
If the array is not ordered then... good luck.
He can be asking you about what methods you have in order to find an item in Java. But anyway they're not faster. They can be olny simpler to use (than a for-each - compare - return).
There's another solution that's creating an auxiliary structure to do a faster search (like a hashmap) but, OF COURSE, it's more expensive to create it and use it once than to do a simple linear search.
Take a perfectly unsorted array, just a list of numbers in memory. All the machine can do is look at individual numbers in memory, and check if they are the right number. This is the "password cracker problem". There is no faster way than to search from the beginning until the correct value is hit.
Are you sure about the question? I have got a questions somewhat similar to your question.
Given a sorted array, there is one element "x" whose value is same as its index find the index of that element.
For example:
//0,1,2,3,4,5,6,7,8,9, 10
int a[10]={1,3,5,5,6,6,6,8,9,10,11};
at index 6 that value and index are same.
for this array a, answer should be 6.
This is not an answer, in case there was something missed in the original question this would clarify that.
If the only information you have is the fact that it's an unsorted array, with no reletionship between the index and value, and with no auxiliary data structures, then you have to potentially examine every element to see if it holds the information you want.
However, interviews are meant to separate the wheat from the chaff so it's important to realise that they want to see how you approach problems. Hence the idea is to ask questions to see if any more information is (or could be made) available, information that can make your search more efficient.
Questions like:
1/ Does the data change very often?
If not, then you can use an extra data structure.
For example, maintain a dirty flag which is initially true. When you want to find an item and it's true, build that extra structure (sorted array, tree, hash or whatever) which will greatly speed up searches, then set the dirty flag to false, then use that structure to find the item.
If you want to find an item and the dirty flag is false, just use the structure, no need to rebuild it.
Of course, any changes to the data should set the dirty flag to true so that the next search rebuilds the structure.
This will greatly speed up (through amortisation) queries for data that's read far more often than written.
In other words, the first search after a change will be relatively slow but subsequent searches can be much faster.
You'll probably want to wrap the array inside a class so that you can control the dirty flag correctly.
2/ Are we allowed to use a different data structure than a raw array?
This will be similar to the first point given above. If we modify the data structure from an array into an arbitrary class containing the array, you can still get all the advantages such as quick random access to each element.
But we gain the ability to update extra information within the data structure whenever the data changes.
So, rather than using a dirty flag and doing a large update on the next search, we can make small changes to the extra information whenever the array is changed.
This gets rid of the slow response of the first search after a change by amortising the cost across all changes (each change having a small cost).
3. How many items will typically be in the list?
This is actually more important than most people realise.
All talk of optimisation tends to be useless unless your data sets are relatively large and performance is actually important.
For example, if you have a 100-item array, it's quite acceptable to use even the brain-dead bubble sort since the difference in timings between that and the fastest sort you can find tend to be irrelevant (unless you need to do it thousands of times per second of course).
For this case, finding the first index for a given value, it's probably perfectly acceptable to do a sequential search as long as your array stays under a certain size.
The bottom line is that you're there to prove your worth, and the interviewer is (usually) there to guide you. Unless they're sadistic, they're quite happy for you to ask them questions to try an narrow down the scope of the problem.
Ask the questions (as you have for the possibility the data may be sorted. They should be impressed with your approach even if you can't come up with a solution.
In fact (and I've done this in the past), they may reject all your possibile approaches (no, it's not sorted, no, no other data structures are allowed, and so on) just to see how far you get.
And maybe, just maybe, like the Kobayashi Maru, it may not be about winning, it may be how you deal with failure :-)

Why use an Array of more than two dimensions?

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.

Categories