Advertisement
vana_shimko

LSD 2.1

Nov 28th, 2014
159
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Pascal 8.45 KB | None | 0 0
  1. {$mode objfpc}
  2.  
  3. program RadixLSD;
  4.  
  5. uses
  6.     Math, SysUtils;
  7.    
  8. type
  9.     TDigit = -9..9;
  10.     TResultPos = -1..high(word);
  11.     TArray = pLongint;
  12.     TInputMode = (Keyboard, Textfile);
  13.     TOutputMode = (ToScreen, ToTextfile, ToBoth);
  14.     TReadElement = function (var f: text; var number: longint; index: longword): boolean;
  15.    
  16. function ReadFromFile(var f: text; var number: longint; index: longword = 0): boolean;
  17. begin
  18.     if eof(f) then
  19.         result:= false
  20.     else
  21.     begin
  22.         result:=true;
  23.         try
  24.             read(f,number);
  25.         except
  26.             result:= false;
  27.         end;
  28.     end;
  29. end;
  30.  
  31. function ReadFromKeyboard(var f: text; var number: longint; index: longword): boolean;
  32. var
  33.     isCorrect: boolean;
  34. begin
  35.     write('Введите ', index + 1, ' элемент массива: ');
  36.     repeat
  37.         isCorrect:= true;
  38.        
  39.         try
  40.             readln(number);
  41.         except
  42.             isCorrect:= false;
  43.             write('Ошибка ввода! Повторите ввод: ');
  44.         end;
  45.     until isCorrect;
  46.    
  47.     result:= true;
  48. end;
  49.  
  50. procedure PrintError(var f: text; outputMode: TOutputMode);
  51. begin
  52.     writeln('Возникла ошибка во время обработки входного файла!');
  53.     if (outputMode <> ToScreen) then
  54.     begin
  55.         append(f);
  56.         writeln(f,'Возникла ошибка во время обработки входного файла!');
  57.         close(f);
  58.     end;   
  59. end;
  60.  
  61. procedure PrintHelp;
  62. begin
  63.     writeln('      Справка по формату входного файла      ');
  64.     writeln;
  65.     writeln(' В первой строке входного файла должно содержаться количество элементов массива для сортировки (>= 2)');
  66.     writeln(' Будет прочитано лишь указанное количество элементов.');
  67.     writeln(' В следующей строке должны содержаться элементы данного массива, разделенные одним пробелом.');
  68.     writeln(' Поддерживаются только целые положительные числа, посторонние символы в файле не допускаются.');
  69.     writeln;
  70. end;
  71.  
  72.  
  73. procedure PrintArray (const arrToPrint: TArray; size: longword; var f: text);
  74. var
  75.     i: word;
  76.  
  77. begin
  78.     append(f);
  79.     for i:= 0 to size-2 do
  80.             write(f, arrToPrint[i],' ');
  81.     writeln(f, arrToPrint[size-1]);
  82.     writeln(f);
  83.     close(f);
  84. end;
  85.  
  86. function GetDigit(number: longint; numberOfDigit: byte): TDigit;
  87. var
  88.     i: byte;
  89. begin
  90.     for i:= 1 to numberOfDigit - 1 do
  91.         number:= number div 10;
  92.  
  93.     result:=number mod 10;
  94. end;
  95.  
  96. procedure RadixSort (var arrToSort: TArray; maxNumberOfDigit: byte; size: longword; var f: text; outputMode: TOutputMode);
  97. var
  98.     numberOfDigit: byte;
  99.     currentDigit: TDigit;
  100.     i: word;
  101.     digits: array [-9..9] of word;
  102.     temp, tempArray: pLongint;
  103.  
  104. begin
  105.     GetMem(tempArray, sizeof(longint) * size);
  106.    
  107.     for numberOfDigit:= 1 to maxNumberOfDigit do
  108.     begin
  109.         fillchar(digits,sizeof(digits),0);
  110.         for i:=0 to size - 1 do
  111.             inc(digits[GetDigit(arrToSort[i], numberOfDigit)]);
  112.  
  113.         digits[9]:= size - digits[9];
  114.  
  115.         for currentDigit:= 8 downto -9 do
  116.             digits[currentDigit]:= digits[currentDigit+1] - digits[currentDigit];
  117.  
  118.         for i:=0 to size-1 do
  119.         begin
  120.             tempArray[digits[GetDigit(arrToSort[i], numberOfDigit)]] := arrToSort[i];
  121.             inc(digits[GetDigit(arrToSort[i], numberOfDigit)]);
  122.         end;
  123.  
  124.         temp:=tempArray;
  125.         tempArray:=arrToSort;
  126.         arrToSort:=temp;
  127.        
  128.         rewrite(f);
  129.         writeln(f, 'Сортировка по ', numberOfDigit, ' разряду:');
  130.         close(f);
  131.        
  132.         PrintArray(arrToSort,size,f);
  133.        
  134.         if (outputMode = ToBoth) then
  135.         begin
  136.             append(output);
  137.             writeln('Сортировка по ', numberOfDigit, ' разряду:');
  138.             PrintArray(arrToSort,size,output);
  139.         end;
  140.     end;
  141.  
  142.     FreeMem(tempArray);
  143. end;
  144.  
  145. function ProcArray (var arrToProc: TArray; size: longword; var maxNumberOfDigits: byte; var f: text; readElement: TReadElement; inputMode: TInputMode): boolean;
  146. var
  147.     numberOfDigits: byte;
  148.     i: word;
  149.     isCorrect: boolean;
  150. begin
  151.     reset(f);
  152.     if (inputMode = Textfile) then
  153.         readln(f);
  154.  
  155.     result:= true;
  156.     maxNumberOfDigits:= 0;
  157.     isCorrect:= true;
  158.  
  159.     i:= 0;
  160.     while (i < size) and (isCorrect) do
  161.     begin
  162.         isCorrect:= readElement(f, arrToProc[i], i);
  163.  
  164.         try
  165.             numberOfDigits:= trunc( ln ( abs (arrToProc[i]) ) / ln(10) )+ 1;
  166.         except
  167.             numberOfDigits:= 0;
  168.         end;
  169.  
  170.         if (numberOfDigits > maxNumberOfDigits) then
  171.                 maxNumberOfDigits:= numberOfDigits;
  172.        
  173.         inc(i);
  174.     end;
  175.    
  176.     close(f);
  177.     result:= isCorrect;
  178. end;
  179.  
  180. function ReadSize(var size: longword; var f: text): boolean;
  181. begin
  182.     reset(f);
  183.    
  184.     result:=true;
  185.     try
  186.         readln(f,size);
  187.         if (size < 2) then
  188.             raise Exception.Create('<2');
  189.     except     
  190.         result:= false;
  191.     end;
  192.    
  193.     close(f);
  194. end;
  195.  
  196. procedure ChooseInputFile(var f: text; var inputFileName: ansistring);
  197. var
  198.     fileName: ansistring;
  199.     isExisting: boolean;
  200. begin
  201.     repeat
  202.         write('Введите имя файла с исходными данными: ');
  203.         readln(fileName);
  204.  
  205.         isExisting:= FileExists(fileName);
  206.         assign(f,fileName);
  207.  
  208.         if not isExisting then
  209.             writeln('Такого файла не существует!')
  210.     until isExisting;
  211.    
  212.     writeln;
  213.     inputFileName:= fileName;
  214. end;
  215.  
  216. procedure ChooseOutputFile (var f: text; const inputFileName: ansistring);
  217. var
  218.     fileName: ansistring;
  219.     isValid: boolean;
  220.    
  221. begin
  222.     repeat
  223.         isValid:=true;
  224.        
  225.         write('Введите имя файла для вывода результата: ');
  226.         readln(fileName);
  227.         assign(f, fileName);
  228.        
  229.         try
  230.             if (fileName = inputFileName) then
  231.                 raise Exception.Create('input = output');
  232.             rewrite(f);
  233.             close(f);              
  234.         except
  235.             isValid:=false;
  236.             writeln('Невозможно использовать файл с таким именем!');
  237.         end;
  238.     until isValid;
  239.     writeln;
  240. end;
  241.  
  242. procedure PressEnter;
  243. begin
  244.     rewrite(output);
  245.     writeln('Нажмите Enter.');
  246.     readln;
  247. end;
  248.  
  249. function ChooseInput: TInputMode;
  250. var
  251.     source: char;
  252. begin
  253.     repeat
  254.         write('Выберите способ ввода входных данных (K - клавиатура, F - файл):  ');     
  255.         readln(source);
  256.        
  257.         if (UpperCase(source) = 'K') then
  258.             result:= Keyboard
  259.         else
  260.             result:= Textfile;
  261.     until ( (UpCase(source) = 'K') or (UpCase(source) = 'F') );
  262.     writeln;
  263. end;
  264.  
  265. function ChooseOutput: TOutputMode;
  266. var
  267.     output: char;
  268. begin
  269.     repeat
  270.         write('Выберите способ вывода данных (S - экран, F - файл, A - экран и файл): ');
  271.         reset(input);
  272.         readln(output);
  273.        
  274.         if (UpperCase(output) = 'S') then
  275.             result:= ToScreen
  276.         else
  277.             if (UpperCase(output) = 'F') then
  278.                 result:= ToTextfile
  279.             else
  280.                 result:= ToBoth;
  281.     until ( (UpCase(output) = 'S') or (UpCase(output) = 'F') or (UpCase(output) = 'A') );
  282.     writeln;
  283. end;
  284.  
  285. var
  286.     fIn, fOut : text;
  287.     size: longword;
  288.     arrToSort: TArray;
  289.     maxDigit: byte;
  290.     isCorrect: boolean;
  291.     inputFileName: ansistring;
  292.     outputMode: TOutputMode;
  293.    
  294. begin
  295.     if (ChooseInput = Textfile) then
  296.     begin
  297.         ChooseInputFile(fIn, inputFileName);
  298.         isCorrect:= ReadSize(size, fIn);
  299.        
  300.         if (isCorrect) then
  301.         begin
  302.             GetMem(arrToSort, sizeof(longint)*size);
  303.             isCorrect:= (ProcArray(arrToSort, size, maxDigit, fIn, @ReadFromFile, Textfile));
  304.         end;
  305.     end
  306.     else
  307.     begin
  308.         repeat
  309.             write('Введите количество элементов массива (минимум - 2): ');
  310.             isCorrect:= ReadSize(size, input);         
  311.         until isCorrect;
  312.         writeln;
  313.        
  314.         fIn:= input;
  315.        
  316.         GetMem(arrToSort, sizeof(longint)*size);
  317.         ProcArray(arrToSort, size, maxDigit, input, @ReadFromKeyboard, Keyboard);
  318.         writeln;
  319.     end;
  320.    
  321.     outputMode:= ChooseOutput;
  322.     if (outputMode = ToScreen) then
  323.         fOut:= output
  324.     else
  325.         if ( (outputMode = ToTextfile) or (outputMode = ToBoth)) then
  326.             ChooseOutputFile(fOut, inputFileName);
  327.        
  328.     if (isCorrect) then
  329.     begin
  330.         if (outputMode <> ToTextfile) then
  331.         begin
  332.             writeln('Исходный массив:');
  333.             PrintArray(arrToSort, size, output);
  334.         end;   
  335.        
  336.         RadixSort(arrToSort, maxDigit, size, fOut, outputMode);
  337.        
  338.         append(fOut);
  339.         writeln(fOut, 'Отсортированный массив:');
  340.         close(fOut);
  341.         PrintArray(arrToSort, size, fOut);
  342.        
  343.         if (outputMode = ToBoth) then
  344.         begin
  345.             rewrite(output);
  346.             writeln('Отсортированный массив:');
  347.             PrintArray(arrToSort, size, output);
  348.         end;
  349.        
  350.         FreeMem(arrToSort);
  351.     end
  352.     else
  353.     begin
  354.         PrintError(fOut, outputMode);
  355.         PrintHelp;
  356.     end;
  357.    
  358.     PressEnter;
  359. end.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement