Creating matrix with `Array.new(n, Array.new)`
Follow the code:
@gameboard = Array.new(3, Array.new(3, " "))
@gameboard.map { |a| a.object_id }
# => [76584030, 76584030, 76584030]
means new(size=0, obj=nil)
method creates an array of size
, having the same ob
.
But new(size) {|index| block }
method works in a different way; it creates an array of size
, having different obs
.
See the code below:
@gameboard = Array.new(3) { Array.new(3, " ") }
@gameboard.map { |a| a.object_id }
# => [75510080, 75509920, 75509540]
The above is the same as your second code example:
@gameboard = [[" ", " ", " "], [" ", " ", " "], [" ", " ", " "]]
@gameboard.map { |a| a.object_id }
# => [80194090, 80193400, 80193080]
If you change or update the the value at index 1
of the first element array of @gameboard
, it wouldn't affect all other inner array elements.
@gameboard = Array.new(3) { Array.new(3, " ") }
@gameboard[0][1] = 2
@gameboard
# => [[" ", 2, " "], [" ", " ", " "], [" ", " ", " "]]
How do I declare a 2d array in C++ using new?
If your row length is a compile time constant, C++11 allows
auto arr2d = new int [nrows][CONSTANT];
See this answer. Compilers like gcc that allow variable-length arrays as an extension to C++ can use new
as shown here to get fully runtime-variable array dimension functionality like C99 allows, but portable ISO C++ is limited to only the first dimension being variable.
Another efficient option is to do the 2d indexing manually into a big 1d array, as another answer shows, allowing the same compiler optimizations as a real 2D array (e.g. proving or checking that arrays don't alias each other / overlap).
Otherwise, you can use an array of pointers to arrays to allow 2D syntax like contiguous 2D arrays, even though it's not an efficient single large allocation. You can initialize it using a loop, like this:
int** a = new int*[rowCount];
for(int i = 0; i < rowCount; ++i)
a[i] = new int[colCount];
The above, for colCount= 5
and rowCount = 4
, would produce the following:
Don't forget to delete
each row separately with a loop, before deleting the array of pointers. Example in another answer.
Making a matrix with numpy.array
Make it a list on the 4th line of your code. Also, correct your function as mentioned in the code below. Function call and function creation are two different things, so does the arguments you pass into it.
import numpy as np
def matrix_input(N): # Argument to function while creation is wrong, use N instead of 3.
matrix = []
for i in range(N):
a = list(np.array(input().split(),int)) # Make it a list here
matrix.append(a)
print(matrix)
output:
matrix_input(3)
1 1 1
1 1
1 1 1
[[1, 1, 1], [1, 1], [1, 1, 1]]
Alternative method for creating a Proper matrix :
import numpy as np
matrix_1 = np.matrix([[1,1,1],[1,1,0],[1,1,1]])
print(matrix_1)
Output:
[[1 1 1]
[1 1 0]
[1 1 1]]
Creating Matrix(array) where each element itself is a matrix
A sample creating function:
In [510]: def foo(astr,m,n):
...: alist = [astr+'%d%d'%(i,j) for i in range(m) for j in range(n)]
...: return np.array(alist).reshape(m,n)
In [511]: foo('A',2,2)
Out[511]:
array([['A00', 'A01'],
['A10', 'A11']], dtype='<U3')
A list of 4 such arrays:
In [512]: alist = [foo('A',2,2),foo('B',2,2),foo('C',2,2),foo('D',2,2)]
Various ways of stacking:
In [513]: np.stack(alist)
Out[513]:
array([[['A00', 'A01'],
['A10', 'A11']],
[['B00', 'B01'],
['B10', 'B11']],
[['C00', 'C01'],
['C10', 'C11']],
[['D00', 'D01'],
['D10', 'D11']]], dtype='<U3')
In [514]: np.stack(alist,2)
Out[514]:
array([[['A00', 'B00', 'C00', 'D00'],
['A01', 'B01', 'C01', 'D01']],
[['A10', 'B10', 'C10', 'D10'],
['A11', 'B11', 'C11', 'D11']]], dtype='<U3')
In [515]: _.shape
Out[515]: (2, 2, 4)
This can be reshaped in various ways:
In [516]: __.reshape(2,2,2,2)
Out[516]:
array([[[['A00', 'B00'],
['C00', 'D00']],
[['A01', 'B01'],
['C01', 'D01']]],
[[['A10', 'B10'],
['C10', 'D10']],
[['A11', 'B11'],
['C11', 'D11']]]], dtype='<U3')
In [517]: _.reshape(4,2,2)
Out[517]:
array([[['A00', 'B00'],
['C00', 'D00']],
[['A01', 'B01'],
['C01', 'D01']],
[['A10', 'B10'],
['C10', 'D10']],
[['A11', 'B11'],
['C11', 'D11']]], dtype='<U3')
Instead different axis, you can create one and transpose the axes to your heart's content.
How to build a matrix of strings in C
Keep the string object implementation and the matrix separated. The most simplistic string object would be something like:
typedef struct {
size_t length;
char* str;
} str_t;
Then we can create a 2D array of such strings:
str_t strings [rows][cols];
Or in case you need dynamic memory allocation, this is equivalent but allocated on the heap:
str_t (*strings)[cols] = malloc( sizeof(str_t[rows][cols]) );
...
free(strings);
Then populate the 2D array as you would have done with one made of int
. Except strings have to be assigned with strcpy
rather than the assignment operator =
. And in this case we also which to store the length.
Also, the sole benefit of using char* str
for the string rather than a fixed length array char str[30]
is that we can adjust the size to match the data being stored:
size_t length = strlen(some_items[i][j]);
strings[i][j].str = malloc(length + 1);
strcpy(strings[i][j].str, some_items[i][j]);
Full example:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main (void)
{
typedef struct {
size_t length;
char* str;
} str_t;
size_t rows = 5;
size_t cols = 2;
str_t (*strings)[cols] = malloc( sizeof(str_t[rows][cols]) );
const char* some_items[5][2] =
{
{"here", "are"},
{"some", "random"},
{"strings", "and"},
{"here", "are"},
{"some", "more"},
};
for(size_t i=0; i<rows; i++)
{
for(size_t j=0; j<cols; j++)
{
size_t length = strlen(some_items[i][j]);
strings[i][j].str = malloc(length + 1);
strcpy(strings[i][j].str, some_items[i][j]);
strings[i][j].length = length;
printf("%s ", strings[i][j].str);
}
printf("\n");
}
free(strings);
return 0;
}
fill 2d array with 1d array java
Based on your example, you want to use the values in the array to insert in line in the matrix.
First, let's build our matrix and array values :
int m = 3;
int n = 5;
float[][] mat = new float[m][n];
float[] array = {1,2,3,4};
Then, iterate the matrix to prepare the update :
for(int i = 0; i < m; i++){
for(int j = 0; j < n; j++){
// update here
}
}
So, what you want is to use the array to set the value, when you reach the end, you start over. There is two solution I see :
Using an index
We increment it but use the modulo to get back to "0" when we reach the length of the array.
int currentIndex = 0;
for(int i = 0; i < m; i++){
for(int j = 0; j < n; j++){
mat[i][j] = array[currentIndex];
currentIndex = (currentIndex + 1 ) % array.length;
}
}
Using the matrix coordinate
Or you can get the index by doing the sum of both index of the matrix then using the modulo again, this allow to update any value without a loop, (if needed)
for(int i = 0; i < m; i++){
for(int j = 0; j < n; j++){
mat[i][j] = array[(i+j)%array.length];
}
}
One problem with this solution, you will not get the correct output for a matrix where m + n > Integer.MAX_VALUE
simply because the sum will give a negative value, give an incorrect index.
Output
You can see the result using :
System.out.println(java.util.Arrays.deepToString(mat));
Both solution give :
[
[1.0, 2.0, 3.0, 4.0, 1.0],
[2.0, 3.0, 4.0, 1.0, 2.0],
[3.0, 4.0, 1.0, 2.0, 3.0]
]
Issue with creating a matrix in R
This was a change in R 4.0.0 -- see the second entry for that version in https://cran.r-project.org/doc/manuals/r-release/NEWS.html:
matrix objects now also inherit from class "array", so e.g., class(diag(1)) is c("matrix", "array"). This invalidates code incorrectly assuming that class(matrix_obj)) has length one.
S3 methods for class "array" are now dispatched for matrix objects.
Previously it was bad form to check that the class was equal to a particular value, now it doesn't work. You (or their authors) will need to fix the downstream tests. The test that works in both old and new versions is
if (inherits(matrix_obj, "matrix")) ...
Dimensions for two-dimensional array creation in Java seem backwards
An expression like new int[2][5]
will create an outer array of length 2, with each element referencing an array of length 5, so a total of 3 arrays are created. This is well-documented in the Java Language Specification, Example 15.10.2-2. Multi-Dimensional Array Creation:
The declaration:
float[][] matrix = new float[3][3];
is equivalent in behavior to:
float[][] matrix = new float[3][];
for (int d = 0; d < matrix.length; d++)
matrix[d] = new float[3];
It does not mean (int[2])[5]
, i.e. an array of 5 referencing arrays of 2.
Because of that, the expression to lookup values is evaluated left-to-right, e.g. x[2][5]
means (x[2])[5]
, i.e. in int[][] x
variable, lookup x[2]
, which is an int[]
, and in that array lookup value at index 5
.
int[][] x = new int[9][9];
// z = x[2][5]
int[] y = x[2];
int z = y[5];
Related Topics
How to Use Ruby to Colorize the Text Output to a Terminal
Rails Sessions Current Practices
Rails: What's a Good Way to Validate Links (Urls)
Ruby'S File.Open and the Need For F.Close
How Does Object_Id Assignment Work
Suppress Ruby Warnings When Running Specs
How to Have Methods Inside Methods
Mixing Keyword With Regular Arguments in Ruby
How to Validate a Date in Rails
String Concatenation Vs. Interpolation in Ruby
Difference Between Various Variables Scopes in Ruby