Let's say I want to write a function to "unpack" (store or log, perhaps) a multidimensional array using nested loops. The concept is simple enough, provided I'm able to determine, in the case of a 3D array, the length, width and height of the array.
In Objective-C, is there some way to, after being passed a multidimensional array of unknown size as a method argument, determine what those dimension sizes are? Then it'd be a simple matter of using, as stated, nested for loops.
NSArray is inherently one dimensional, a vector if you like, and as noted by John it has a count property. To simulate a multidimensional array you could of course have a NSArray *rows that contains a number of NSAarray *columnElement and so forth. This is not really a multi diensional array and more like a tree type structure but you could sort of call it an array. But I do not think that is what you are asking.
I think you are thinking of a C style buffer of memory traversed by pointer references. This is also inherently a one dimensional structure as memeory adressing is one dimensional. In many cases such a buffer can be viewed as 2 or more dimensional in such way that you say every 50 bytes is a row, so position 0 is row 1 col 1, position 49 is row 1 col 50 and position 50 is row 2 col 1 etc.
In this case as it is you as the designer who have defined this interpretation of the buffer as a two-dimensional array there cannot be a way to derive the structure from the buffer alone. Either you have to store the arrangement of the buffer as metadata in other variables or impose some form of delimeter characters in the buffer, e.g. newline for new row. and comma for new column element or similar (but then it is no longer an array in my opinion it is a file format, here a csv file).
Related
One interview question which I couldn't answer and couldn't find any relevant answers online.
I know the arraylist retrieve the data in constant time based on the indexes.
Suppose in an arraylist, there are 10000 data and the element is at 5000th location(We are not given the location), we have to search for a particular value( for eg integer 3 which happens to be on the 5000th index), for searching the value, we will have to traverse through the arraylist to find the value and it would take linear time right??
Because if we are traversing through the arraylist to find the data, it would take linear time and not constant time.
In short I want to know the internal working of contains method in which I have to check for the particular value and I don't have the index. It will have to traverse through the array to check for the particular value and it would take O(n) time right?
Thanks in advance.
I hope this is what you want to know about search in ArrayList:
Arrays are laid sequentially in memory. This means, if it is an array of integers that uses 4 bytes each, and starts at memory address 1000, next element will be at 1004, and next at 1008, and so forth. Thus, if I want the element at position 20 in my array, the code in get() will have to compute:
1000 + 20 * 4 = 1080
to have the exact memory address of the element. Well, RAM memory got their name of Random Access Memory because they are built in such way that they have a hierarchy of hardware multiplexers that allow them to access any stored memory unit (byte?) in constant time, given the address.
Thus, two simple arithmetic operations and one access to RAM is said to be O(1). See link to original answer.
Let's say I have the following flatbuffer IDL file:
table Monster {
mana:short = 150;
inventory:[ubyte]; // Vector of scalars.
}
And that I want to serialize an array of 2 Monster objects in a buffer.
Apparently it is possible to create the following memory layout for the overall buffer while serializing the data:
ArrayOfUBytesForInventoryOfMonster1|ArrayOfUBytesForInventoryOfMonster2|Monster1Data|Monster2Data
Which means that now all the inventory fields lay in a contiguous memory location.
However is it possible to also do this on the mana field?
ie I want to serialize my objects with this memory representation:
ArrayOfUBytesForInventoryOfMonster1|ArrayOfUBytesForInventoryOfMonster2|Monster1ManaValue|Monster2ManaValue|Monster1Data|Monster2Data.
Which has the effect of transforming all the "mana" values into a raw array in memory.
Is it possible to do this with Flatbuffers? It seems that fields can be only be serialized after the start of the object itself
Neither will work in the way you indicated. Scalar fields like mana are always inline in the table, so will never be contiguous with similar fields. Even vectors like inventory are prefixed by a size field, so their elements are not contiguous, even though they can be adjacent since they are not inline.
If you want contiguous data, you'll explicitly have to write out a single vector of such values.
I'm starting to study the FITS format and I'm in the proccess of reading the Definition of FITS document.
I know that a FITS file can have one or more HDUs, the primary being the first one and the extensions being the following ones (if there is more than one HDU), I also know that for the extensions there is a mandatory keyword in the header (XTENSION) that let us know if the Data Unit is an Image, Binary Table or ASCII Table, but how can I know what is the Data Type (Image, Binary Table or ASCII Table) of the first HDU?
I don't understand why XTENSION isn't a mandatory keyword in the primary header.
The "type" of the PRIMARY HDU is essentially IMAGE in most cases. From v3.0 of the standard:
3.3.2. Primary data array
The primary data array, if present, shall consist of a single data
array with from 1 to 999 dimensions (as specified by the NAXIS
keyword defined in Sect. 4.4.1). The random groups convention
in the primary data array is a more complicated structure and
is discussed separately in Sect. 6. The entire array of data values
are represented by a continuous stream of bits starting with
the first bit of the first data block. Each data value shall consist
of a fixed number of bits that is determined by the value of
the BITPIX keyword (Sect. 4.4.1). Arrays of more than one dimension
shall consist of a sequence such that the index along
axis 1 varies most rapidly, that along axis 2 next most rapidly,
and those along subsequent axes progressively less rapidly, with that along axis m, where m is the value of NAXIS, varying least
rapidly. There is no space or any other special character between
the last value on a row or plane and the first value on the next
row or plane of a multi-dimensional array. Except for the location
of the first element, the array structure is independent of the
FITS block structure. This storage order is shown schematically
in Fig. 1 and is the same order as in multi-dimensional arrays in
the Fortran programming language (ISO 2004). The index count
along each axis shall begin with 1 and increment by 1 up to the
value of the NAXISn keyword (Sect. 4.4.1).
If the data array does not fill the final data block, the remainder
of the data block shall be filled by setting all bits to zero.
The individual data values shall be stored in big-endian byte order
such that the byte containing the most significant bits of the
value appears first in the FITS file, followed by the remaining
bytes, if any, in decreasing order of significance.
Though it isn't until later on (in section 7.1) that it makes this connection:
7.1. Image extension
The FITS image extension is nearly identical in structure to the
the primary HDU and is used to store an array of data. Multiple
image extensions can be used to store any number of arrays in a
single FITS file. The first keyword in an image extension shall
be XTENSION= ’IMAGE ’.
It isn't immediately apparent what it means by "nearly identical" here. I guess the only difference is that the PRIMARY HDU may also have the aformentioned "random groups" structure, whereas with IMAGE extension HDU's PCOUNT is always 0 and GCOUNT is always 1.
You'll only rarely see the "random groups" convention. This is sort of a precursor to the BINTABLE format. It was used traditionally in radio interferometry data, but hardly at all outside that.
The reason for all this is for backwards compatibility with older versions of FITS that predate even the existence of extension HDUs. Many FITS-based formats don't put any data in the PRIMARY HDU and use the primary header only for metadata keywords that pertain to the entire file (e.g. most HST data).
I have an understanding about how multiple dimensional arrays work and how to use them except for one thing, In what situation would we need to use them and why?
Basically multi dimension arrays are used if you want to put arrays inside an array.
Say you got 10 students and each writes 3 tests. You can create an array like: arr_name[10][3]
So, calling arr_name[0][0] gives you the result of student 1 on lesson 1.
Calling arr_name[5][2] gives you the result of student 6 on test 3.
You can do this with a 30 position array, but the multi dimension is:
1) easier to understand
2) easier to debug.
Here are a couple examples of arrays in familiar situations.
You might imagine a 2 dimensional array is as a grid. So naturally it is useful when you're dealing with graphics. You might get a pixel from the screen by saying
pixel = screen[20][5] // get the pixel at the 20th row, 5th column
That could also be done with a 3 dimensional array to represent 3d space.
An array could act like a spreadsheet. Here the rows are customers, and the columns are name, email, and date of birth.
name = customers[0][0]
email = customers[0][1]
dateofbirth = customers[0][2]
Really there is a more fundamental pattern underlying this. Things have things have things... and so on. And in a sense you're right to wonder whether you need multidimensional arrays, because there are other ways to represent that same pattern. It's just there for convenience. You could alternatively
Have a single dimensional array and do some math to make it act multidimensional. If you indexed pixels one by one left to right top to bottom you would end up with a million or so elements. Divide by the width of the screen to get the row. The remainder is the column.
Use objects. Instead of using a multidimensional array in example 2 you could have a single dimensional array of Customer objects. Each Customer object would have the attributes name, email and dob.
So there's rarely one way to do something. Just choose the most clear way. With arrays you're accessing by number, with objects you're accessing by name.
Such solution comes as intuitive when you are faced with accessing a data element identified by a multidimensional vector. So if "which element" is defined by more than two "dimensions".
Good uses for 2D or Two D arrays might be:
Matrix Math i.e. rotation things in space on a plane and more.
Maps like game maps, top or side views for either actual graphics or descriptive data.
Spread Sheet like storage.
Multi Columns of display table data.
Kinds of Graphics work.
I know there could be much more, so maybe someone else can add to this list in their answers.
I need to keep 90x90 array data for iphone app. how can i keep this data? making an multi-dimensional array is a solution for this big table. or is there an other solution.
If the matrix is always 90x90, then you should just use C arrays.
Unless you have a special need for passing the matrix around, searching using predicates, or need some other feature of NSArray, then keep it simple.
You can:
Use a single Obj-C array containing 8100 elements and map your rows and columns onto the single index yourself: index = (row * 90) + column;
Create an Obj-C array containing 90 Obj-C arrays of 90 elements each.
Hash the row and column together into a single key that you can use with a dictionary. This could be a good solution especially if the array is sparse.
Use a single- or multi-dimensional C array, especially if the elements of the array are plain old C types, like int. If you're storing objects, it's better to go with an Obj-C container.
Iphone's have a built in database SQL-Lite. I'd look into that to see if it meets you needs