Я пытаюсь проанализировать химическую формулу (в формате, например: Al2O3
или O3
или C
или C11H22O12
) в C# из строки. Он отлично работает, если только один атом определенного элемента (например, атом кислорода в H2O
). Как я могу исправить эту проблему, и, кроме того, есть ли лучший способ проанализировать строку химических формул, чем я делаю?Разбор химической формулы из строки в C#?
ChemicalElement - это класс, представляющий собой химический элемент. Он имеет свойства AtomicNumber (int), Name (string), Symbol (string). ChemicalFormulaComponent - это класс, представляющий собой химический элемент и количество атомов (например, часть формулы). Он имеет свойства Element (ChemicalElement), AtomCount (int).
Остальное должно быть достаточно ясно, чтобы понять (я надеюсь), но, пожалуйста, дайте мне знать с комментарием, если я могу прояснить что-либо, прежде чем вы ответите.
Вот мой текущий код:
/// <summary>
/// Parses a chemical formula from a string.
/// </summary>
/// <param name="chemicalFormula">The string to parse.</param>
/// <exception cref="FormatException">The chemical formula was in an invalid format.</exception>
public static Collection<ChemicalFormulaComponent> FormulaFromString(string chemicalFormula)
{
Collection<ChemicalFormulaComponent> formula = new Collection<ChemicalFormulaComponent>();
string nameBuffer = string.Empty;
int countBuffer = 0;
for (int i = 0; i < chemicalFormula.Length; i++)
{
char c = chemicalFormula[i];
if (!char.IsLetterOrDigit(c) || !char.IsUpper(chemicalFormula, 0))
{
throw new FormatException("Input string was in an incorrect format.");
}
else if (char.IsUpper(c))
{
// Add the chemical element and its atom count
if (countBuffer > 0)
{
formula.Add(new ChemicalFormulaComponent(ChemicalElement.ElementFromSymbol(nameBuffer), countBuffer));
// Reset
nameBuffer = string.Empty;
countBuffer = 0;
}
nameBuffer += c;
}
else if (char.IsLower(c))
{
nameBuffer += c;
}
else if (char.IsDigit(c))
{
if (countBuffer == 0)
{
countBuffer = c - '0';
}
else
{
countBuffer = (countBuffer * 10) + (c - '0');
}
}
}
return formula;
}
Почему вы проверка, является ли первым символ формулы в верхнем регистре на каждой итерации 'for' loop ('! char.IsUpper (chemicalFormula, 0)')? Индекс здесь всегда равен 0. –
Я думаю, что у вашей функции также есть проблема с чем-то вроде C4O2, это правда? –
См. Также страницу http://stackoverflow.com/questions/2974362/parsing-a-chemical-formula/3742985. Он запрашивает одно в Java, с ответом в Python и связанными с более сложными решениями ANTLR и Python. –