У вас есть ответы о том, как это сделать, вот почему ваш путь не работает.
Прежде всего, у вас была хорошая идея: начните с первого символа в строке, посчитайте его(вы забыли включить код счета), удалите все вхождения одного и того же символа в строке.Идея неэффективна, но она будет работать.У вас возникли проблемы с этим битом кода:
For i:=1 to (length(s)) do
begin
If (c=s[i]) then
begin
delete(s,i,1);
end;
end;
Проблема в том, что Паскаль примет значение Length(s)
при настройке цикла, но ваш код изменяет длину строки, удаляя символы(используя delete(s,i,1)
).Вы в конечном итоге посмотрите на плохую память.Вторичная проблема заключается в том, что i
будет продвигаться вперед, не имеет значения, соответствует ли он и удаляет ли символ или нет.Вот почему это плохо.
Index: 12345
String: aabbb
Вы собираетесь проверить i = 1,2,3,4,5, ища a
.Когда i
равно 1, вы найдете совпадение, удалите первый символ, и ваша строка будет выглядеть следующим образом:
Index: 1234
String: abbb
Вы сейчас тестируете с i = 2, и это несовпадение, потому что s [2] = b.Вы только что пропустили один a
, и данный a
собирается остаться в массиве в другом раунде и заставить ваш алгоритм считать его дважды.«Фиксированный» алгоритм будет выглядеть следующим образом:
i := 1;
while i <= Length(s) do
if (c=s[i]) then
Delete(s,i,1)
else
Inc(i);
Это отличается: в данном примере, если я нашел совпадение в 1
, курсор не перемещается, поэтому он видит второеa
.Кроме того, поскольку я использую цикл while
, а не цикл for
, я не могу столкнуться с возможными деталями реализации цикла for.
У вашего алгоритма есть другая проблема.После цикла, который удаляет все вхождения первого символа в строке, вы подготавливаете следующий цикл, используя этот код:
c: = s [1];
Проблема в том, что если выпередать этому алгоритму строку вида aa
(длина = 2, два одинаковых символа), он собирается войти в цикл, удалить или вхождения a
(те, которые превращают s в пустую строку), а затем попытаться прочитатьпервый символ ПУСТОЙ строки.
Последнее слово: ваш алгоритм должен обрабатывать пустую строку на входе, возвращая счет = 0.Вот фиксированный алгоритм:
var s:string;
i,count:integer;
c:char;
begin
Readln(s);
count:=0;
while Length(s) > 0 do
begin
Inc(Count);
c := s[1];
i := 1;
while i <= Length(s) do
begin
If (c=s[i]) then
delete(s,i,1)
else
Inc(i);
end;
end;
Writeln(Count);
Readln;
end.