Задать вопрос
@Alertoso

Как можно оптимизировать код?

Разобрался полностью в шифраторе и дешифраторе, постарался сделать что-то неплохое, вышло так, посоветуйте, как можно оптимизировать код?
Program Encryption;

{$APPTYPE CONSOLE}

Type
  MyArrayType = array of array of Char;
  DirectionType = (Left, Right, Down, Up);

Var
  Matrix: MyArrayType;
  LenMyS, I, Temp: Integer;
  MyString, HelpString: String;
  SizeArray, Key: Integer;
  InputText, KeyText, OutputText: TextFile;

Procedure MatrixInput(var M: MyArrayType; S: string; const N: integer);
Var I, J: Integer;
Begin
  for I:=1 to N do
  Begin
    for J:=1 to N do
    Begin
      M[I,J]:=S[N*(i-1)+j];
      write(M[I,J]:3)
    End;
    writeln
  End;
End;

Procedure FillVerticalSide(var CurrentStep: Integer; var Pace: Integer; const Interim: Integer; var Orientation: DirectionType; var PositionY: Integer; TurningDirection: Boolean);
Begin
  if TurningDirection then
  Begin
    PositionY:=PositionY+1;
    if CurrentStep=Pace then
    Begin
      CurrentStep:=1;
      if Interim mod 2 = 0 then Orientation:=Up
      else Orientation:=Down;
      if (Interim = 2) or (Interim = 3) then Pace:=Pace+1
    End
    else
      CurrentStep:=CurrentStep+1
  End
  else
  Begin
    PositionY:=PositionY-1;
    if CurrentStep=Pace then
    Begin
      CurrentStep:=1;
      if Interim mod 2 = 0 then Orientation:=Down
      else Orientation:=Up;
      if (Interim = 2) or (Interim = 3) then Pace:=Pace+1
    End
    else
      CurrentStep:=CurrentStep+1
  End;
End;

Procedure FillHorizontalSide(var CurrentStep: Integer; var Pace: Integer; const Interim: Integer; var Orientation: DirectionType; var PositionX: Integer; TurningDirection: Boolean);
Begin
  if TurningDirection then
  Begin
    PositionX:=PositionX+1;
    if CurrentStep=Pace then
    Begin
      CurrentStep:=1;
      if Interim mod 2 = 0 then Orientation:=Right
      else Orientation:=Left;
      if (Interim = 0) or (Interim = 1) then Pace:=Pace+1
    End
    else
      CurrentStep:=CurrentStep+1
  End
  else
  Begin
    PositionX:=PositionX-1;
    if CurrentStep=Pace then
    Begin
      CurrentStep:=1;
      if Interim mod 2 = 0 then Orientation:=Left
      else Orientation:=Right;
      if (Interim = 0) or (Interim = 1) then Pace:=Pace+1
    End
    else
      CurrentStep:=CurrentStep+1
  End
End;

Procedure Spiral(var M: MyArrayType; SpirWrite: Boolean; var S: String; var Temp: integer);
Var
  CurStep, Step, PosX, PosY: Integer;
  Direction: DirectionType; //от 1 до 4 - 1 вправо, 2 вниз, 3 влево, 4 вверх
  I: integer;
Begin
  I:=1;
  PosX:=Trunc(SizeArray/2)+1;
  PosY:=Trunc(SizeArray/2)+1;
  CurStep:=1;
  Step:=1; //через сколько шагов повернуть
  Temp:=Random(4);
  Direction:=DirectionType(Temp);
  write(KeyText, Temp mod 2,Temp);
  while (PosX>0) and (PosX<=SizeArray) and (PosY>0) and (PosY<=SizeArray) do
  Begin
      S[I]:=M[PosX, PosY];
    //движение матрицы по спирали
    case Direction of
      Right: FillVerticalSide(CurStep, Step, Temp, Direction, PosY, True);
      Down: FillHorizontalSide(CurStep, Step, Temp, Direction, PosX, True);
      Left: FillVerticalSide(CurStep, Step, Temp, Direction, PosY, False);
      Up: FillHorizontalSide(CurStep, Step, Temp, Direction, PosX, False);
    End;
    Inc(I)
  End
End;

Procedure CheckAndFixString(var S: String; NeedLength: Integer);
Begin
  if (NeedLength>=1) or (NeedLength<=255) then
  Begin
    if Length(S)>NeedLength then
      S:=Copy(S,1,NeedLength)
    else
      while length(S)<NeedLength do
        S:=S + '#'
  End
End;

Begin
  Randomize;
  MyString:='';
  AssignFile(InputText, 'D:\Работы по ОАиП\2 семестр\InputText.txt');
  Reset(InputText);
  while (not EOF(InputText)) do
  Begin
    Readln(InputText, HelpString);
    if not EOF(InputText) then MyString:=MyString+HelpString+'_'
    else MyString:=MyString+HelpString;
  End;
  LenMyS:=length(MyString);
  if Trunc(sqrt(LenMyS)) mod 2 = 0 then
    SizeArray:=Trunc(sqrt(LenMyS))+1
  else
    SizeArray:=Trunc(sqrt(LenMyS))+2;
  writeln('The required size of the matrix = ',SizeArray,'x',SizeArray);
  Setlength(Matrix, SizeArray+1, SizeArray+1);
  writeLn('The length of the string = ',LenMyS);
  CheckAndFixString(MyString, sqr(SizeArray));
  LenMyS:=length(MyString);
  WriteLn('Required the length of the string = ',LenMyS);
  writeln('Matrix:');
  MatrixInput(Matrix, MyString, SizeArray);
  Assign(KeyText, 'D:\Работы по ОАиП\2 семестр\Key.txt');
  Rewrite(KeyText);
  Key:=Random(16)+1;
  write(KeyText,'Decryption key = ');
  for i:=1 to Key do Spiral(Matrix, True, MyString, Temp);
  writeln(KeyText);
  writeln(KeyText,'Number of passes = ',Key);
  Close(KeyText);
  Assign(OutputText, 'D:\Работы по ОАиП\2 семестр\EncryptedOut.txt');
  Rewrite(OutputText);
  for I:=1 to SizeArray*SizeArray do
    Write(OutputText,MyString[i]);
  Close(OutputText);
  writeln('Press Enter to exit...');
  readln
End.
  • Вопрос задан
  • 491 просмотр
Подписаться 1 Простой Комментировать
Решения вопроса 1
@kalapanga
"Как оптимизировать код" - неверный вопрос. Код можно оптимизировать, если есть критерии оптимизации. А у Вас не только критериев нет, Вы даже не написали, что программа делать должна, с какими данными работать. Так что думаю, если программа делает то, что задумано, то не стоит ничего "оптимизировать". Лучше лишний раз на ошибки проверьте.
Если уж Вам сильно хочется замечаний, то вот некоторые. Часть можете считать придирками, но есть и более важные.
Сверху вниз.
Глобальная переменная I. Потенциальный источник ошибок. В каких-то процедурах она перекрывается локальной переменной, в каких-то нет. Легко неуследить и использовать не ту, что нужно. (Глобальную переименовать)
Нелогичное название процедуры MatrixInput. Да, там формируется матрица, но при этом она не вводится (Input), а наоборот выводится - write(...)! (Для лучшей читабельности кода назовите например FillMatrix)
В этой же процедуре не контролируется выход индекса за границу в строке
M[I,J]:=S[N*(i-1)+j];
Раз уж выделили этот кусочек в отдельную процедуру, в её начале надо проверить корректность входных параметров.
В процедуре CheckAndFixString вместо цикла
while length(S)<NeedLength do S:=S+'#'
лучше так
S := S + StringOfChar('#', NeedLength - length(S));
Здесь длина строки нужна только один раз, а не на каждом проходе цикла.
Основная программа.
Главная ошибка - "захардкоженные" имена файлов. Вы принесли кому-то Вашу программу. Откуда у него такие каталоги?
Или используйте ini-файл с путями к файлам или хотябы оставьте в коде только имена файлов и ищите их в каталоге программы.
Здесь же вторая ошибка - отсутствие обработки ошибок при работе с файлами. Если например нужного файла нет программа свалится с ошибкой вместо информативного сообщения пользователю.
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
@evgeniy_lm
Если сильно хочется оптимизации "древний" TextFile замените на StringList который существенно удобнее.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы