Reputation: 1
I have this line:
const char *S1 = "AaA BbB CcC DdD AaA";
I think that this creates a pointer *S1
, which is located a constant char type value and has the AaA BbB CcC DdD AaA
value in it. Is that right?
If so, how can I read each character of this constant value and recognize how many times AaA
occurs?
I was thinking of creating a loop that will copy each letter to a different cell and then 3 enclosed if
statements, of which the first could check for A
, the second for a
and so one. And if those 3 are true I will increment a counter like so i++
. Is that correct?
I think it's too complicated and it can be done with less code.
Upvotes: 0
Views: 150
Reputation: 4432
The C++ way:
std::string
for string management, it provide a lot benefit, memory management, iterators, some algorithms like find
.find
method of std::string
to search for the index of s1
where s2
begin, if s2
is not present in s1
(a dummy value std::string::npos is returned).Code:
#include <iostream>
int main() {
std::string s1("AaAaAaA");
//std::string s1("AaA BbB CcC DdD AaA");
std::string s2("AaA");
int times = 0;
size_t index = s1.find(s2, index);
while (index != std::string::npos) {
times++;
index = s1.find(s2, index + 1);
}
std::cout << "Found '" << s2 << "' in '" << s1 << "' "
<< times << " times" << std::endl;
}
Upvotes: 0
Reputation: 545518
Your fundamental approach is sound. However, it’s complex and doesn’t scale: what if you wanted to search for a word with more than three letters? Four if
s? Five if
s? Six …? Clearly that won’t do.
Instead, use two loops: one to go over the string you search in (the “haystack” or “reference”) and one over the string you search for (“needle” or “pattern”).
But luckily you don’t even have to do that, because C++ gives you the tools to search for the occurrence of one string in another, the find
function:
#include <string>
#include <iostream>
int main() {
std::string const reference = "AaA BbB CcC DdD AaA";
std::string const pattern = "AaA";
std::string::size_type previous = 0;
int occurrences = 0;
for (;;) {
auto position = reference.find(pattern, previous);
if (position == std::string::npos)
break;
previous = position + 1;
++occurrences;
}
std::cout << occurrences << " occurrences of " << pattern << '\n';
}
You can look up the individual types and functions in the C++ reference. For instance, you can find the std::string::find
function there, which does the actual searching for us.
Note that this will find nested patterns: the reference “AaAaA” will contain two occurrences of “AaA”. If this isn’t what you want, change the line where the previous
position is reassigned.
Upvotes: 1
Reputation: 5416
A simple way to achieve what you want is using strstr(str1, str2)
function, which returns a pointer to the first occurrence of str2 in str1, or a null pointer if str2 is not part of str1.
int count_sequence(const char *S1, const char *sequence) {
int times, sequence_len;
const char *ptr;
times = 0;
sequence_len = strlen(sequence);
ptr = strstr(S1, sequence); //Search for the first sequence
while(ptr != NULL) {
times++;
ptr = strstr(ptr + sequence_len, sequence); //search from the last position
}
return times;
}
Upvotes: 0