Вам нужен способ пометить символы, которые вы уже подсчитали, чтобы вы могли избежать повторного подсчета персонажа.
Вы можете сделать это, используя первый символ в качестве отметки, означающей «Уже посчитано, поэтому пропустите этот символ». Вы делаете это, изменяя символы, которые считаются равными первому символу. Когда вы перемещаетесь по строке, вы просто пропускаете символы, равные первому символу.
Пример:
Скажем, текст i "HelloHey", тогда он выглядит так:
1. iteration "HelloHey" -> "HelloHey" and print "H 2 times"
2. iteration "HelloHey" -> "HelloHHy" and print "e 2 times" (second e replaced by H)
3. iteration "HelloHHy" -> "HelHoHHy" and print "l 2 times" (second l replaced by H)
4. iteration skip because of an 'H' in position 4 of "HelHoHHy"
5. iteration "HelHoHHy" -> "HelHoHHy" and print "o 1 time"
6. iteration skip because of an 'H' in position 6 of "HelHoHHy"
7. iteration skip because of an 'H' in position 7 of "HelHoHHy"
8. iteration "HelHoHHy" -> "HelHoHHy" and print "y 1 time"
Код может выглядеть следующим образом:
#include <stdio.h>
#include <wchar.h>
int main(void) {
wchar_t text[] = L"Hello world";
wchar_t* p = text + 1;
unsigned i = 1;
// Unconditional loop to count first letter
while(*p)
{
if (*p == text[0])
{
++i;
}
++p;
}
printf("[%lc] seen %u times\n", text[0], i);
// Loop the remaining string
p = text + 1;
while(*p)
{
// Only count if current letter differs from first letter
if (*p != text[0])
{
// New character - count its occurence
wchar_t* t = p + 1;
unsigned i = 1;
while (*t)
{
if (*p == *t)
{
++i;
*t = text[0]; // Mark letter as counted
}
++t;
}
printf("[%lc] seen %u times\n", *p, i);
}
++p;
}
return 0;
}
Вывод:
[H] seen 1 times
[e] seen 1 times
[l] seen 3 times
[o] seen 2 times
[ ] seen 1 times
[w] seen 1 times
[r] seen 1 times
[d] seen 1 times