Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > [ "Начинающим" ]
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 05.01.2011, 14:46
FAZA FAZA вне форума
Прохожий
 
Регистрация: 05.01.2011
Сообщения: 16
Репутация: 10
По умолчанию Помогите оптимизировать программу

Программа для N равного 1000 работает 7 секунд, надо 2. Входной текстовый файл большой 1МБ.
Код:
program Project2;



{$APPTYPE CONSOLE}
{$R+,Q+,I+}

uses
  SysUtils;
const a='а';
const Wmin =1000;
const ABC=['а'..'я', 'А'..'Я','ё','Ё'];

Function EqualWord(n:string; w: array of string; i:integer):boolean; //проверяет выходном массиве w есть ли такое слово n
var l:integer;
begin
  result:=true;
  for l:=1 to i do
    if ansilowercase(w[l])=ansilowercase(n) then result:=false;
end;

Function ShortestWord (w:string;z:array of string; k:integer):boolean; // Проверяет есть ли в массиве z cлова которые длиннее входного слова w
var i:integer;
begin
  Result:=false;
  if z[1]='' then result:=true;
  for i:=k downto 1 do
    if length(z[i])>length(w) then begin
      Result:=true;
      exit;
    end;
end;

Procedure InsertWord(w:string;var z:array of string; var k:integer); //  проверяем куда нам нужно вставить слово w и вставляет по неубыванию длины
var prev,d:string;
    i:integer;
begin
  prev:=w;
  for i:=k downto 1 do begin
    if length(z[i])<length(prev) then begin
      d:=z[i];
      z[i]:=prev;
      z[i+1]:=d;
    end;
  end;
end;

Function Letter(w:string;a:char):boolean; // Проверяет содержит ли слово два раза заданную букву
var  i,j   : integer;
begin
  j:=0;
  Result:=false;
  for i:=1 to length(w) do
    if w[i]=a then inc(j);
  If j=2 then result:=true;
end;
 {#34.Дан файл, содержащий русский текст. Найти в тексте N<=2000 самых коротких слов,
 содержащих 2 раза заданную букву. Записать найденные слова в текстовый файл в
 порядке неубывания длины. Все найденные слова должны быть разными!}
var
    i,j,k : integer;
    s:string;
    z: array [1..2000] of string;//массив найденных слов
    w: array [1..100] of string; //массив слов теущей строки
begin

  rewrite (output, 'output.txt');
  reset (input, 'input.txt');
  while not seekeof do begin
    readln(s);
    s:=s+' ';
    i:=1;
    j:=0;
    while i<=length(s) do begin
      if s[i] in ABC then begin
        inc(j);
        w[j]:='';
        while s[i] in ABC do begin
          w[j]:=w[j]+s[i];
          inc(i);
        end;
        inc(i);
      end
      else inc (i);
    end;
    k:=Wmin;
    for i:=1 to j do begin
      if (Letter(w[i],a)) and (EqualWord(w[i],z,k)) and (ShortestWord(w[i],z,k)) then InsertWord(w[i],z,k);
    end;
 end;
 for i:=1 to Wmin do
   If z[i]<>'' then writeln (z[i],' ');
end.
Ответить с цитированием
  #2  
Старый 05.01.2011, 19:19
Asinkrit Asinkrit вне форума
Местный
 
Регистрация: 29.10.2009
Сообщения: 446
Репутация: 271
По умолчанию

У меня сомнения, что эта программа вообще работает... Оптимизировать здесь много чего можно, для начала выходить с циклов, когда условие удовлетворено, а не крутить их до посинения. А вообще пересмотреть алгоритм и проделать все тоже самое, только в одном цикле.

Последний раз редактировалось Asinkrit, 05.01.2011 в 19:23.
Ответить с цитированием
  #3  
Старый 05.01.2011, 20:13
Аватар для Konrad
Konrad Konrad вне форума
Эксперт
 
Регистрация: 19.03.2009
Сообщения: 1,261
Репутация: 45834
По умолчанию

Тут нечего оптимизировать - нужно заново писать программу.
Просто ты её начал решать прямолинейно, а нужно было чуток схитрить.
Ответить с цитированием
  #4  
Старый 05.01.2011, 21:08
lmikle lmikle сейчас на форуме
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,087
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

В общем, +1 к предыдущим постам.

а если тупо оптимизировать текущую версию, то:
1. Отказаться от динамических массивов типа String - использовать TStringList.
2. Выходы из циклов при выполнении условия (уже упоминалось).
3. Минимизировать кол-во операций со строками (upper/lower) путем того, что добавлять в список уже обработынные априори строки. тогда в сравнении тебе надо будет преобразовывать одну строку, а не обе. Плюс к этому вынести преобразование за границы цикла.
4. читать исходный файл одним куском в тот же TStringList.
5. Использовать глобальные переменнные там, где это имеет смысл.

Вот этот список - для начала.
Ответить с цитированием
  #5  
Старый 06.01.2011, 00:33
lmikle lmikle сейчас на форуме
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,087
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

Мой вариант кода на проце Core 2 Duo (мобильном) под WinXP файл размером 795.207 байт (взял текст какой-то книжки с lib.rus.ec) отрабатывает меньше, чем за секунду для N = 1000.
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 20:28.


 

Сайт

Форум

FAQ

Соглашения

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2025