Функция имитации длины для получения длины списка - PullRequest
5 голосов
/ 24 октября 2011

Я пытаюсь смоделировать функцию длины в Mathematica v.8, чтобы получить длину списка. Учитывая это факты:

  • Пустой список представлен как {}
  • l = Rest [l] назначает l (который является списком) список l без первого элемента
  • а цикл пока

Это мой первый год использования mathematica, и я не слишком хорош в этом, поэтому, вероятно, что-то (или все) не так с тем, что я делаю:

Ej1[l_List] := Module[{i, v},
v = {{}};
i = 1;
While[l != v, l = Rest[l]; i++]
Return[i]
]

L = {а, б, в, д, е};

Когда я пытаюсь запустить его, цикл никогда не заканчивается, и он выдает мне следующие предупреждения:

Set::shape: Lists {a,b,c,d,e} and {b,c,d,e} are not the same shape. >>

Set::shape: Lists {a,b,c,d,e} and {b,c,d,e} are not the same shape. >>

Set::shape: Lists {a,b,c,d,e} and {b,c,d,e} are not the same shape. >>

General::stop: Further output of Set::shape will be suppressed during this calculation. >>

Ответы [ 6 ]

9 голосов
/ 24 октября 2011

Основные проблемы заключались в том, что вы пытались изменить входную переменную l, что невозможно, и у вас отсутствовала точка с запятой.

Ej1[l_List] := Module[{i = 0, v = {}, thisl},
  thisl = l;
  While[thisl != v, thisl = Rest[thisl]; i++];
  i]
6 голосов
/ 24 октября 2011

Вы также можете использовать NestWhile:

Clear[f];
f[l_List] := NestWhile[{Rest[#[[1]]], (#[[2]]) + 1} &, {l, 0}, 
   (#[[1]] != {}) &][[2]]

Этот код не ограничен $RecursionLimit или $IterationLimit, поэтому он также работает для очень больших списков. Недостатком является то, что это не очень эффективно, так как на каждом шаге итерации создается копия из оставшегося списка. Более быстрый способ подсчета элементов в списке - сделать что-то вроде

f2[l_List] := Fold[(# + 1) &, 0, l]

Для сравнения:

list=RandomReal[1,10000];
Timing[f[list]]
(* ==> {3.35747, 10000} *)

Timing[f2[list]]
(* ==> {0.000658, 10000} *)
4 голосов
/ 24 октября 2011
length[myList_List] := Module[{x = 0}, Scan[x++ &, myList]; x]

length[{a, b, c, d, e, f, g}]

==> 7
3 голосов
/ 25 октября 2011

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

myLength[{}] := 0
myLength[lis_List] := 1 + myLength[Rest[lis]]

In[47]:= myLength[{}]
Out[47]= 0

In[48]:= myLength[{1}]
Out[48]= 1

In[49]:= myLength[{1,2,3,4,5}]
Out[49]= 5
3 голосов
/ 24 октября 2011

Рекурсивно, используя If[]:

ClearAll[f];

f[l_List, i_: 0] := If[l != {}, f[Rest[l], i + 1], i];

f[{1,2}]
(*
-> 2
*)
1 голос
/ 24 октября 2011

То же, что и Велисарий, но без явного написания If:

ClearAll[ej2];
ej2[lst_ /; (lst == {}), i_: 0] := i
ej2[lst_, i_: 0] := ej2[Rest[lst], i + 1]

ej2[{1, 2, 3, 4, 5}]
(*
5
*)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...