Как вы сортируете и эффективно находите элементы в массиве ячеек (строк) в Octave? - PullRequest
17 голосов
/ 22 ноября 2011

Есть ли для этого встроенная функциональность?

Ответы [ 3 ]

31 голосов
/ 02 декабря 2012

GNU Octave ищет массив ячеек строк за линейное время O(n):

Другой ответ имеет cellidx, который амортизируется на октаву, он все еще выполняется, но говорят, что вместо него используется ismemberнапример:

%linear time string index search.
a = ["hello"; "unsorted"; "world"; "moobar"]
b = cellstr(a)
%b =
%{
%  [1,1] = hello
%  [2,1] = unsorted
%  [3,1] = world
%  [4,1] = moobar
%}
find(ismember(b, 'world'))   %returns 3

'world' находится в индексном интервале 3. Это дорогостоящая операция с линейным временем O (n) , потому что она должна проходить через все элементы, независимо от того,

Чтобы получить решение логарифмического времени O (log n) , ваш список должен быть предварительно отсортирован, а затем вы можете использовать двоичный поиск:

Если ваш массив ячеек уже отсортирован, вы можете выполнить O(log-n) наихудший случай:

function i = binsearch(array, val, low, high)
  %binary search algorithm for numerics, Usage:
  %myarray = [ 30, 40, 50.15 ];        %already sorted list
  %binsearch(myarray, 30,    1, 3)     %item 30 is in slot 1
  if ( high < low )
    i = 0;
  else
    mid = floor((low + high) / 2);
    if ( array(mid) > val )
      i = binsearch(array, val, low, mid-1);
    elseif ( array(mid) < val )
      i = binsearch(array, val, mid+1, high);
    else
      i = mid;
    endif
  endif
endfunction

function i = binsearch_str(array, val, low, high)
  % binary search for strings, usage:
  %myarray2 = [ "abc"; "def"; "ghi"];       #already sorted list
  %binsearch_str(myarray2, "abc", 1, 3)     #item abc is in slot 1
  if ( high < low )
    i = 0;
  else
    mid = floor((low + high) / 2);
    if ( mystrcmp(array(mid, [1:end]), val) == 1 )
      i = binsearch(array, val, low, mid-1);
    elseif ( mystrcmp(array(mid, [1:end]), val) == -1 )
      i = binsearch_str(array, val, mid+1, high);
    else
      i = mid;
    endif
  endif
endfunction
function ret = mystrcmp(a, b)
    %this function is just an octave string compare, it's exactly like 
    %strcmp(str1,str2) in C, or java.lang.String.compareTo(...) in Java.
    %returns 1 if string a > b
    %returns 0 if string a == b
    %return -1 if string a < b
    letters_gt = gt(a, b);      %list of boolean a > b
    letters_lt = lt(a, b);      %list of boolean a < b
    ret = 0;
    %octave makes us roll our own string compare because 
    %strings are arrays of numerics
    len = length(letters_gt);
    for i = 1:len
        if letters_gt(i) > letters_lt(i)
            ret = 1;
            return
        elseif letters_gt(i) < letters_lt(i)
            ret = -1;
            return
        endif
    end;
endfunction

%Assuming that myarray is already sorted, (it must be for binary 
%search to finish in logarithmic time `O(log-n))` worst case, then do

myarray = [ 30, 40, 50.15 ];        %already sorted list
binsearch(myarray, 30,    1, 3)     %item 30 is in slot 1
binsearch(myarray, 40,    1, 3)     %item 40 is in slot 2
binsearch(myarray, 50,    1, 3)     %50 does not exist so return 0
binsearch(myarray, 50.15, 1, 3)     %50.15 is in slot 3

%same but for strings:
myarray2 = [ "abc"; "def"; "ghi"];       %already sorted list
binsearch_str(myarray2, "abc", 1, 3)     %item abc is in slot 1
binsearch_str(myarray2, "def", 1, 3)     %item def is in slot 2
binsearch_str(myarray2, "zzz", 1, 3)     %zzz does not exist so return 0
binsearch_str(myarray2, "ghi", 1, 3)     %item ghi is in slot 3

Чтобы отсортировать массив, если его еще нет:

Сложность сортировки зависит от видаданных, которые у вас есть, и какой бы алгоритм сортировки ни писали октавы в GNU, он находится где-то между O(n*log(n)) и O(n*n).

myarray = [ 9, 40, -3, 3.14, 20 ];        %not sorted list 
myarray = sort(myarray) 

myarray2 = [ "the"; "cat"; "sat"; "on"; "the"; "mat"];       %not sorted list 
myarray2 = sortrows(myarray2)

Не стесняйтесь клейкой ленты с этой док-станцией, это единственное, что удерживает устройство вместе.

11 голосов
/ 25 ноября 2011

Да, проверьте это: http://www.obihiro.ac.jp/~suzukim/masuda/octave/html3/octave_36.html#SEC75

a = ["hello"; "world"];
c = cellstr (a)
     ⇒ c =
         {
           [1,1] = hello
           [2,1] = world
         }
>>> cellidx(c, 'hello')
ans =  1

>>> cellidx(c, 'world')
ans =  2
3 голосов
/ 15 декабря 2013

Решение cellidx не соответствует требованию эффективности OP и устарело (как отмечено help cellidx).

Говард Гайтус в комментарии, предложенном с использованием функции lookup () для сортировки массив ячеек строк, который значительно эффективнее, чем cellidx.Тем не менее, это все еще бинарный поиск, тогда как большинство современных языков (и даже многие из 20-летних) дают нам легкий доступ к ассоциативным массивам, что было бы намного лучше.

Хотя Octave, очевидно, не имеетмассивы, это фактически то, что интерпретатор использует для переменных ocatve, включая структуры, так что вы можете сделать это, как описано здесь: http://math -blog.com / 2011/05/09 / associative-arrays-and-cellular-автоматы-в-октаве /

Built-in Function: struct ("field", value, "field", value,...)
Built-in Function: isstruct (expr)
Built-in Function: rmfield (s, f)
Function File: [k1,..., v1] = setfield (s, k1, v1,...)
Function File: [t, p] = orderfields (s1, s2)
Built-in Function: fieldnames (struct)
Built-in Function: isfield (expr, name)
Function File: [v1,...] = getfield (s, key,...)
Function File: substruct (type, subs,...)

Преобразование Matlab в Octave, есть ли контейнеры. Эквивалент карты? предлагает использовать javaObject ("java.util.Hashtable")).Это может привести к некоторым накладным расходам на настройку, но будет выигрыш в производительности, если вы часто его используете.Может даже быть жизнеспособным ссылаться в какой-то библиотеке, написанной на C или C ++?Подумайте, может ли это быть поддерживаемым вариантом.

Предостережение: я относительно новичок в Octave, и пишу это, когда я сам исследую его (вот как я здесь оказался).Я еще не проводил тесты на эффективность этих методов, и хотя я достаточно хорошо разбираюсь в базовых алгоритмах, я могу делать необоснованные предположения о том, что на самом деле эффективно в Octave.

...