Версия для печати темы

Нажмите сюда для просмотра этой темы в обычном формате

Форум «Всё о Паскале» _ Задачи _ Удаление повторяющихся элементов массива

Автор: redeezko 8.12.2009 22:47

Помогите со следующей задачей: в заданном массиве из n литер удалить все повторяющиеся литеры.
Вот что получилось у меня:

program Project1;
{$APPTYPE CONSOLE}
uses
SysUtils;
const n=10;
type u=array[1..n] of char;
var x:u;
i,j,l,k:integer;
begin
writeln('vvedite nabor liter');
for i:=1 to n do
read(x[i]);
i:=2;
l:=n;
while i<=l do
begin
for j:=1 to i-1 do
if x[i]=x[j] then
begin
l:=l-1;
for k:=i to n do
x[k]:=x[k+1];
i:=i-1;
end;
inc(i);
end;
for i:=1 to l do write(x[i]);
readln;
readln;
end.

Но она почему то не работает. Вернее не всегда работает. Например если ввести aasdfsyajy то
программа оставит asdjy. Очень прощу помощи.
P.S. Учусь на 1 курсе, так что не знаю что такое процедуры и функции smile.gif . Да и проходим мы сейчас массивы, так что задачу необходимо сделать наподобие как делаю я. Заранее спасибо

Автор: Lapp 9.12.2009 0:43

Цитата(redeezko @ 8.12.2009 18:47) *
в заданном массиве из n литер удалить все повторяющиеся литеры.
Поясни, пожалуйста, поточнее, что это значит. Удалить повторы, идущие подряд, или вообще все? При этом хотя бы одну оставить или тоже удалять? Ставь задачу четче..

Автор: redeezko 9.12.2009 0:48

Написал задачу в точности как она была продиктована мне... Но все таки думаю что необходимо оставить по одной литере, то есть из abaadcba сделать abdc. Удалять все повторы.

Автор: Гость 9.12.2009 1:20

Цитата(redeezko @ 8.12.2009 20:48) *
из abaadcba сделать abdc. Удалять все повторы.
Хорошо, с этим понятно.
Теперь скажи: вы проходили тип set (множество), или еще нет?

Автор: redeezko 9.12.2009 1:34

Нет, не проходили.

Автор: Unconnected 9.12.2009 2:35

Блин, а я уже со множествами сделал...

const n=10;
var lits:set of char=[];
s:array[1..n] of char;
i,i2:integer;
begin
writeln('Vvedite nabor liter');
for i:=1 to n do readln(s[i]);
for i:=1 to n do
if (s[i] in lits) then s[i]:=#0 else include(lits,s[i]);
for i:=1 to n do writeln(s[i]);
readln;
end.


Пусть будет)

Автор: Lapp 9.12.2009 3:21

Ну, тогда можно делать примерно так:

program Project1;
{$APPTYPE CONSOLE}
const
n=10;
type
u=array[1..n] of char;
var
x:u;
i,j,l,k:integer;

begin
writeln('vvedite nabor liter');
for i:=1 to n do read(x[i]);
ReadLn;
i:=2;
l:=n;
while i<=l do begin
j:=1;
while (j<i)and(i<=l) {проверять l} do if x[i]=x[j] then begin
Dec(l);
for k:=i to l do x[k]:=x[k+1];
j:=1 {начать снова}
end
else Inc(j);
inc(i);
end;
for i:=1 to l do write(x[i]);
readln;
end.

Автор: volvo 9.12.2009 3:30

Цитата
Но она почему то не работает. Вернее не всегда работает.
Потому что вот этот цикл:
      for j:=1 to i-1 do
if x[i]=x[j] then
begin
l:=l-1;
for k:=i to n do { <--- Вот этот самый }
x[k]:=x[k+1];
i:=i-1;
end;
не должен выполняться дважды при одном и том же j ни в коем случае. А у тебя - выполняется: несмотря на то, что ты уменьшил значение i, Паскаль работает со старым, неизмененным значением (это особенности цикла For в Паскале, начало и конец цикла вычисляются один раз, перед выполнением, а не на каждой итерации), что приводит к удалению лишнего символа.

Будем переписывать, или исправлять? smile.gif

P.S. Хм... Опоздал smile.gif Но объяснение, почему не работало - не помешает все же, я думаю...