Link to home
Start Free TrialLog in
Avatar of formadmirer
formadmirerFlag for United States of America

asked on

VFP Reverse Words In A String

Hello Experts!

I would like to reverse the order of words within a string, for example:

"Mary had a little lamb" becomes "lamb little a had Mary"


As a mention for speed issues I should note that this will be run against a memo field, so there could be hundreds to maybe even a couple thousand characters involved.

Thank you!
Avatar of peterhupp
peterhupp
Flag of Canada image

lcString = "Mary had a little lamb"
lcReverseString = ""
alines(laWords,lcString,1," ")
for lnx=1 TO alen(laWords,1) -1
    lcReverseString = SPACE(1)+laWords(lnx) + lcReverseString  
ENDFOR
lcReverseString =  laWords(ALEN(laWords,1)) + lcReverseString
? "Reversed string: " + lcReverseString
ASKER CERTIFIED SOLUTION
Avatar of Cyril Joudieh
Cyril Joudieh
Flag of Lebanon image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Speed is not problem for VFP...
CREATE CURSOR cTemp (txt M, revTxt M)
APPEND BLANK

LOCAL lnI, lcText
lcText = ''

FOR lnI = 1 TO 1000
  lcText = m.lcText + TRANSFORM(m.lnI) + '. '
NEXT

REPLACE txt WITH m.lcText
REPLACE revTxt WITH ReverseWords(txt)

MODIFY MEMO txt NOWAIT
MODIFY MEMO revTxt NOWAIT


FUNCTION ReverseWords

LPARAMETERS lcString

LOCAL lnI, lcOutput
lcOutput = ''

FOR lnI = GETWORDCOUNT(m.lcString) TO 1 STEP -1
  lcOutput = m.lcOutput + IIF(EMPTY(m.lcOutput), '', ' ') + GETWORDNUM(m.lcString, m.lnI)
NEXT

RETURN m.lcOutput

Open in new window

You may even define additional word separators in GETWORDCOUNT() and GETWORDNUM() functions.
There's nothing to add codewise.

As the texts need to be read from DBF or more precise from FPT memo fiel, this is what will take the longest. In memory processing is fast anyway, also in VFP.

Indeed c++ can do faster with memory, as it has pointers. C++ could simply allocate 2*textlength bytes and fill half that memory with the original memo text read from file and then fill the other half with the words in reverse order.

With vfp any variable assignment will cause new memory allocation for the longer new string and freeing of the old allocated memoery. Then it writes the result of newword+reversedtextsofar to compose the next reversedtextsofar. In average, the number of bytes copied and copied again is textlength/2*wordcount, so for a 1000 word text you have 1000 memory allocations compared to 1 and in average textlength/2 bytes are resevered and filled. The first allocation is for one (the last word), the second for two (last and previous word), etc.

Still also that much more memory copying will be lightning fast, as modern CPUs can copy multiple GB per second in RAM. (unlike in files, also with SSDs, though the difference there is a smaller factor).

Simply try any of the codes above, and you'll see. It won't pay to do this in c++, especially if you're not firm  in DLL or FLL development. It's not just leraning the bit of c++ needed, but the settings of compiler and linker and the IDE that'll take a bit of time. That'll only pay, if you'd need that functionality for a lot of data and repeatedly, regularly, and if the VFP code does exceed a few seconds. The potential is not as it seems 500times faster, because the part that will take the same time in c++ is reading the memo from the file. the hdd or ssd speed will be the bottle neck. Even with SSD you get in the range of ~0.5 GB/s, but less than with RAM, that can peek to 17GB/s (PC3-17000).

So ideal situations assumed, the file read would take 34x the time to make a RAM copy. Of course SSD speeds and RAM speeds vary a lot. In reality that'll take longer, as there is a seek time to first find file and memo position within the fpt, the drive controller will take it's time and so on. The file read is the bottleneck.

If the time needed to process a few hundred thousand memo text with each a few thousand words is 3 seconds in VFP and you could turn that down to 0.3 or 0.1 with c++ that won't matter much, will it?

Bye, Olaf.
Avatar of formadmirer

ASKER

Thank you all. I'm sure any of the suggestions would have done the trick, but I wound up using CaptainCyril's as I could better understand what it was doing.
Hmm... Interesting.

Are you sure Captain's code will reverse words in a string the way you requested it?

You should test it.

But never mind... I did not believe peterhupp's code will do the task before reading it the third time.
My code reverses the string character by character and not word by word. I understood the question wrongly. You can use my Extract function and reverse words if you like I can write it out for you tomorrow.
Well, maybe the real task is to reverse letter by letter, but formadmirer will see soon enough, if the result fits his needs or not.

You could also put a mirror besides the screen and do it with no code at all ;)

If you run a middle east version of Windows, you may also make use of the RightToLeft proper5ty. RTF should also support RightToLeft text and you can display that via The RichtText control. Arabic users of VFP should also know about this and be able to help out with sample code. Maybe you'll rather find someone at foxite.

Bye, Olaf.