Create a two-dimensional array at runtime: Difference between revisions

From Rosetta Code
Content added Content deleted
No edit summary
No edit summary
Line 46: Line 46:


=={{header|C}}==
=={{header|C}}==
<C>
<lang c>
#include <stdio.h>
#include <stdio.h>


Line 60: Line 60:
return 0;
return 0;
}
}
</C>
</lang>


=={{header|C++}}==
=={{header|C++}}==

Revision as of 17:58, 3 February 2009

Task
Create a two-dimensional array at runtime
You are encouraged to solve this task according to the task description, using any language you may know.

Data Structure
This illustrates a data structure, a means of storing data within a program.

You may see other such structures in the Data Structures category.

Get two integers from the user, then create a two-dimensional array where the two dimensions have the sizes given by those numbers, and which can be accessed in the most natural way possible. Write some element of that array, and then output that element. Finally destroy the array if not done by the language itself.

Ada

<lang ada>

with Ada.Text_Io; use Ada.Text_Io;
with Ada.Float_Text_Io; use Ada.Float_Text_Io;
with Ada.Integer_Text_Io; use Ada.Integer_Text_Io;

procedure Two_Dimensional_Arrays is
   type Matrix_Type is array(Positive range <>, Positive range <>) of Float;
   Dim_1 : Positive;
   Dim_2 : Positive;
begin
   Get(Item => Dim_1);
   Get(Item => Dim_2);
   -- Create an inner block with the correctly sized array
   declare
      Matrix : Matrix_Type(1..Dim_1, 1..Dim_2);
   begin
      Matrix(1, Dim_2) := 3.14159;
      Put(Item => Matrix(1, Dim_2), Fore => 1, Aft => 5, Exp => 0);
      New_Line;
   end;
   -- The variable Matrix is popped off the stack automatically
end Two_Dimensional_Arrays;

</lang>

ALGOL 68

main:(
  print("Input two positive whole numbers separated by space and press newline:");
  [read int,read int] INT array;
  array[1,1]:=42;
  print (array[1,1])
)

BASIC

Works with: QuickBasic version 4.5
CLS
INPUT a, b 'inputs need to be separated by commas
DIM array (1 TO a, 1 TO b)
array(1,1) = 42
PRINT array(1,1)
ERASE array

C

<lang c>

  1. include <stdio.h>

int main(int argc, char **argv) {

  int user1 = 0, user2 = 0;
  printf("Enter two integers.  Space delimited, please:  ");
  scanf("%d %d",&user1, &user2);
  int array[user1][user2];
  array[user1/2][user2/2] = user1 + user2;
  printf("array[%d][%d] is %d\n",user1/2,user2/2,array[user1/2][user2/2]);
  return 0;

} </lang>

C++

With language built-in facilities:

#include <iostream>
#include <istream>
#include <ostream>

int main()
{
  // read values
  int dim1, dim2;
  std::cin >> dim1 >> dim2;

  // create array
  double* array_data = new double[dim1*dim2];
  double** array = new double*[dim1];
  for (int i = 0; i < dim1; ++i)
    array[i] = array_data + dim2*i;

  // write element
  array[0][0] = 3.5;

  // output element
  std::cout << array[0][0] << std::endl;

  // get rid of array
  delete[] array;
  delete[] array_data;
}

Using std::vector from the standard library:

#include <iostream>
#include <istream>
#include <ostream>
#include <vector>

int main()
{
  // read values
  int dim1, dim2;
  std::cin >> dim1 >> dim2;

  // create array
  std::vector<std::vector<double> > array(dim1, std::vector<double>(dim2));

  // write element
  array[0][0] = 3.5;

  // output element
  std::cout << array[0][0] << std::endl;

  // the array is automatically freed at the end of main()
}

D

import std.stdio: writef, writefln, readln;
import std.conv: toInt;
import std.string: strip;

void main() {
    writef("Give me the numer of rows: ");
    int nrow = toInt(readln().strip());

    writef("Give me the numer of columns: ");
    int ncol = toInt(readln().strip());

    auto array = new float[][](nrow, ncol);
    array[0][0] = 3.5;
    writefln("The number at place [0 0] is ", array[0][0]);
}

Clean

import StdEnv

Start :: *World -> { {Real} }
Start world
    # (console, world) = stdio world
      (_, dim1, console) = freadi console
      (_, dim2, console) = freadi console
    = createArray dim1 (createArray dim2 1.0)

Common Lisp

(let ((d1 (read))
      (d2 (read)))
  (assert (and (typep d1 '(integer 1)) 
               (typep d2 '(integer 1))) 
          (d1 d2))
  (let ((array (make-array (list d1 d2) :initial-element nil))
        (p1 0)
        (p2 (floor d2 2)))
    (setf (aref array p1 p2) t)
    (print (aref array p1 p2))))

The assert will allow the user to reenter the dimensions if they are not positive integers.

Forth

: cell-matrix
  create ( width height "name" ) over ,  * cells allot
  does> ( x y -- addr ) dup cell+ >r  @ * + cells r> + ;

5 5 cell-matrix test

36 0 0 test !
0 0 test @ .  \ 36
 INTEGER DMATRIX my-matrix{{
 & my-matrix{{ 8 9 }}malloc
 
 8 my-matrix{{ 3 4 }} !
 my-matrix{{ 3 4 }} @ .
 
 & my-matrix{{ }}free

Fortran

In Fortran 90 and later

PROGRAM Example

  IMPLICIT NONE
  INTEGER :: rows, columns, errcheck
  INTEGER, ALLOCATABLE :: array(:,:)

  WRITE(*,*) "Enter number of rows"
  READ(*,*) rows
  WRITE(*,*) "Enter number of columns"
  READ(*,*) columns
 
  ALLOCATE (array(rows,columns), STAT=errcheck) ! STAT is optional and is used for error checking
 
  array(1,1) = 42
 
  WRITE(*,*) array(1,1)
 
  DEALLOCATE (array, STAT=errcheck)

END PROGRAM Example

Haskell

doit n m = a!(0,0) where a = array ((0,0),(n,m)) [((0,0),42)]

IDL

The following is only for demonstration. No real program should just assume that the user input is valid, integer, large enough etc.

read, x, prompt='Enter x size:'
read, y, prompt='Enter y size:'
d = fltarr(x,y) 

d[3,4] = 5.6
print,d[3,4]
;==> outputs  5.6

delvar, d

J

In J, all aspects of arrays are resolved through evaluation. Everything counts as being given at run time.

task=: 3 : 0
'init new' =. 0;1               NB. values for initialization and alteration
array =. y $ init               NB. create array of shape y
element =. < ? $ array          NB. pick an atom of the array at random
array =. new element } array    NB. amend that element to new value
element { array                 NB. return value of changed element
)

Passing two integers to task (as a list) satisfies the specifications for a two-dimensional array, but providing a longer list of integers accomplishes the same task on an array of as many dimensions as the count of integers given.

The type of the array is determined by the type of the values used in filling the array. E.g., alternate data types are obtained by substituting any of the following lines:

'init new' =. ' ';'x'           NB. literals
'init new' =. 1r2;2r3           NB. fractions
'init new' =. a: ; <<'Rosetta'  NB. boxes

Java

import java.util.Scanner;

public class twoDimArray {
  public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        
        int nbr1 = in.nextInt();
        int nbr2 = in.nextInt();
        
        double[][] array = new double[nbr1][nbr2];
        array[0][0] = 42.0;
        System.out.println("The number at place [0 0] is " + array[0][0]);
  }
}

Works with: UCB Logo
make "a2 mdarray [5 5]
mdsetitem [1 1] :a2 0     ; by default, arrays are indexed starting at 1
print mditem [1 1] :a2    ; 0

MAXScript

a = getKBValue prompt:"Enter first dimension:"
b = getKBValue prompt:"Enter second dimension:"
arr1 = #()
arr2 = #()
arr2[b] = undefined
for i in 1 to a do
(
     append arr1 (deepCopy arr2)
)
arr1[a][b] = 1
print arr1[a][b]

OCaml

let nbr1 = read_int ();;
let nbr2 = read_int ();;
let array = Array.make_matrix nbr1 nbr2 0.0;;
array.(0).(0) <- 3.5;;
print_float array.(0).(0); print_newline ();;

Pascal

Works with: GNU Pascal version 20060325, based on gcc-3.4.4

The following code is standard Extended Pascal (tested with gpc --extended-pascal):

program array2d(input, output);

type
 tArray2d(dim1, dim2: integer) = array[1 .. dim1, 1 .. dim2] of real;
 pArray2D = ^tArray2D;

var
 d1, d2: integer;
 data: pArray2D;

begin
 { read values }
 readln(d1, d2);

 { create array }
 new(data, d1, d2);

 { write element }
 data^[1,1] := 3.5;

 { output element }
 writeln(data^[1,1]);

 { get rid of array }
 dispose(data);
end.


Perl

Works with: Perl version 5.x

Predefining an array (or multi-dimension array) size is unnecessary, Perl dynamically resizes the array to meet the requirements. Of course I'm assuming that the user is entering array size 0 based.

sub make_array($ $){
  # get array sizes from provided params, but force numeric value
  my $x = ($_[0] =~ /^\d+$/) ? shift : 0;
  my $y = ($_[0] =~ /^\d+$/) ? shift : 0;
  
  # define array, then add multi-dimensional elements
  my @array;
  $array[0][0] = 'X '; # first by first element
  $array[5][7] = 'X ' if (5 <= $y and 7 <= $x); # sixth by eighth element, if the max size is big enough
  $array[12][15] = 'X ' if (12 <= $y and 15 <= $x); # thirteenth by sixteenth element, if the max size is big enough
  
  # loop through the elements expected to exist base on input, and display the elements contents in a grid
  foreach my $dy (0 .. $y){
    foreach my $dx (0 .. $x){
      (defined $array[$dy][$dx]) ? (print $array[$dy][$dx]) : (print '. ');
    }
    print "\n";
  }
}

Pop11

vars itemrep;
incharitem(charin) -> itemrep;
;;; Read sizes
vars n1 = itemrep(), n2= itemrep();
;;; Create 0 based array
vars ar = newarray([0 ^(n1 - 1) 0 ^(n2 - 1)], 0);
;;; Set element value
15 -> ar(0, 0);
;;; Print element value
ar(0,0) =>
;;; Make sure array is unreferenced
0 -> ar;

Pop11 is garbage collected so there is no need to destroy array. However, the array is live as long as variable ar references it. The last assignment makes sure that we loose all our references to the array turning it into garbage.

Pop11 arrays may have arbitrary lower bounds, since we are given only size we create 0 based array.

Python

Works with: Python version 2.5

<lang python> width = int(raw_input("Width of myarray: "))

 height = int(raw_input("Height of Array: "))
 myarray = [[0] * width for i in xrange(height)]
 myarray[0][0] = 3.5
 print myarray[0][0]</lang>

Note: Some people may instinctively try to write myarray as [[0] * width] * height, but the * operator creates n references to [[0] * width]

You can also use a two element tuple to index a dictionary like so:

<lang python> myarray = dict(((w,h), 0) for w in range(width) for h in range(height))

 myarray[(0,0)] = 3.5
 print myarray[(0,0)]</lang>

Ruby

 puts 'Enter width and height: '
 w=gets.to_i
 arr = Array.new(gets.to_i){Array.new(w)}
 arr[1][3] = 5
 p arr[1][3]


Toka

Toka has no direct support for 2D arrays, but they can be created and operated on in a manner similar to normal arrays using the following functions.

[ ( x y -- address )
  cells malloc >r
  dup cells >r
  [ r> r> r> 2dup >r >r swap malloc swap i swap array.put >r ] iterate
r> r> nip
] is 2D-array

[ ( a b address -- value )
  array.get array.get
] is 2D-get-element

[ ( value a b address -- )
  array.get array.put
] is 2D-put-element

And a short test:

5 5 2D-array >r             #! Create an array and save the pointer to it
10 2 3 r@ 2D-put-element    #! Set element 2,3 to 10
2 3 r@ 2D-get-element       #! Get the element at 2,3
r> drop                     #! Discard the pointer to the array