예제 #1
0
void reverse_i(char s[], int lim, int i) {
	char tmp;
	if (i < lim) {
		reverse_i(s, lim - 1, i + 1);
		tmp = s[i];
		s[i] = s[lim - 1];
		s[lim - 1] = tmp;
	}
}
예제 #2
0
void reverse(char s[], int lim) {
	reverse_i(s, lim, 0);
}
예제 #3
0
  SignedSize EmpiricalFormula::parseFormula_(Map<const Element *, SignedSize> & ef, const String & input_formula) const
  {
    SignedSize charge = 0;
    String formula(input_formula), symbol, number;

    // we start with the charge part, read until the begin of the formula or a element symbol occurs
    String suffix;
    for (SignedSize reverse_i(formula.size() - 1); reverse_i >= 0; --reverse_i)
    {
      if (!isalpha(formula[reverse_i]))
      {
        suffix = formula[reverse_i] + suffix;
      }
      else
      {
        break;
      }
    }

    // determine charge
    if (!suffix.empty())
    {
      String charge_part;
      Size i = 1;
      for (; i < suffix.size(); ++i)
      {
        if (!isdigit(suffix[i]))
        {
          break;
        }
      }
      if (i != suffix.size())
      {
        // we found the charge part
        String charge_str;
        for (Size j = i + 1; j < suffix.size(); ++j)
        {
          charge_str += suffix[j];
        }

        SignedSize tmp_charge = 1;
        if (!charge_str.empty())
        {
          tmp_charge = charge_str.toInt();
        }
        if (suffix[i] == '-')
        {
          charge = -1 * tmp_charge;
        }
        else
        {
          if (suffix[i] == '+')
          {
            charge = tmp_charge;
          }
          else
          {
            throw Exception::ParseError(__FILE__, __LINE__, __PRETTY_FUNCTION__, formula, "Cannot parse charge part of formula!");
          }
        }

        // now remove the charge part from the formula
        formula.resize(formula.size() - charge_str.size() - 1);
      }
    }

    if (suffix.size() == 1 && suffix[0] == '+')
    {
      charge = 1;
      formula.resize(formula.size() - 1);
    }
    else if (suffix.size() == formula.size())
    {
      if (suffix.size() > 1)
      {
        if (suffix[0] == '-' || suffix[0] == '+')
        {
          charge = suffix.toInt();
          return charge;
        }
      }
      else
      {
        if (suffix == "-")
        {
          charge = -1;
          return charge;
        }
      }
    }

    // split the formula
    vector<String> splitter;
    if (formula.size() > 0)
    {
      if (!isdigit(formula[0]) || formula[0] == '(')
      {
        bool is_isotope(false), is_symbol(false);
        String split;
        for (Size i = 0; i < formula.size(); ++i)
        {
          if ((isupper(formula[i]) && (!is_isotope || is_symbol))
             || formula[i] == '(')
          {
            if (split != "")
            {
              splitter.push_back(split);
              is_isotope = false;
              is_symbol = false;
            }
            split = String(1, formula[i]);
          }
          else
          {
            split += String(1, formula[i]);
          }
          if (formula[i] == '(')
          {
            is_isotope = true;
          }
          if (isupper(formula[i]))
          {
            is_symbol = true;
          }
        }
        splitter.push_back(split);
      }
      else
      {
        throw Exception::ParseError(__FILE__, __LINE__, __PRETTY_FUNCTION__, formula, "This formula does not begin with an element!");
      }
    }

    // add up the elements
    for (Size i = 0; i != splitter.size(); ++i)
    {
      String split = splitter[i];
      String number;
      String symbol;
      bool had_symbol(false);
      for (SignedSize j = split.size() - 1; j >= 0; --j)
      {
        if (!had_symbol && (isdigit(split[j]) || split[j] == '-'))
        {
          number = split[j] + number;
        }
        else
        {
          symbol = split[j] + symbol;
          had_symbol = true;
        }
      }

      SignedSize num(1);
      if (number != "")
      {
        num = number.toInt();
      }

      if (element_db_->hasElement(symbol))
      {
        if (num != 0)
        {
          const Element * e = element_db_->getElement(symbol);
          if (ef.has(e))
          {
            ef[e] += num;
          }
          else
          {
            ef[e] = num;
          }
        }
      }
      else
      {
        throw Exception::ParseError(__FILE__, __LINE__, __PRETTY_FUNCTION__, "'" + split + "'", "'" + symbol + "'");
      }
    }

    // remove elements with 0 counts
    Map<const Element *, SignedSize>::iterator it = ef.begin();
    while (it != ef.end())
    {
      if (it->second == 0)
      {
         ef.erase(it++);  // Note: post increment needed! Otherwise iterator is invalidated 
      }
      else
      {
         ++it;
      }
    }

    return charge;
  }