two-dimensional array in C - c

I want to declare a two-dimensional array with two different data types in C language. First column and row must be character and they are the same and other elements must be integer. Then, I want to set the values of the elements based on the first column and row. For example:
A B C D
A 1 2 3 4
B 4 3 2 1 a[A][D] = 4
C 9 8 7 6
D 6 7 8 9
I cannot use a[0][3] = 4, because A and D are returned values of another function in my program and I don't know what there indeces are in the array a. If I use another array for my first row and search in it to find the index, it takes too much time and it is not good for the performance of my program.

In C, you cannot declare an array, two-dimensional or otherwise, such that some parts of the array are of one type and some are of another type. It is possible to cheat, and use the larger of the two data types for the entire array and then cast a whole bunch, but I do not recommend that idea for your problem, since it's more error-prone and gives up what little illusion of type safety C has.
If I use another array for my first row and search in it to find the index, it takes too much time and it is not good for the performance of my program.
Build a correct solution first, and then optimize if the correct solution isn't fast enough. If you have such a solution, please post it. If not, write it and then, if it isn't fast enough, ask another question on how to optimize it.

Related

Most efficient way to add a constant to a column of an array in LabVIEW?

I want to add a constant to the second column of an array.
I do this as shown below:
Where for illustration the values are as follows:
What is the most efficient way of adding a constant to an array column?
With a question about efficiency you should supply number. For anything lower than a 1000 x 1000 2D array I can't measure the difference. Usually it is best to simply test it.
Here the code for testing (same answer as crossrulz)
With a 10000 x 10000 array option 2 becomes about 10 times faster.
One comment unless you are in a very high demanding situation, readability is usually preferred over efficiency. In my opinion option 2 is more readable since it has no for loop and the constant is presented as a constant instead of an array.
But you can get more efficient than that by using the In Place Element structure. The image below shows two different ways to add 5 to a column. The second one avoids making a memory copy of the entire array. Indexing out a column of an array with Index Array and then modifying it requires a shift of underlying memory format, even though the array is going to be put back in the Replace Array Subset. The In Place Element structure gives enough context to LabVIEW for it to recognize that the Add can be done without data copies.
Index Array to get the second column, add your constant, and then Replace Array Subset to replace the second column.

Performing operations on items within an array - VBA

Sorry for this question, but I haven’t found the answer in any of the texts or sites I’ve been researching. I am trying to do something that seems like it should be easy, but I don’t understand enough about arrays to pull it off. I am trying to create an array that is some number of rows; let’s say 10 rows, by 3 columns, or Myarr(1 to 10 , 1 to 3) – and then populate it as follows in memory before pasting it back into an excel sheet. Here’s an example using very simple constants and functions, not the ones I really need to run.
The reason is that I've found that running my particular construct as set of Excel formulas and VBA custom functions is very slow and results in a recalculation problem that I have written about in this forum that is not yet solved, so I am trying a work-around that performs all operations in an array, and then just pastes the result back to Excel.
Column 1 is just the list of numbers 1 to 10
Column 2 is the value of the previous row of Column 2 plus a constant; “Constant”; this is the part I really am puzzled by
Column 3 is just a function of the value of this row of Column 2
For example:
Constant = 2
Function of Column 2 value is simply Column 2 value x 4
So the output should be
Value col 1, previous value col 2 + Constant, column 2 x 4 as follows:
1,2,8
2,4,16
3,6,24
4,8,32
5,10,40
6,12,48
7,14,56
8,16,64
9,18,72
10,20,80
I just cant find any instructions about how to refer backwards to previous row values in an array and use them to produce a new value for that same column,
The simplest example would be a 1 dimensional array making a list of numbers where you started with a number and each successive row was the previous value + 1.
I realize this is probably basic stuff, but I must be searching on the wrong term to find an answer so I turn to you. Thank you very much for your help.
Did you try something like
Myarr(i,2)=Myarr(i-1,2)+const

Determining the number of dimensions of an Ada array

Is it possible to determine the number of dimensions of an Ada array at runtime? For example, given the array type
type int_int_array is array (1 .. 3, 1 .. 4) of integer;
I'm looking for some attribute or combination of attributes I could use to determine that the array has 2 dimensions. The end goal is really to iterate over the entire array but all the ways of doing this I'm aware of only work if you know the dimension count ahead of time. The array's definition (including the number of dimensions) is going to be changing quite a bit during some current development and I'm hoping I don't have to update every piece of code that iterates over it every time.
Thanks!
You will always know it, so there is no need to ask at run-time.

Unexpected COUNTIF behavior when mixing number and text (EXCEL)

This question is about how Excel's COUNTIF function treats different data types when used as an array formula.
There are lots of good posts out there detailing how to use COUNTIF for tasks such as extracting unique values from a list, for example this post. I've managed to use examples from this and other posts to solve specific problems, but I'm trying to get a deeper understanding of array formulas in order to adapt my formulas to new needs.
I came across a peculiar behavior of COUNTIF. In general, Excel seems to treat strings as "larger than" numbers, so that the following examples are valid:
Cell Formula Returns
=1<2 TRUE
="a"<"b" TRUE
="a">"b" FALSE
=1<"b" TRUE
Now, suppose range A1:A6 contains the following data set:
1
2
3
A
B
C
For each cell in this set, I want to check how many of all the cells in the set that are smaller than or equal to that cell (a useful technique in more complex formulas). I enter the following array formula in range B1:B6:
{=COUNTIF($A$1:$A$6,"<="&$A$1:$A$6)} (CTRL + SHIFT + ENTER)
Based on the examples above comparing numbers and strings (also illustrated in Column D below), I would expect the output shown below to look like Column C. However, the array formula returns the result shown in Column B, which suggests that strings and number elements are counted separately by arraywise COUNTIF.
Column A Column B Column C Column D
1 1 1 A1<"C" = TRUE
2 2 2 A2<"C" = TRUE
3 3 3 A3<"C" = TRUE
A 1 4 A4<"C" = TRUE
B 2 5 A5<"C" = TRUE
C 3 6 A6<"C" = FALSE
So the question is how to produce the output in Column C? (EDIT: Just to clarify, I'm specifically looking for solutions that make use of COUNTIF's array properties.)
Any insight into why arraywise COUNTIF apparently behaves differently than the single-cell examples would also be much appreciated.
NOTE: I've translated the examples from a non-English version of Excel, so I apologize in advance for any typos.
PS. For a background, I ran into this problem when I tried to build a formula that would both extract unique values from a list with possible duplicates, and sort the unique values in numerical/alphabetical order. My current solution is to do this in two steps. One solution for how to do it in one step is proposed here.
First of all, excellently laid-out question, and on an interesting topic to boot.
I also raised an eyebrow when I first came across this behaviour of the COUNTIF(S)/SUMIF(S) functions. In their defence, I suppose we could construct situations in which we actually want strings and numerics to be considered separately.
In order to construct your required in-formula array, you will need something like:
MMULT(0+(TRANSPOSE($A$1:$A$6)<=$A$1:$A$6),ROW($A$1:$A$6)^0)
though note that the necessary transposition will mean that any set-up which includes this construction will require committing with CSE.
Regards
The different behavior can easily shown if you compare
=COUNTIF($A$1:$A$6,"<=A")
with
{=COUNT(IF($A$1:$A$6<="A",1))}
The first will only get text values from $A$1:$A$6 because it is clearly text to compare and it is faster ignoring other values then. =COUNTIF($A$1:$A$6,"<=3") will only get numeric values from $A$1:$A$6 because of the same reasons. Even if the criterion would be a concatination with a cell reference, then the concatination would be the first process and would lead either to "<=A" or "<=3". So it is ever clear what to compare, text or numbers.
The second first needs an array of the comparisons, then performs the IF, gets so an array of 1 or FALSE and counts then. But the "A" could also be a cell reference. So it is not clear what to compare at the beginning and the first array has to compare all values in $A$1:$A$6.
So COUNTIF(S) and SUMIF(S) cant be used comparing mixed text and numeric data.
The solution is shown already by XOR LX.
Btw.: with your PS. For a background you should consider the following solution from an German Excel site: http://www.excelformeln.de/formeln.html?welcher=236.
In your linked example:
Formula in B2 downwards
{=INDEX($A$2:$A$99,MATCH(LARGE(COUNTIF(A$2:A$99,">="&A$2:A$99)+99*ISNUMBER(A$2:A$99),ROWS($1:1)),COUNTIF(A$2:A$99,">="&A$2:A$99)+99*ISNUMBER(A$2:A$99),0))&""}
In this solution the COUNTIF compares with >= so the biggest text or number will count lowest and so get the lowest position. All number positions are added with 99. So they are ever greater than all possible text positions. So we have a descended sorted array. Then, using LARGE, the list is created from the highest to the lowest position.
I doubt that countif is the right function for what you want to achieve here.
try this (ctrl+shift+enter):
={SUM(IF(A1>=$A$1:$A$6,1,0))}
You will get
1
2
3
4
5
6
PS: CountIf is an basically an array function internally. Using it in another array function results into multiple array functions and their behaviour becomes complex. Array functions are best used with clear logical path.
As tested in Excel 2013, you will only get 1 in all results instead of what was proposed in Column B.
Currently, in the function provided by you, countif cannot figure out which cell to compare to which cell. Array functions expand ranges and then perform the provided action. Therefore, it is comparing each cell to same cell and resulting into 1.
Try this FormulaArray in B1 then copy till B6:
=SUM(($A$1:$A$6<=$A1)*1)

How can I master the idea of arrays?

I totally understand the purpose of arrays, yet I do not feel I have "mastered" them. Does anyone have some really good problems or readings involving arrays. I program in PHP and C++ so if there are examples with those languages that would be preferable but is not necessary.
Draw everything out on graph paper.
Memory is just little boxes, it's a lot clearer to see on paper with a few arrows than in some complex markup language
Define 'mastered'.
Does anyone have some really good problems or readings involving arrays.
Try array based
Linked-list implementation.
Implement stacks, queues, etc and then use stack(s) to emulate a queue etc
Heaps
A lot of people seem to struggle with the concept of arrays at first, particularly arrays of >2 dimensions.
It's a little too abstract. However, getting past that initial block just requires a concrete exploration of the mechanics. So, here's an example I've used a lot that shows the basic mechanics in a nerd-friendly way:
Concrete Example (in psuedocode)
Let's say you're building a role playing game and you want to keep track of your character's stats. You could use an array of integers like this:
Stats(0) could be strength
Stats(1) could be dexterity
Stats(2) could be intelligence
...And so on.
Now let's add a level of complexity. Maybe we want to introduce a potion of strength that increases strength by 5 for 10 turns. We could represent the stat side of that by making this into a 2-dimensional array:
Stats(0, 0) - this is my current strength.
Stats(0, 1) - this is my normal strength.
Stats(0, 2) - this is the number of turns until the strength potion wears off.
Stats(1, 0) - this is my current dexterity.
...And so on. You get the idea.
So I've added a 2nd dimension to hold details about the 1st dimension. What if I wanted our Stats array to handle statistics for more than one character? I could represent that by making this into a 3-dimensional array:
Stats(0, 0, 0) - character 0's current strength.
Stats(1, 1, 0) - character 1's current dexterity.
It would be even better to create some constants or enums to eliminate magic numbers from the code:
Const Strength = 0
Const Dexterity = 1
Const Intelligence = 2
Const CurrentValue = 0
Const NormalValue = 1
Const PotionTurns = 2
Then I could do:
Stats(1, Dexterity, NormalValue) = 5 'For character 1, set the normalvalue of dex to 5.
A few more thoughts about arrays... At least in the .Net world where I live, most of us don't have to use them in our day-to-day lives too often because they're slowly being relegated to underpinnings for more elaborate data structures like collections.
In fact, if I were to implement character stats, realistically I would not use arrays.
However, it's still important to get your head around them because they are rocket-fast and there are definitely cases where they're invaluable.
Try manually (no built in methods) sorting with arrays (bubblesort is a good one to get yourself going)
An array is a contiguous block of memory devoted to N items of the same type, where N is a fixed number indicating the number of items. In order to expand an array (as they are fixed in size), you can use the C function realloc(..). In C++, you can manually re-allocate an array by creating a new, larger array and copying the contents of the old array into the new one (an expensive operation).
Modern languages have options that supplant arrays (so as to overcome the inherent limitations of arrays). In C++, you can use the Standard Template Library (STL) for this purpose; the STL "vector" data type is a typical replacement for standard arrays in C++. Platform-dependent APIs like MFC have built-in constructs like the CArrayList for a richer array usage experience. ;-)
I'm going to try to explain the best i can arrays in their fundamental form.
Ok, so an array is basically a way to store data. For instance if you want a list of shopping items, we would use a one dimensional array:
[0] - "Bread"
[1] - "Milk"
[2] - "Eggs"
[3] - "Butter"
.
.
.
[n] - "Candy"
Each index 0,1,2,3,...n holds a specific data. The data as you can see are represented as Strings. Now i can't use something like :
[n+1] = 1000
because this will put an integer as index n+1, the compiler will tell you that it's no good and you need to fix that issue.
Moving on to matrices or 2-dimensional arrays. Take a piece of squared paper like the ones you use for math and draw a Cartesian system and some dots. Put the coordinates on different piece of paper and next to them put a 1. For example:
[0,0] = 1
[0,1] = 1
[2,3] = 1
What this means is that at index [0,0],[0,1],[2,3] i have 1. A representation would be like so:
Cartesian System in form of a matrices :
1) 2) 3)
1) 1 1 0
2) 0 0 1
3) 0 0 0
I used just simple arrays to illustrate what are they, for example if you want to go 3D the data structure for that would be a array of matrices aka a list which holds each Cartesian location at a specific height.
If we had 10 as height and the same dots as above it would be something like:
[10,0,0] - 1
[10,0,1] - 1
[10,2,3] - 1
If you want a way to master: grab a simple list of problems and try to implement them using arrays of any kind. There is no quick way to do it, just have patience and practice.
Alright, so a one-dimensional array is just a grouping of variables. Useful if you've got a lot of something, and you like to save time and space. Functionally,
element1:=5;
element2:=6;
element3:=7;
...
is the same as saying
element[1]:=5;
element[2]:=6;
element[3]:=7;
...
except now the computer knows what you're talking about and you can write something like:
for i:=1 to n do
element[i]:=element[i]+1;
Moving on, a two dimensional array is somewhat more complicated, but can be thought of as an array of arrays. So we could have something like this:
type
arrayA=array[1..50] of integer;
arrayB=array[1..50] of arrayA;
arrayB=array[1..50,1..50] of integer; //an equivalent declaration in Pascal to the above two
More specifically, a two-dimensional array is a table. So for example, if arrayA contains the grades of a student in 50 classes, then arrayB represents the grades of a bunch of students. So, arrayB[3,5] would be the grade of the third student on class number 3.
It's easy to expand the same logic to add another dimension to the array:
arrayC=array[1..50] of arrayB;
We could say that C represents a school, so arrayC[2,4,6] is the grade of the second schools fourth student in class 6.
Now, what are arrays used for? Storing groups of similar information, or information which'll need to be processed in bulk. In practice, though, you'll mostly be using a one-, at most two-, dimensional array. If you can imagine your data as a table, you'll almost definitely want an two-dimensional array, for example. How else would you represent a chess board, if you had to?
Three-dimensional arrays tend to be used less, but what if you had to save some sort of state for each of your table elements? Something like:
Table=array[1..50, 1..50, 0..1] of integer;
Then the third value is 1 if some condition is true for a given element, and 0 otherwise. Of course, a trivial example, but it's another way of understand three-dimensional arrays more easily.

Resources