Помогите пожалуйста разобраться как делать.
Кодирование длин серий (Run-length encoding, RLE) - простая техника сжатия,при которой каждая последовательность знаков, которые состоят более чем из 2 одинаквых знаков, кодируется по первому знаку и длине последовательности.
Реализуйте простой вариант этого способа в форме программы фильта, которая кодирует и снова декодирует текстовые файлы,в которых содержатся только строчные и прописные буквы , знаки препинания и пробелы (но не цифры).Ваша программа должна предлогать следующие возможности вызова из камандной строки (метасимболы[...] и ...|... стоят для опций или альтернатив):
RLE [ -c | -d ] [inFile] [outFile]
Значение параметров:
-c входной файл нужно кодировать (значение по умолчанию),
-d входной файл нужно декодировать,
inFile имя входного файла, иначе стандартный ввод (input)
outFile имя выходного файла, иначе стандартный вывод (output).
Пример:
http://radikal.ru/F/s48.radikal.ru/i122/1004/7c/f44389e250f8.jpg.html
Файлы я пока не трогала...Попыталась просто кодировать. В переменную ch сохраняю символ, если он равен следующему - увеличиваю счетчик, если нет - скидываю в строку str2 и текущий символ сохраняю снова в ch и так далее. Не работает..:
var x, str1, str2, ch,countstr : string;
i, k, count : integer;
begin
countstr:= '';
ch := '';
str2 := '';
count := 0;
Readln(str1);
for i := 1 to Length(str1) do begin
if i=1 then begin
ch:=str1[1];
count:= 1;
end
else begin
if ch= str1[i] then
inc(count)
else begin
if count > 2 then begin
Str(count,countstr);
str2:= countstr+ch
end
else begin
for k := 1 to count do
str2 := str2+ch;
ch := str1[i];
count := 1;
end;
end;
end;
end;
end.
А если вот так попробовать:
var
str1, str2, ch, countstr: string;
i, k, count: integer;
begin
str2 := '';
{ Readln(str1); }
str1 := 'AbbCCCddddEnd';
str1 := str1 + '_'; { <--- Последний символ не должен совпадать с добавляемым !!! }
ch := str1[1]; count := 1;
for i := 2 to Length(str1) do begin
if ch = str1[i] then inc(count)
else begin
if count > 2 then begin
Str(count,countstr);
str2 := str2 + countstr + ch { <--- Здесь надо увеличивать str2 !!! }
end
else begin
for k := 1 to count do
str2 := str2 + ch;
end;
ch := str1[i]; count := 1; { <--- Это делается в любом случае, а не только по Else !!! }
end;
end;
writeln(str2);
end.
Спасибо) поняла
Не получается с декодированием. Не могу понять почему больше d намного больше.
var str1 , str2, ch, substr,numberstr: string;
number,i,j,k : integer;
begin
numberstr := '';
str2:= '';
str := 'abb3c4dend';
substr := '1234567890';
for i := 1 to Length(str1) do begin
ch := str1[i];
if Pos(ch,substr)=0 then
str2 := str2 + ch
else begin
numberstr := numberstr+ch;
for j := i+1 to length(str1) do begin
ch:= str1[j];
if pos(ch,substr)>0 then
numberstr := numberstr + ch
else begin;
val(numberstr,number);
for k := 1 to number do
str2 := str2+ch;
break;
end; i:= j+1;
end;
end;
end;
end; i:= j+1;
end;
numberstr := '';
end;
end; i:= j+1;
Ок)
Насчет последнего исправления тоже неверно. Я так обрадавалась, что количесиво d уменьшилось, что даже не заметила что их 5 вместо 4(
uses crt;Попробуй так, вроде пашет
var
str1, str2, ch, countstr: string;
i, k, count: integer;
errcode : integer;
begin
str2 := '';
ch:='';
{ Readln(str1); }
str1 := 'Abb10C4dEn2d';
i:=1;
while i <= length(str1) do begin
if str1[i] in ['0'..'9'] then begin
while (str1[i] in ['0'..'9']) do begin
ch:=ch + str1[i];
inc(i);
end;
val(ch, count, errcode);
if count > 2 then
for k:=1 to count-1 do
str2 := str2 + str1[i];
end
else begin
str2 := str2 + str1[i];
ch:='';
inc(i);
end;
end;
writeln(str2);
readkey
end.
Спасибо, Client.
Просто обидно, что у меня никогда ничего не работает(
Добавлено через 14 мин.
volvo, а что у меня неправильно?/
Узнаешь код
var str1 , str2, ch, substr,numberstr: string;?
number,i,j,k : integer;
errcode: integer;
begin
numberstr := '';
str2:= '';
str1:= 'abb10c4den2d';
substr := '1234567890';
i:=1;
while i <= Length(str1) do begin //замена на while
ch := str1[i];
if Pos(ch,substr)=0 then begin
str2 := str2 + ch;
numberstr:=''; //обнуление
end
else begin
numberstr := numberstr+ch;
for j := i+1 to length(str1) do begin
ch:= str1[j];
if pos(ch,substr)>0 then begin
numberstr := numberstr + ch;
inc(i); //подсчет цифр
end
else begin
val(numberstr,number, errcode);
if number > 2 then //проверка на 2
for k := 1 to number-1 do
str2 := str2+ch;
break;
inc(i);
end;
end;
end;
inc(i); //на основной while для перехода к след символу
end;
writeln(str2);
end.
Хм..но работает неверно.
Вадает результат abbccccccccccddend
пропустило последий символ.
А если задать abb3c4cEnd, то вообще не получается.
вариант что в коде - 10 "с" и 4 "d"
Сорри. Имела в виду abb3c4dEnd.
Походу я что-то недопонимаю...
Снова извините. Переклинило.
Не мог бы кто-нибудь объяснить про командную строку?
ParamCount - число параметров командной строки.
ParamStr(N) - N-ый параметр, строковый тип. ParamStr(0) - само имя программы, с полным путём к ней.
Честно говоря вообще не понимаю как это должно работать
Ну тебе надо получить 3 параметра, делаешь что-то типа (пишу тут):
var c,infile,outfile:string;
begin
c:=paramstr[1];
infile:=paramstr[2];
outfile:=paramstr[3];
if uppercase©='-D' then unpcking else packing;
end.
это значит что надо выполнить выбранное действие
Что такое командная строка - знаешь? Говоря на пальцах, это то, что есть в любом нормальном файловом менеджере, там можно написать myProgram.exe, а можно написать myProgram.exe a b c d, через пробел (если же написать "myProgram.exe a" b c d, то часть, заключённая в кавычки, будет пониматься как один параметр, несмотря на то, что в ней содержится пробел). Это означает, что ты вызываешь программу myProgram.exe с параметрами a, b, c, d. То, что написано в свойствая ярлыка в строке "Объект" - это тоже команда, как правило, она там без параметров. Когда ты открываешь файл "a.txt", на самом деле вызывается команда notepad.exe a.txt, то есть в качестве параметра идёт имя открываемого файла. Поэтому все приличные программы знают, когда надо при запуске показать пустое окно, а когда - сразу открыть файл.
Программа получает информацию о них через функции ParamCount (в данном примере, с myProgram.exe a b c d - 4), и через ParamStr(N) (N от 0 до 4).
Твоя программа может принимать до 3 параметров, надо отдельно разобрать случаи разного их количества, чтобы сформировать, что программа должна делать. Типа так:
var
Decode: boolean;
InFile, OutFile: string;
...
Decode := False;
InFile := '';
OutFile := '';
if ParamCount >= 1 then begin
if ParamStr(1) = '-c' then Decode := False
else if ParamStr(1) = '-d' then Decode := True
else InFile := ParamStr(1);
end;
if ParamCout >= 2 then begin
if InFile = '' then InFile := ParamStr(2) else OutFile := ParamStr(2);
end;
if ParamCount >= 3 then begin
if OutFile = '' then OutFile := ParamStr(3);
end;
Спасибо. Стало немного понятней. А можешь привести какой-нибудь простой полный пример как это работает?
Ну например, программа возводит одно число в степень другого, числа задаются как параметры.
program Test;
var
a, b: extended;
Code: integer;
begin
if ParamCount < 2 then begin
WriteLn('Must be >= 2 parameters!');
Exit;
end;
Val(Paramstr(1), a, Code);
if Code <> 0 then begin
WriteLn(Paramstr(1) , ' is not a number!');
Exit;
end;
Val(Paramstr(2), b, Code);
if Code <> 0 then begin
WriteLn(Paramstr(2) , ' is not a number!');
Exit;
end;
if a > 0 then WriteLn(exp(ln(a) * b))
else if a = 0 then WriteLn(0)
else if (Frac(b) = 0) and (Frac(b/2) = 0) then WriteLn(exp(ln(-a) * b))
else if (Frac(b) = 0) then WriteLn(-exp(ln(-a) * b))
else WriteLn('Invalid argument');
end.
Spasibo ogromnoje.