i want to take 2 lists for example like this;
find=["Hou","House","Mouse"]
repl=["Mou","Bird","House"]
So when i give a text like that;
"The House with Mouse is big"
Output should be this;
"The Mouse with House is big"
So i wrote this;
replace :: String->String->String->String
replace _ _ []=[]
replace find repl text
= if take(length find) text == find
then repl ++ replace find repl (drop (length find) text)
else [head text] ++ (replace find repl (tail text))
replaceMore ::[String]->[String]->String->String
replaceMore _ _ []=[]
replaceMore _ [] _ =[]
replaceMore [] _ _ =[]
replaceMore find repl text
= if (tail find) == [] || (tail repl)==[]
then text
else replaceMore (tail find)
(tail repl)
(replace (head find) (head repl) text)
It returns
"The Mouse with Mouse is big"
so it doesn't work like how i want and i think the problem is here;
replaceMore _ _ []=[]
replaceMore _ [] _ =[]
replaceMore [] _ _ =[]
But still i have no idea how to fix this.So any Ideas?
I might give you some ideas towards the working algorithm.
First of all, you need to divide your input String
into parts ( [String]
) according to your find
strings. So this function is
divideIntoParts :: [String] -> String -> [String]
which works something like
divideIntoParts find "The House with Mouse is big"
gives
["The ", "Hou", "se with ", "Mouse", " is big"]
So it extracts the parts to replace from the string, but preserves the order of letters by keeping other parts in the same list. The naive implementation might look like this
https://gist.github.com/Shekeen/5523749
Next you'll need a function to scan through this list and replace the parts, which need to be replaced. The signature will be
replaceParts :: [String] -> [String] -> [String] -> String
which works like
replaceParts find repl $ divideIntoParts find "The House with Mouse is big"
will be
"The Mouse with House is big"
So your full replace
function will look like
replacePatterns :: [String] -> [String] -> String -> String
replacePatterns find repl = (replaceParts find repl) . (divideIntoParts find)
Also you really need to implement a faster substring search algorithm and consider replacing find
and repl
with one Data.Map
There are two bugs I can see:
The final elements of find
and repl
are always ignored. replaceMore
gives back text
when tail find == []
or tail repl == []
; that should be when find == []
or repl == []
.
But they should be caught by the earlier equations
replaceMore _ [] _ =[] replaceMore [] _ _ =[]
which, you should be able to see now, are wrong, and should be
replaceMore _ [] text = text replaceMore [] _ text = text
But then the output would be
"The House with House is big"
Still wrong. This is because you are building replaceMore
out out replace
. For each search term, you search through the text, replacing it when found. So you replace "Hou"
with "Mou"
(so "House"
is replaced by "Mouse"
); and then later you replace "Mouse"
with "House"
(meaning that what was originally "House"
ends up as "House"
again).
Instead you should search through the text once, looking for every search term at a position before advancing through the text.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.