function a = chvec_permute ( n, a, p ) %% CHVEC_PERMUTE permutes a character vector in place. % % Discussion: % % This routine permutes an array of character "objects", but the same % logic can be used to permute an array of objects of any arithmetic % type, or an array of objects of any complexity. The only temporary % storage required is enough to store a single object. The number % of data movements made is N + the number of cycles of order 2 or more, % which is never more than N + N/2. % % Example: % % Input: % % N = 5 % P = ( 2, 4, 5, 1, 3 ) % A = ( 'B', 'D', 'E', 'A', 'C' ) % % Output: % % A = ( 'A', 'B', 'C', 'D', 'E' ). % % Modified: % % 24 April 2005 % % Author: % % John Burkardt % % Parameters: % % Input, integer N, the number of objects. % % Input/output, character A(N), the array to be permuted. % % Input, integer P(N), the permutation. P(I) = J means % that the I-th element of the output array should be the J-th % element of the input array. P must be a legal permutation % of the integers from 1 to N, otherwise the algorithm will % fail catastrophically. % % Output, character A(N), the permuted array. % ierror = perm_check ( n, p ); if ( ierror ~= 0 ) fprintf ( 1, '\n' ); fprintf ( 1, 'CHVEC_PERMUTE - Fatal error!\n' ); fprintf ( 1, ' The input array does not represent\n' ); fprintf ( 1, ' a proper permutation. In particular, the\n' ); fprintf ( 1, ' array is missing the value %d\n', ierror )'; error ( 'CHVEC_PERMUTE - Fatal error!' ); end % % Search for the next element of the permutation that has not been used. % for istart = 1 : n if ( p(istart) < 0 ) continue elseif ( p(istart) == istart ) p(istart) = -p(istart); continue else a_temp = a(istart); iget = istart; % % Copy the new value into the vacated entry. % while ( 1 ) iput = iget; iget = p(iget); p(iput) = -p(iput); if ( iget < 1 | n < iget ) fprintf ( 1, '\n' ); fprintf ( 1, 'CHVEC_PERMUTE - Fatal error!\n' ); fprintf ( 1, ' A permutation index is out of range.\n' ); fprintf ( 1, ' P(%d) = %d\n', iput, iget ); error ( 'CHVEC_PERMUTE - Fatal error!' ); end if ( iget == istart ) a(iput) = a_temp; break end a(iput) = a(iget); end end end % % Restore the signs of the entries. % p(1:n) = -p(1:n);