Say I have a huge body of text ~500 chars stored in a string, how can i loop through the string and increment a variable by 1 every time i encounter the character 'a'?
Program to loop on every character in string in C++. Here in this program we will see how to iterate through each characters of a string in C++. To loop on each character, we can use loops starting from 0 to (string length – 1). For accessing the character we can either use subscript operator " [ ]" or at () function of string object.
Here in this program we will see how to iterate through each characters of a string in C++. To loop on each character, we can use loops starting from 0 to (string length – 1).
Loop Through Each Character in a String. The following is an example of looping through a string using a For…Next Loop, and returning each character in a msgbox. The Len Function counts the total number of characters in the string. will loop through each letter in the string.
In the above example, we have used the for-loop to access each element of the string. Here, we have used the charAt () method to access each character of the string. In the above example, we have converted the string into a char array using the toCharArray ().
I think there are more easily understandable approaches to this that might work just fine for you. Using a regex:
Regex.scan(~r/a/, str) |> Enum.count
or dividing the string into its unicode characters and then counting on that:
str |> String.graphemes |> Enum.count(fn(c) -> c == "a" end)
These are not very efficient approaches but the performance impact should be negligible with a (relatively small!) string that is only 500 chars long.
If you need a more efficient approach, a good option is often to iterate using recursion and then counting the occurences manually. Although this approach is quite verbose, it performs much better.
defmodule Recursive do
def count(str, <<c::utf8>>) do
do_count(str, c, 0)
end
defp do_count(<<>>, _, acc) do
acc
end
defp do_count(<<c::utf8, rest::binary>>, c, acc) do
do_count(rest, c, acc + 1)
end
defp do_count(<<_::utf8, rest::binary>>, c, acc) do
do_count(rest, c, acc)
end
end
Finally, here's a benchmark using benchfella of the approaches so far. I also included @DeboraMartins' "split length" solution, which outperforms all of the above for small strings. For larger strings, the difference to the recursive approach is negligible.
# 500 Characters
split length 500000 5.90 µs/op
recursive 100000 10.63 µs/op
regex count 100000 24.35 µs/op
graphemes count 10000 118.29 µs/op
# 500.000 Characters
split length 100 11150.59 µs/op
recursive 100 12002.20 µs/op
regex count 100 25313.40 µs/op
graphemes count 10 218846.20 µs/op
My sugestion of code is:
countSubstring = fn(_, "") -> 0
(str, sub) -> length(String.split(str, sub)) - 1 end
And you can call using IO.puts countSubstring.(str, "a")
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With