Технический форум

Технический форум (http://www.tehnari.ru/index.php)
-   Помощь студентам (http://www.tehnari.ru/forumdisplay.php?f=41)
-   -   Шифровка и расшифровка (http://www.tehnari.ru/showthread.php?t=72469)

virginia 29.04.2012 15:46

Шифровка и расшифровка
 
const
str= 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvw xyz';
alpha='YXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkji hgfedcba';
var
S: String;
Ch : Char;
i, j, Len : Integer;
Procedure shifrovka(var s:string);
begin
for i := 1 to Length(S) do
begin
Len := Length(str);
for j := 1 to Len do
if str[j] = S[i] then Break;
if j <= Len then S[i] := alpha[j]
end;
Writeln(S);

end;
Procedure rasshifrovka(var s:string);
begin
for i := 1 to Length(S) do
begin
Len := Length(alpha);
for j := 1 to Len do
if alpha[j] = S[i] then Break;
if j <= Len then S[i] := str[j]
end ;
Writeln(S);
end;

помогите,пожалуйста,переделать программу без break

Vladimir_S 29.04.2012 19:12

Цитата:

Сообщение от virginia (Сообщение 725028)
помогите,пожалуйста,переделать программу без break

Начать с того, что я здесь напрочь не вижу программы - только две процедуры. Составленные, к слову сказать, не слишком грамотно: во-первых, именовать глобальный параметр программы и формальный параметр процедуры одинаково (в данном случае строка S) - не то, чтобы ошибка, но дурной стиль. Но это, как говорится, семечки. Там еще куча ошибок и нелепостей. Вот вы вводите цикл по j:
for j := 1 to Len do
а дальше - условие
if j <= Len
абсолютно бессмысленное, поскольку оно и так выполнено исходя из диапазона цикла.
Не говоря уже о таких мелочах, как отсутствие буквы Z в строке alpha, зачем-то всунутые внутрь циклов вычисления (при каждом проходе!!!) длин строк-констант, ну и прочие неряшливости. Да, отмечу еще, что присваивать идентификаторам имена стандартных функций Паскаля хоть и допустимо, но КРАЙНЕ нежелательно. В данном случае я об имени строковой константы Str. (Str(X,S) - это оператор преобразования числа в строку).
Вообще-то задачка оказалась ох, до чего непростая - я с ней где-то полтора часа провозился, пока отладил. Тут когда пытаешься учесть повторы букв, а также отделить совпадающие ранее замененные буквы с с еще не замененными - ух! Ну, в общем, отладил. Но непростой код в итоге получился:
Код:

const
 str1= 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvw xyz';
 alpha='ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkji hgfedcba';

var
 Q: String;

Procedure shifrovka(var S:string);
var
 i,j,k:Integer;
 M:Set of Byte;
 Ch:Char;
begin
 M:=[];
 for i:= 1 to Length(S) do
  begin
  If Not(i in M) then
    begin
    Ch:=S[i];
    j:=0;
    repeat
      Inc(j);
    until (str1[j]=Ch) or (j=Length(str1));
    If str1[j]=Ch then
      for k:=i to Length(S) do
      if (S[k]=Ch) and Not(k in M) then
        begin
        S[k]:=alpha[j];
        M:=M+[k];
        end;
    end;
  end;
 Writeln(S);
end;

Procedure rasshifrovka(var S:string);
var
 i,j,k:Integer;
 M:Set of Byte;
 Ch:Char;
begin
 M:=[];
 for i:=1 to Length(S) do
  begin
  If Not(i in M) then
    begin
    Ch:=S[i];
    j:=0;
    repeat
      Inc(j);
    until (alpha[j]=Ch) or (j=Length(alpha));
    If alpha[j]=Ch then
      for k:=i to Length(S) do
      if (S[k]=Ch) and Not(k in M) then
        begin
        S[k]:=str1[j];
        M:=M+[k];
        end;
    end;
  end;
 Writeln(S);
end;

Begin
 writeln('Enter the string to code/decode:');
 readln(Q);
 shifrovka(Q);
 rasshifrovka(Q);
 readln
End.


virginia 30.04.2012 20:06

Procedure shifrovka(var S:string);
var
i,j,k:Integer;
M:Set of Byte;
Ch:Char;
begin
M:=[];
for i:= 1 to Length(S) do
begin
If Not(i in M) then
begin
Ch:=S[i];
j:=0;
repeat
Inc(j);
until (str1[j]=Ch) or (j=Length(str1));
If str1[j]=Ch then
for k:=i to Length(S) do
if (S[k]=Ch) and Not(k in M) then
begin
S[k]:=alpha[j];
M:=M+[k];
end;
end;
end;
Writeln(S);
end;
объясните пожалуйста эту часть пошагово

Vladimir_S 30.04.2012 21:12

Цитата:

Сообщение от virginia (Сообщение 725563)
объясните пожалуйста эту часть пошагово

Ха, а я ведь предупреждал, что тут отнюдь не просто! Вообще задача изначально имеет куда более простое (и тупое) решение, если ввести дополнительную строку S1, а потом, например, с помощью оператора Case, задать таблицу заполнения этой S1, а в конце обратно переприсвоить S:=S1. Но Вы пошли по пути последовательной замены символов исходной строки, я, соответственно, тоже. Правда, тут возникает проблема.
Пусть, например, надо закодировать строку
zazazaza
из которой после кодировки должно получиться
azazazaz
Простой вариант - это идти по исходной строке "символ за символом" и заменять последовательно. Тогда получится не сложно, но долго и скучно. Но можно (как это сделано в программе) пытаться сразу заменить все одинаковые символы строки, что и реализовано.
Итак, начали. Первый символ - z. После замены всех символов "z" символом "a", имеем:
aaaaaaaa
И как, спрашивается, программе различить подлежащий замене исходный символ "a" от получившегося в результате замены и потому дальнейшему преобразованию не подлежащего? Вот для этого создается множество M порядковых номеров преобразованных символов. В данном случае после замены z→a это будет множество [1, 3, 5, 7], и символы "a", стоящие на указанных позициях, уже преобразованию не подлежат. Т.е. в данном примере на втором шаге будут заменены только "a", стоящие на позициях 2, 4, 6 и 8.
Ну и пара слов по структуре процедуры. Цикл по i - это последовательное прохождение символов исходной строки. Если текущего номера i нет в "черном списке" (множестве М), то производится замена всех символов строки, идентичных стоящему на i-той позиции, начиная с номера i и до конца (это цикл по k), причем и тут необходимо сверять позицию каждого заменяемого символа с "черным списком", и если эта позиция в нем есть, то пропускать. При этом во время каждой замены "черный список" пополняется номером заменяемого символа.
Понятнее стало? Надеюсь, что объяснил. Если всё же непонятно, спрашивайте.

virginia 30.04.2012 21:40

спасибо огромное.теперь понятно


Часовой пояс GMT +4, время: 08:09.

Powered by vBulletin® Version 4.5.3
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.