Minounderstand är nöjd med hjälpen
Minounderstand 154
Postad: 1 sep 2017 18:04

Beräkna ord i Haskell

Så jag har fått en uppgift där jag ska beräkna antalet ord i strängar med Haskell.

Orden är sammanhängande bokstäver i alfabetet, så strängen "h3llo th3re" skulle ha 4 ord totalt. Hade lätt kunnat lösa denna uppgift med ett imperativt språk men eftersom Haskell är funktionellt vet jag inte hur jag ska bära mig åt.

Vet hur jag ska iterera genom strängen rekursivt men är helt lost på hur jag ska "identifiera" orden i strängarna jag behandlar.

Finns det något smidigt sätt att göra detta på som inte kräver att jag importerar en massa paket?

 

Tack på förhand!

Bubo 7000
Postad: 1 sep 2017 20:15

Gör det för hand i ditt exempel. Hur kom du fram till att det skulle bli fyra ord?

Minounderstand 154
Postad: 2 sep 2017 15:08

Okej så för strängen "h3llo th3re", kollar jag först 'h', vilket är en bokstav, men efterföljande tecken är en siffra, så då har jag 1 ord. Därefter kollar jag 'l', där de två efterföljande tecknen 'l' och 'o' också är bokstäver. Så då får jag ett till ord, osv osv.

Jag förstår dock inte hur jag ska implementera detta rekursivt.

Tänker att svansrekursion med guards skulle kunna fungera, typ:

words :: String -> Int

words [] = 0

words(x:xs)
|isAlpha 1 + words xs
|otherwise words xs

Men då beräknar jag antalet bokstäver i strängen. :(

Bubo 7000
Postad: 2 sep 2017 15:12

Låt bli att räkna upp på ditt andra L och på O.

Minounderstand 154
Postad: 2 sep 2017 15:37

Exakt, men hur skulle jag göra det funktionellt? Kan ju inte ha någon counter eller liknande i Haskell.

Bubo 7000
Postad: 2 sep 2017 16:00

Det går väl att minnas om förra tecknet var en bokstav eller inte?

Minounderstand 154
Postad: 2 sep 2017 16:04

På något sätt, men vet inte riktigt hur. Tänker att jag kan droppa alla icke-bokstäver efter första bokstaven och fortsätta så, rekursivt.

Bubo 7000
Postad: 2 sep 2017 16:09

Det här borde fungera i vilket språk som helst

 

 

Om Läs_en_variabel isAlpha

  New_word = Last_char_was_not_Alpha
  Last_char_was_not_Alpha = False

else

  Last_char_was_not_Alpha = True

end if

 

if New_word then
  Number_of_words = Number_of_words + 1
end if

Minounderstand 154
Postad: 2 sep 2017 17:18

Får inte tilldela värden till variabler i Haskell, tyvärr, det är det som gör det så klurigt. :(

Stokastisk 3597 – Fd. Medlem
Postad: 2 sep 2017 17:21

Jag har aldrig programmerat i Haskell, så detta kanske är en ful lösning som tusan, men jag löste det genom följande

isLetter :: Char -> Bool
isLetter n = (||) (n >= 'a' && n <= 'z') (n >= 'A' && n <= 'Z')

eatWord :: String -> String
eatWord (x:xs)
| isLetter x = eatWord xs
| otherwise = x : xs
eatWord "" = ""

countWords :: String -> Int
countWords (x:xs)
| isLetter x = 1 + (countWords (eatWord xs))
| otherwise = countWords xs
countWords "" = 0

Minounderstand 154
Postad: 2 sep 2017 18:42

Är mest imponerad över hur du kom fram till den lösningen, ska försöka göra min egen implementation.

Tack för svar!

Svara Avbryt
Close