Array2D и зубчатые массивы в f#

Я написал этот код f# для создания зубчатого (непрямоугольного) массива.

open System

type MatrizIrregular() = 
  let irregular = Array2D.zeroCreate 5

  member This.Inicializar() =
    for f in 0 .. 4 do
      printf "Introduzcal el número de columnas de la matriz de la fila %d: " f
      let res = Console.ReadLine()
      let col = Int32.Parse(res)
      Array2D.set irregular f (col)
      for c in 0 .. col - 1 do
        printf "Introduzca el valor de la columna %d: " c
        let res2 = Console.ReadLine()
        Array2D.set irregular f c (Int32.Parse(res2))

  member This.Mostrar() = 
    for f in 0 .. 4 do
    for f in 0 .. irregular.[f,c].Lenght - 1 do
      printf "%d " irregular.[f,c]
      printf "\n" 

let matriz = MatrizIrregular()
matriz.Inicializar()
matriz.Mostrar()

Я получаю ошибки в строках 11,15

Ожидалось, что это выражение будет иметь тип 'a[,], но здесь имеет тип int -> 'b[,]

и на строках 19,20

Оператор expr.[idx] был использован для объекта неопределенного типа на основании информации, предшествующей этому программному пункту. Рассмотрите возможность добавления дополнительных ограничений типа.

Я хочу сделать что-то вроде этого java-кода в f #

import java.util.Scanner;
public class MatrizIrregular {
    public Scanner teclado = new Scanner(System.in);
public int[][] irregular;

public void inicializar(){
    irregular = new int[5][];
    for(int f=0;f<irregular.length;f++){
            System.out.print("Introduzca el numero de columnas del la fila de la matriz "+f+": ");
    int col = teclado.nextInt();
    irregular[f] = new int[col];
    for(int c =0; c<irregular[f].length;c++){
        System.out.print("Introduzca el elemento de la columna "+c+": ");
            irregular[f][c] = teclado.nextInt();
            }
        }
    }

public void mostrar(){
    for(int f=0;f<irregular.length;f++){
            for(int c=0;c<irregular[f].length;c++){
               System.out.print(irregular[f][c]+" ");
            }
            System.out.print("\n");
        }
}

public static void main(String[] ar){
     MatrizIrregular matriz = new MatrizIrregular();
     matriz.inicializar();
     matriz.mostrar();
}

}


person Dominuskernel    schedule 22.03.2014    source источник


Ответы (2)


2D-массив не является нерегулярным, поэтому, как и в java, вам нужно объявить array из array из ints. В F# это int array array, и zeroCreate должен знать, для какого типа он собирается инициализировать массив. Также будьте осторожны с отступами, ваши вложенные циклы for не имеют отступа должным образом.

open System

type MatrizIrregular() = 
  let irregular : int array array = Array.zeroCreate 5

  member This.Inicializar() =
    for f in 0 .. 4 do
      printf "Introduzcal el número de columnas de la matriz de la fila %d: " f
      let res = Console.ReadLine()
      let col = Int32.Parse(res)
      let cols : int array = Array.zeroCreate col
      for c in 0 .. col - 1 do
        printf "Introduzca el valor de la columna %d: " c
        let res2 = Console.ReadLine()
        Array.set cols c (Int32.Parse(res2))
      Array.set irregular f cols

  member This.Mostrar() = 
    for f in 0 .. 4 do
      for c in 0 .. (Array.length irregular.[f]) - 1 do
        printf "%d " irregular.[f].[c]
      printf "\n" 

let matriz = MatrizIrregular()
matriz.Inicializar()
matriz.Mostrar()

Не самый функциональный ответ, но это то, о чем просили.

person jbtule    schedule 22.03.2014

Вы не можете создавать зубчатые 2D-массивы, подобные этому. Array2D и тип [,] и может использоваться только для прямоугольных 2D-массивов.

Чтобы узнать, как работать с зубчатыми массивами, перейдите по этой ссылке.


Я хотел бы прокомментировать ваше использование Array2D.zeroCreate. Он имеет такой тип:

val it : (int -> int -> 'a [,])

Когда вы дали ему два целых числа, он даст вам массив. Если вы дадите ему только одно целое число:

let irregular = Array2D.zeroCreate 5
val irregular : (int -> '_a [,])     (* Also complains about generic types. *)

Вы получаете функцию, которая при задании отсутствующего второго измерения даст вам массив. Вы не получите массив с неопределенным вторым измерением.

(Может быть, попробовать поиграть с let f x y = x + y и f 1 в интерпретаторе; посмотреть, что это за типы, и попытаться применить f к одной или двум вещам.)

person Søren Debois    schedule 22.03.2014