Loading ...
Sorry, an error occurred while loading the content.

22229Re: Finding gaps in a sequence

Expand Messages
  • Eb
    Nov 14, 2011
      Hi Flo,

      I have a bit outside-of-the-box approach for converting and testing, which require no calculations. I have not tested the code below, but have used the technique successfully in similar situations. Note that there are a couple of holes you need to fill -- the alpha variables, and the GAP_HANDLER.

      If you start your code with a series of variables, one per letter in the alphabet, assigning two-digit hex codes from 01 .. 1a, the StrSplit function will separate the code letters, and the StrReplace function converts the letters to variables. Finally the assignment parses these variables (long line).

      ;n variables, 1 per letter in alphabet used in your index codes,
      ; containing 2-digit hex code each, starting with 01
      ^!Set %a%=01; %b%=02;...%z%=1a

      ;fetch index codes -- use TABS to avoid confusion with StrSplit
      ^!SetListDelimiter ^%tab%
      ^!SetArray %codes%=^$GetDocMatchAll("^[a-z]{3}")$

      ;split character codes into variables, convert to dec nums
      ^!Set %i%=0
      ^!Inc %i%
      ;-----long line ahead
      ^!Set %codes^%i%%=^%^$StrReplace("^%nl%";"%*^%";"^$StrSplit("^%codes^%i%%";1;True)$"%
      ;-----end long line
      ^!Set %codes^%i%%=^$HexToInt(^%codes^%i%%)$
      ;test if gap -- if gap, have the gap handler update the %gapdetect% variable
      ^!If ^%i%=^%codes^%i%% NEXT else GAP_HANDLER
      ^!If ^%i%<^%codes0% LOOP
      ;reports only the first gap, but using a separate lin e num variable allows you to report multiple gaps.

      --- In ntb-clips@yahoogroups.com, "flo.gehrke" <flo.gehrke@...> wrote:
      > --- In ntb-clips@yahoogroups.com, "flo.gehrke" <flo.gehrke@> wrote:
      > >
      > > I've got a database where each record is indexed with an alpha-code
      > > from 'aaa' to 'zzz'...I want to find out if there is a gap in a
      > > sorted list of these codes...
      > Thanks for all replies to my question!
      > @Rod
      > > Treat them as 3-digit radix-26 numbers, and check the numerical
      > > difference between two records. If not =1, something's missing.
      > I understand that diodeom's solution is based on something like that where the numeric value of each character is determined by ^$StrPos$ and a string from a to z.
      > @Axel
      > > Get the first triple, say pqf and add it to the first line with
      > > a space...
      > Wittily, indeed! But we know from experience that this would lead to a lot of cursor movements, insertings etc ending in a very slow performance with a long list.
      > @diodeom
      > > The following basic take looks for what the next index in sequence
      > > should be and flags a gap if no match is found...
      > Thanks, that's great! The advantage is that it needs no '^$Calc$' functions which are rather slow when being called very often.
      > Just for the fun of it, I would like to present my first approach. It's dealing with a pure list of 3-digit-alpha-codes from 'aaa' to 'zzz' without any further stuff in the lines.
      > It's quite fast as well since it doesn't move from line to line but assigns the whole list to an array. The result is a list of codes with gaps, i.e. codes that do not immediately follow one another displayed in a second window (avoid empty line at end of list):
      > ; Assign whole list to array %Codes%
      > ^!SetListDelimiter ^%NL%
      > ^!SetArray %Codes%=^$GetText$
      > ^!Set %i%=1
      > :Loop
      > ; Assign first and second code to array %A% and %B%
      > ^!Set %A%=^%Codes^%i%%
      > ^!Inc %i%
      > ^!Set %B%=^%Codes^%i%%
      > ; Calculate numeric value of each code
      > ^!Set %x%=^$Calc(^$CharToDec(^$StrIndex(^%A%;1)$)$+^$CharToDec(^$StrIndex(^%A%;2)$)$+^$CharToDec(^$StrIndex(^%A%;3)$)$)$
      > ^!Set %y%=^$Calc(^$CharToDec(^$StrIndex(^%B%;1)$)$+^$CharToDec(^$StrIndex(^%B%;2)$)$+^$CharToDec(^$StrIndex(^%B%;3)$)$)$
      > ; Calculate difference
      > ^!Set %Diff%=^$Calc(^%y%-^%x%)$
      > ^!If ^%Diff% = 1 Skip Else Next
      > ^!If ^%Diff%=-24 Next Else Error
      > ^!If ^%i%=^%Codes0% Out
      > ^!Goto Loop
      > :Error
      > ; Assign wrong sequence to variable %Gaps%
      > ^!Set %Gaps%=^%Gaps%^%A%/^%B%^P
      > ^!If ^%i%=^%Codes0% Out
      > ^!Goto Loop
      > :Out
      > ^!IfEmpty ^%Gaps% Next Else Skip_2
      > ^!Info No gaps!
      > ^!Goto End
      > ^!Toolbar New Document
      > ^!InsertText There's a gap at:^P^%Gaps%
      > ^!Toolbar Second Window
      > ^!ClearVariables
      > Regards,
      > Flo
    • Show all 29 messages in this topic