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

Delphi Sources



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

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 18.12.2008, 16:57
PIF85 PIF85 вне форума
Прохожий
 
Регистрация: 18.12.2008
Сообщения: 17
Репутация: 10
По умолчанию Чтение текста из Memo

Здравствуйте уважаемые программисты! У меня такя проблемма: мне нужно считать из memo набор символов, затем распознать эти симфолы, т.е. если в memo написано HSO2, то нужно чтобы программа распознала каждый из этих символов отдельно и присвоила каждому из этих символов соответствующие значения например: H:=3, S:=7, O:=1*2. Подскажите пожалуста как можно это осуществить в виде кода?!
Ответить с цитированием
  #2  
Старый 18.12.2008, 17:19
ApplicatiOn ApplicatiOn вне форума
Активный
 
Регистрация: 28.02.2008
Сообщения: 388
Репутация: -10
По умолчанию

case ставишь, и каждый символ проверяешь...
Ответить с цитированием
  #3  
Старый 18.12.2008, 17:31
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,096
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

Во первых, тебе надо иметь константный массив соответсвия символов значениям. Во вторых, надо писать парсер, который разбирает выражение и с помощью соотв. массива возвращает тебе твои циферки.
Ты не написал что надо делать с этими цифрами (куда их "складывать").
Для твоего примера будет где-то так:
Код:
type
  TVal = record
    Letter : String;
    Value : Integer;
  end;

const
  Vals : Array [1..3] Of TVal =
    ((Letter:'H'; Value:3),(Letter:'S'; Value:7),(Letter:'O'; Value:1));

function GetValue(ALetter : String) : Integer;
var
  I : Integer;
begin
  Result := -1;
  For I := 1 To 3 Do
    If Vals[i].Letter = ALetter Then
      Begin
        Result := Vals[i].Value;
        Break;
      End;
end;

function Parse(AText : String) : String;
var
  I : Integer;
  Buf : String;
  V : Integer;
begin
  Result := '';
  I := 1;
  While I <= Length(AText) Do
    Begin
      // Получить хим элемент.
      If Not (AText[i] In ['A'..'Z']) Then Raise Exception.CreateFmt('Ошибка в формуле в позиции %d',[i]);
      Buf := AText[i];
      If AText[I+1] In ['a'..'z'] Then
        Begin
          Inc(I);
          Buf := Buf + AText[i];
        End;
      V := GetValue(Buf);
      If V = -1 Then Raise Exception.CreateFmt('Введенный хим элемент не найден (%s)',[Buf]);
      Result := Result + IntToStr(V);
      Inc(I);

      // Проверяем на цифру
      Buf := '';
      While AText[i] In ['0'..'9'] Do
        Begin
          Buf := Buf + AText[i];
          Inc(I);
        End;
      If Buf <> '' Then Result := Result + '*' + Buf;

      Result := Result + ' - ';
    End;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  Edit2.Text := Parse(Edit1.Text);
end;

Код понимает "правильное" написание химэлементов (первая буква большая, вторая, если есть, маленькая) и цифры. Цифра не может идти первой. Результат выводит в виде строки. Для увеличения поддерживаемых элементов надо "добить" их в константный массив в соотв. виде и скорректировать цикл в функции GetValue.
Ответить с цитированием
  #4  
Старый 18.12.2008, 17:40
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,096
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

Да, скобки не поддерживаютя.
Ответить с цитированием
  #5  
Старый 18.12.2008, 17:59
PIF85 PIF85 вне форума
Прохожий
 
Регистрация: 18.12.2008
Сообщения: 17
Репутация: 10
По умолчанию

Спасибо Вам огромное! А как можно вывести в Edit2 конечное число, т.е. уже результат расчета? И будет ли все работать если значения элементов будут не целыми числами?Заранее премного благодарен за исчерпывающий ответ!
Ответить с цитированием
  #6  
Старый 18.12.2008, 18:07
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,096
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

Да, можно.
Ты же не написал что надо делать с этими числами.
Просто сложить?

Тогда там надо немного переделать функцию Parse.
Изменения:
Код:
function Parse(AText : String) : Integer;
var
  I : Integer;
  Buf : String;
  V : Integer;
begin
  Result := 0;
  I := 1;
  While I <= Length(AText) Do
    Begin
      // Получить хим элемент.
      If Not (AText[i] In ['A'..'Z']) Then Raise Exception.CreateFmt('Ошибка в формуле в позиции %d',[i]);
      Buf := AText[i];
      If AText[I+1] In ['a'..'z'] Then
        Begin
          Inc(I);
          Buf := Buf + AText[i];
        End;
      V := GetValue(Buf);
      If V = -1 Then Raise Exception.CreateFmt('Введенный хим элемент не найден (%s)',[Buf]);
      Inc(I);

      // Проверяем на цифру
      Buf := '';
      While AText[i] In ['0'..'9'] Do
        Begin
          Buf := Buf + AText[i];
          Inc(I);
        End;
      If Buf <> '' Then V := V * StrToInt(Buf);
      Result := Result + V
    End;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  Edit2.Text := IntToStr(Parse(Edit1.Text));
end;

С дробными числами где? В формуле - ну можно, но муторно.
В весах элементов - можно. А зачем? Вроде атомные веса всегда считают приблизительно целыми.
Ответить с цитированием
  #7  
Старый 18.12.2008, 18:16
PIF85 PIF85 вне форума
Прохожий
 
Регистрация: 18.12.2008
Сообщения: 17
Репутация: 10
По умолчанию

Спасибо большое! Атомные веса действительно считаются, чаще всего, целыми числами, как например в школе считали, но во-первых для некоторых элементов, таких как Cu(Mr=63.5) и Cl (Mr=35.5) не допускается округление, А вообще для более точных расчетов пользуются атомными весами с двумя значащими цифрами после запятой.
А не скажете как быть со скобками? очень бы хотелось сделать модуль к моей программе по-универсальнее! Очень Вам благодарен!!!
Ответить с цитированием
  #8  
Старый 18.12.2008, 18:44
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,096
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

Перевод на дробные - вместо Integer надо указать Double везде, где это надо. Все. В проверочном вызове надо использовать FloatToStr.

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


Delphi Sources

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

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

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

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


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


 

Сайт

Форум

FAQ

Соглашения

Прочее

 

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