Экспертная система Delphi.int.ru

Сообщество программистов
Общение, помощь, обмен опытом

Логин:
Пароль:
Регистрация | Забыли пароль?

Delphi.int.ru Expert

Другие разделы портала

Переход к вопросу:

#   

Статистика за сегодня:  


Лучшие эксперты

Подробнее »



Вопрос # 5 670

/ вопрос решён /

Здравствуйте!

Вообщем ситуация такая: необходима программка для обработки специфического текстового файла: в нём может быть около 10000 строк, состоящих из 14 символов. Необходимо загрузить содержимое в поле Мемо Main, дальше по нажатию кнопки "Проверить" сравнить все сроки друг с другом по символам с 4 по 11 и если они совпадают то удалить их их поля из Main(для последующего сохранения в отсортированный файл) и одновременно копировать: строка с "3" на конце (14 символ) в поле мемо "Closed", а с "2" в поле мемо "Open". К вопросу прилагаю принт скрин с пояснениями.
Заранее благодарен за помощь!

К вопросу прикреплён файл. Загрузить » (срок хранения: 60 дней с момента отправки вопроса)

Rhasta Вопрос решён, но можно продолжить его обсуждение в мини-форуме

Вопрос задал: Rhasta (статус: Посетитель)
Вопрос отправлен: 8 октября 2011, 21:48
Состояние вопроса: решён, ответов: 2.

Ответ #1. Отвечает эксперт: ierihon1

Здравствуйте, Rhasta! Вот конечный вариант алгоритма:

function CompareStrings(S1,S2:string):Boolean;
begin
  Delete(S1,1,3); Delete(S1,12,3);
  Delete(S2,1,3); Delete(S2,14,3);
  if S1 = S2 then
    Result:=True
  else
    Result:=False;
end;
 
procedure TForm11.btn1Click(Sender: TObject);
var i,j:Integer;
begin
  mmo2.Clear;
  mmo3.Clear;
  for i := 0 to mmo1.Lines.Count - 1 do
    for j := 0 to mmo1.Lines.Count - 1 do
      if i <> j then
        if CompareStrings(mmo1.Lines[i],mmo1.Lines[j]) then
        begin
          if mmo1.Lines[i][14] = '2' then
            mmo2.Lines.Add(mmo1.Lines[i]);
          if mmo1.Lines[i][14] = '3' then
            mmo3.Lines.Add(mmo1.Lines[i]);
          mmo1.Lines.Delete(i);
        end;
end;

Ответ отправил: ierihon1 (статус: 1-ый класс)
Время отправки: 8 октября 2011, 22:43
Оценка за ответ: 5

Комментарий к оценке: Кое что подправил, но за идею спасибо

Ответ #2. Отвечает эксперт: Drinkenz

Здравствуйте, Rhasta!

function CompareStrings(S1,S2:string):Boolean;
begin
  Delete(S1,14,1);
  Delete(S1,1,3);
  Delete(S2,14,1);
  Delete(S2,1,3);
  Result:=S1=S2;
end;
 
 
procedure TForm1.Button1Click(Sender: TObject);
var i,j,k:Integer;
    savmemo,delmemo: tstringlist;
    f1,f2: boolean;
begin
  savmemo:=TStringList.Create();
  delmemo:=TStringList.Create();
  memo2.Clear;
  memo3.Clear;
  i:=0;
  while i<(memo1.Lines.Count-2) do begin
    f1:=false;
    f2:=true; // restore i
    for j:=i+1 to memo1.Lines.Count-1 do
      if CompareStrings(memo1.Lines[i],memo1.Lines[j]) then begin
         f1:=true;
         delmemo.add(memo1.Lines[j]);
         end
         else
         savmemo.add(memo1.Lines[j]);
 
    if f1 then begin
      f2:=false; // мемо1 в  на переделку
      delmemo.add(memo1.Lines[i])
      end
      else
      savmemo.add(memo1.Lines[i]); //  строка уникальна!
 
    for k:=0 to delmemo.count-1 do
      case delmemo.strings[k][14]of
        '2': memo2.Lines.Add(delmemo.strings[k]);
        '3': memo3.Lines.Add(delmemo.strings[k]);
        end;
    delmemo.Clear;
    memo1.lines.assign(savmemo);
    if f2 then inc(i);
    savmemo.Clear;
    end;
 
  delmemo.Free;
  savmemo.Free;
end;

Ответ отправил: Drinkenz (статус: 1-ый класс)
Время отправки: 9 октября 2011, 01:10


Мини-форум вопроса

Всего сообщений: 25; последнее сообщение — 13 октября 2011, 15:59; участников в обсуждении: 4.

Страницы: [1] [2] [Следующая »]

ierihon1

ierihon1 (статус: 1-ый класс), 8 октября 2011, 22:00 [#1]:

я так понимаю нужен именно алгоритм сравнения?
Rhasta

Rhasta (статус: Посетитель), 8 октября 2011, 22:06 [#2]:

Да, вы совершенно правы!
ierihon1

ierihon1 (статус: 1-ый класс), 8 октября 2011, 22:07 [#3]:

хорошо уже работаю над этим.
ierihon1

ierihon1 (статус: 1-ый класс), 8 октября 2011, 22:19 [#4]:

function CompareStrings(S1,S2:string):Boolean;
begin
  Delete(S1,1,3); Delete(S1,14,1);
  Delete(S2,1,3); Delete(S2,14,1);
  if S1 = S2 then
    Result:=True
  else
    Result:=False;
end;
 
procedure TForm11.btn1Click(Sender: TObject);
var i,j:Integer;
begin
  for i := 0 to mmo1.Lines.Count - 1 do
    for j := 0 to mmo1.Lines.Count - 1 do
      if i <> j then
        if CompareStrings(mmo1.Lines[i],mmo1.Lines[j]) then
          if mmo1.Lines[i][14] = '2' then
          begin
            mmo2.Lines.Add(mmo1.Lines[i]);
            mmo1.Lines.Delete(i);
          end;
          if mmo1.Lines[i][14] = '3' then
          begin
            mmo3.Lines.Add(mmo1.Lines[i]);
            mmo1.Lines.Delete(i);
          end;
end;
Проверьте, если будут недочёты исправим.
Rhasta

Rhasta (статус: Посетитель), 8 октября 2011, 22:24 [#5]:

Ок, кэп. Отпишусь завтра. Спасибо!
ierihon1

ierihon1 (статус: 1-ый класс), 8 октября 2011, 22:46 [#6]:

Только сейчас увидел: в ответе в чётвёртой строке должно быть
  Delete(S2,1,3); Delete(S2,12,3);
Drinkenz

Drinkenz (статус: 1-ый класс), 8 октября 2011, 23:23 [#7]:

после Delete(S2,1,3) длина строки у тебя будет 11 символов,
и Delete(S2,12,3) уже работает с пустотой
Rhasta

Rhasta (статус: Посетитель), 8 октября 2011, 23:27 [#8]:

Delete(S1,1,3); Delete(S1,11,1);
Delete(S2,1,3); Delete(S2,11,1); Тогда наверное так?
Rhasta

Rhasta (статус: Посетитель), 8 октября 2011, 23:34 [#9]:

Алгоритм вроде не работает... буду копаться дальше)))
Drinkenz

Drinkenz (статус: 1-ый класс), 8 октября 2011, 23:38 [#10]:

проще вот так

function CompareStrings(S1,S2:string):Boolean;
begin
Delete(S1,12,3);Delete(S1,1,3);
Delete(S2,12,3);Delete(S2,1,3);
Result:=S1=S2;
end;
Rhasta

Rhasta (статус: Посетитель), 8 октября 2011, 23:46 [#11]:

Извиняюсь, в вопросе сделал опечатку сравнение идёт с 4 по 13 символ
min@y™

min@y™ (статус: Доктор наук), 9 октября 2011, 09:16 [#12]:

Цитата (Drinkenz):

проще вот так
function CompareStrings(S1,S2:string):Boolean; 
begin 
Delete(S1,12,3); Delete(S1,1,3); 
Delete(S2,12,3); Delete(S2,1,3); 
Result:=S1=S2; 
end;



А может вот так быстрее будет?
function CompareStrings(const S1, S2: string): Boolean;
var
 Index: Integer;
begin
  // 4 вызова Delete() - это 4 перераспределения памяти,
  // которые нахрен не нужны. Поэтому ФТОПКУ их.
 
  Result:= False;
 
  { при необходимости можно проверять коррекность:
  if (Length(S1) <> 14) or (Length(S2) <> 14)
    then Exit; }
 
  for Index:= 4 to 13 do
    if S1[Index] <> S2[Index]
      then Exit;
 
  Result:= True;
end;
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
Rhasta

Rhasta (статус: Посетитель), 9 октября 2011, 12:37 [#13]:

min@y™, спасибо сейчас попробую!
ierihon1, если программа находит совпадения, то она не копирует одну из двух строк в поле мм3, а также не удаляет значения из главного поля Мемо
Drinkenz, Ваш алгоритм ещё не пробовал. Но всё равно спасибо, отпишусь в течение дня
Rhasta

Rhasta (статус: Посетитель), 10 октября 2011, 12:18 [#14]:

Спасибо всем кто откликнулся. Добился желаемого примерно следующим:
procedure TForm1.Button2Click(Sender: TObject);
var i,j:Integer;
str1,str2:string;
begin
  close.Clear;
  open.Clear;
  for i := 0 to main.Lines.Count-1 do
    for j := 0 to main.Lines.Count-1  do
      if i <> j then
        if CompareStrings(main.Lines[i],main.Lines[j]) then
        begin
          str1:=main.Lines[i];
          str2:=main.Lines[j];
          main.Lines.Delete(j);
          main.Lines.Delete(i);
          if str1[14] = '2' then
            open.Lines.Add(str1)
              else close.Lines.Add(str1);
        if str2[14] = '3' then
            close.Lines.Add(str2)
              else open.Lines.Add(str2);
        end;
 label1.Caption:=inttostr(main.Lines.Count);
 label2.Caption:=inttostr(main.Lines.Count);
 label3.Caption:=inttostr(main.Lines.Count);
end;

Теперь в поле main у меня все необходимые строки для сортировки. написал процедуру на кнопку:

procedure TForm1.Button3Click(Sender: TObject);
var
i:integer;
begin
 for i := 0 to main.Lines.Count-1 do
 if main.Lines[i][14]='3'then
    main.Lines.Delete(i)
end;

Но почему то выдаёт ошибку... где я напортачил и как рациональней с точки зрения ресурсов выполнить удаление? (если 14 символ 3, то удалить из поля)
Drinkenz

Drinkenz (статус: 1-ый класс), 10 октября 2011, 12:56 [#15]:

Rhasta, мне тоже пятерку поставь.
Rhasta

Rhasta (статус: Посетитель), 10 октября 2011, 13:10 [#16]:

Поставлю, только помогите мне с последним вопросом))))
min@y™

min@y™ (статус: Доктор наук), 10 октября 2011, 13:12 [#17]:

Цитата (Rhasta):

Поставлю, только помогите мне с последним вопросом))))

for ... to ... do замени на for ... downto .. do.
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
Rhasta

Rhasta (статус: Посетитель), 10 октября 2011, 13:17 [#18]:

min@y™: А так при нажатии на кнопку вообще ничего не происходит((((
min@y™

min@y™ (статус: Доктор наук), 10 октября 2011, 13:45 [#19]:

Цитата (Rhasta):

А так при нажатии на кнопку вообще ничего не происходит

Вместо того, штобы скулить на форуме, прочитал бы, как работает цикл for через downto.
procedure TForm1.Button3Click(Sender: TObject);
var
  i: integer;
begin
  main.Lines.BeginUpdate();
  try
    for i := main.Lines.Count - 1 downto 0 do
      if main.Lines[i][14] = '3'
        then main.Lines.Delete(i);
  finally
    main.Lines.EndUpdate();
  end; 
end;
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
Rhasta

Rhasta (статус: Посетитель), 10 октября 2011, 13:51 [#20]:

я не скулю, а вы вместо того, чтобы оскорблять, тогда бы вообще не писали! такая помощь не особо то нужна

Страницы: [1] [2] [Следующая »]

Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.

Версия движка: 2.6+ (26.01.2011)
Текущее время: 22 февраля 2025, 11:56
Выполнено за 0.06 сек.