Determine if a string has all unique characters
Given a character string (which may be empty, or have a length of zero characters):
- Task
- create a function/procedure/routine to:
- determine if all the characters in the string are unique
- indicate if or which character is duplicated and where
- display each string and it's length (as the strings are being examined)
- a zero─length (empty) string shall be considered as unique
- process the strings from left─to─right
- if unique, display a message saying such
- if not unique, then:
- display a message saying such
- display what character is duplicated
- only the 1st non─unique character need be displayed
- display where "both" duplicated characters are in the string
- the above messages can be part of a single message
- display the hexadecimal value of the duplicated character
Use (at least) these five test values (strings):
- a string of length 0 (an empty string)
- a string of length 1 which is a single period (.)
- a string of length 6 which contains: abcABC
- a string of length 7 which contains a blank in the middle: XYZ ZYX
- a string of length 36 which doesn't contain the letter "oh":
- 1234567890ABCDEFGHIJKLMN0PQRSTUVWXYZ
Show all output here on this page.
REXX
<lang rexx>/*REXX pgm determines if a string is comprised of all unique characters (no duplicates).*/ @.= /*assign a default for the @. array. */ parse arg @.1 /*obtain optional argument from the CL.*/ if @.1= then do; @.1= /*Not specified? Then assume defaults.*/
@.2= . @.3= 'abcABC' @.4= 'XYZ ZYX' @.5= '1234567890ABCDEFGHIJKLMN0PQRSTUVWXYZ' end
do j=1; if j\==1 & @.j== then leave /*String is null & not j=1? We're done*/ say copies('─', 79) /*display a separator line (a fence). */ say 'Testing for the string (length' length(@.j)"): " @.j say dup= isUnique(@.j) say 'The characters in the string' word("are aren't", 1 + (dup>0) ) 'all unique.' if dup==0 then iterate ?= substr(@.j, dup, 1) say 'The character ' ? " ('"c2x(?)"'x) at position " dup , ' is repeated at position ' pos(?, @.j, dup+1) end /*j*/
exit /*stick a fork in it, we're all done. */ /*──────────────────────────────────────────────────────────────────────────────────────*/ isUnique: procedure; parse arg x /*obtain the character string.*/
do k=1 to length(x) - 1 /*examine all but the last. */ p= pos( substr(x, k, 1), x, k + 1) /*see if the Kth char is a dup*/ if p\==0 then return k /*Find a dup? Return location.*/ end /*k*/ return 0 /*indicate all chars unique. */</lang>
- output when using the internal defaults
─────────────────────────────────────────────────────────────────────────────── Testing for the string (length 0): The characters in the string are all unique. ─────────────────────────────────────────────────────────────────────────────── Testing for the string (length 1): . The characters in the string are all unique. ─────────────────────────────────────────────────────────────────────────────── Testing for the string (length 6): abcABC The characters in the string are all unique. ─────────────────────────────────────────────────────────────────────────────── Testing for the string (length 7): XYZ ZYX The characters in the string aren't all unique. The character X ('58'x) at position 1 is repeated at position 7 ─────────────────────────────────────────────────────────────────────────────── Testing for the string (length 36): 1234567890ABCDEFGHIJKLMN0PQRSTUVWXYZ The characters in the string aren't all unique. The character 0 ('30'x) at position 10 is repeated at position 25