changeset 10020:ffee051323f8

rewrite strjust
author Jaroslav Hajek <highegg@gmail.com>
date Thu, 24 Dec 2009 12:02:27 +0100
parents 7ad32bf759c3
children bf26f81d009f
files scripts/ChangeLog scripts/strings/strjust.m
diffstat 2 files changed, 42 insertions(+), 51 deletions(-) [+]
line wrap: on
line diff
--- a/scripts/ChangeLog	Wed Dec 23 20:58:06 2009 -0600
+++ b/scripts/ChangeLog	Thu Dec 24 12:02:27 2009 +0100
@@ -1,3 +1,7 @@
+2009-12-24  Jaroslav Hajek  <highegg@gmail.com>
+
+	* strings/strjust.m: Rewrite.
+
 2009-12-23  Jaroslav Hajek  <highegg@gmail.com>
 
 	* strings/strjust.m: Special-case string and empty argument.
--- a/scripts/strings/strjust.m	Wed Dec 23 20:58:06 2009 -0600
+++ b/scripts/strings/strjust.m	Thu Dec 24 12:02:27 2009 +0100
@@ -1,4 +1,5 @@
 ## Copyright (C) 2000, 2001, 2003, 2005, 2006, 2007, 2009 Paul Kienzle
+## Copyright (C) 2009 Jaroslav Hajek
 ##
 ## This file is part of Octave.
 ##
@@ -35,7 +36,7 @@
 ## @end example
 ## @end deftypefn
 
-function x = strjust (x, just)
+function y = strjust (x, just)
 
   if (nargin < 1 || nargin > 2)
     print_usage ();
@@ -52,59 +53,45 @@
   endif
 
   if (isempty (x))
-    return
-  endif
+    y = x;
+  else
+    ## Apparently, Matlab considers nulls to be blanks as well; however, does
+    ## not preserve the nulls, but rather converts them to blanks.  That's a
+    ## bit unexpected, but it allows simpler processing, because we can move
+    ## just the nonblank characters. So we'll do the same here.
+
+    [nr, nc] = size (x);
+    ## Find the indices of all nonblanks.
+    nonbl = x != " " & x != "\0";
+    [idx, jdx] = find (nonbl);
 
-  if (rows (x) == 1)
-    ## string case
-    nonbl = x != " " & x != char (0);
-    n = length (x);
-    switch (just)
-    case "right"
-      idx = find (nonbl, 1, "last");
-      if (idx < n) # false if idx is empty
-        x = [" "(1, ones (1, n-idx)), x(1:idx)];
-      endif
-    case "left"
-      idx = find (nonbl, 1, "first");
-      if (idx > 1) # false if idx is empty
-        x = [x(idx:n), " "(1, ones (1, idx))];
-      endif
-    case "center"
-      idx = find (nonbl, 1, "first");
-      jdx = find (nonbl, 1, "last");
-      if (idx > 1 || jdx < n)
-        nsp = ((idx - 1) + (n - jdx)) / 2;
-        lpad = " "(1, ones (1, floor (nsp)));
-        rpad = " "(1, ones (1, ceil (nsp)));
-        x = [lpad, x(idx:jdx), rpad];
-      endif
-    otherwise
-      error ("strjust: invalid justify type: %s", just);
-    endswitch
-  else
-    ## char matrix case.
+    if (strcmp (just, "right"))
+      ## We wish to find the maximum column index for each row. Because jdx is
+      ## sorted, we can take advantage of the fact that assignment is processed
+      ## sequentially and for duplicate indices the last value will remain.
+      maxs = nc * ones (nr, 1);
+      maxs(idx) = jdx;
+      shift = nc - maxs;
+    elseif (strcmp (just, "left"))
+      ## See above for explanation.
+      mins = ones (nr, 1);
+      mins(flipud (idx(:))) = flipud (jdx(:));
+      shift = 1 - mins;
+    else
+      ## Use both of the above.
+      mins = ones (nr, 1);
+      mins(flipud (idx(:))) = flipud (jdx(:));
+      maxs = nc * ones (nr, 1);
+      maxs(idx) = jdx;
+      shift = floor ((nc + 1 - maxs - mins) / 2); 
+    endif
 
-    ## For all cases, left, right and center, the algorithm is the same.
-    ## Find the number of blanks at the left/right end to determine the
-    ## shift, rotate the row index by using mod with that shift, then
-    ## translate the shifted row index into an array index.
-    [nr, nc] = size (x);
-    idx = (x != " " & x != char (0)).';
-    if (strcmp (just, "right"))
-      [N, hi] = max (cumsum (idx));
-      shift = hi;
-    elseif (strcmp (just, "left"))
-      [N, lo] = max (cumsum (flipud (idx)));
-      shift = (nc - lo);
-    else
-      [N, hi] = max (cumsum (idx));
-      [N, lo] = max (cumsum (flipud (idx)));
-      shift = ceil (nc - (lo-hi)/2);
-    endif
-    idx = rem (ones(nr,1)*[0:nc-1] + shift'*ones(1,nc), nc);
-    x = x (idx*nr + [1:nr]'*ones(1,nc));
+    ## Adjust the column indices.
+    jdx += shift (idx);
 
+    ## Create a blank matrix and position the nonblank characters.
+    y = " "(ones (1, nr), ones (1, nc));
+    y(sub2ind ([nr, nc], idx, jdx)) = x(nonbl);
   endif
 
 endfunction