Hi all,

I wrote a function. The aim of it is ;

If the formula is "C12H22" and the str11 is "+H1" then the result should be "C12H23" or if the str11 is "-H1+O1+C1", then the result should be "C13H21O1". It is working all the time but it fails when the formula is "C24H32Cl1O4" and str11 is "-H1-O1". But the same works for all other compounds.

Can anyone help me in this regard.

private void button1_Click(object sender, EventArgs e)
        {
             string formulae = "C24H32Cl1O4";
             string str11 = "-H1-O1";
             string H = "+";
                           // MessageBox.Show("ok");
                    for (int v = 0; v <= str11.Length - 1; v++)
                    {
                        if (str11.Substring(v, 1).ToString() == "-" && char.IsLetter(Convert.ToChar(str11.Substring(v + 1, 1))))
                        {
                            H = "-";

                        }
                        if (str11.Substring(v, 1).ToString() != "-")
                        {
                            if (v <= str11.Length - 1)
                            {
                                if (char.IsLetter(str11, v))
                                {
                                    string atom = "";
                                    if (v + 1 <= str11.Length - 1 && char.IsLetter(Convert.ToChar(str11.Substring(v, 1))) && char.IsLower(str11, v + 1))
                                    {

                                        try
                                        {
                                            H = str11.Substring(v - 1, 1).ToString();
                                            atom = str11.Substring(v, 2).ToString();

                                        }
                                        catch (Exception ex)
                                        {
                                            H = "+";
                                            atom = str11.Substring(v, 2).ToString();
                                            MessageBox.Show("error");
                                            // atom = 
                                        }
                                        //  dt5.Rows[x]["c_IonFormula"] = get_numofstr(atom, formulae, H, get_numfrominotype(str11, v + 1));
                                        formulae = get_numofstr(formulae, H, get_numfrominotype(str11, v + 1), atom).ToString();

                                        v = v + 1;
                                        H = "+";
                                    }
                                    else
                                    {
                                        atom = str11.Substring(v, 1).ToString();
                                        textBox2.Text = get_numofstr(formulae, H, get_numfrominotype(str11, v), atom);
                                        
                                        
                                        H = "+";
                                    }
                                }
                            }
                        }
                    }
                                        
                                    
                                
        }
        public int get_numfrominotype(string Ionsatom, int indexx)
        {



            try
            {



                int a_ = 0;
                int Retrive = 0;
                for (int z11 = indexx; z11 <= Ionsatom.Length - 1; z11++)
                {
                    for (a_ = z11 + 1; a_ <= Ionsatom.Length - 1; a_++)
                    {
                        if (char.IsDigit(Ionsatom, a_))
                        {


                            Retrive = Retrive + Convert.ToInt32(Ionsatom.Substring(a_, 1));
                        }
                        else
                        {
                            break;
                        }

                    }
                    if (Retrive == 0)
                        Retrive = 1;
                    //  z11 = a_;

                    z11 = Ionsatom.Length;

                }

                return Retrive;

            }
            catch (Exception ex)
            {

                return 0;
            }

        }
        public string get_numofstr(string formulae111, string H, int add, string atom)
        {
            try
            {

                string formulae = formulae111;

                int a_ = 0;
                //string formulae = formulae111;
                string Retrive = "";
                int y1 = 0;
                for (int z11 = 0; z11 <= formulae.Length - 1; z11++)
                {

                    if (atom.Length > 1)
                    {
                        if (formulae.Contains(atom.ToString()))
                        {
                            int indexx = formulae.IndexOf(atom.ToString());
                            for (a_ = indexx + 2; a_ <= formulae.Length - 1; a_++)
                            {
                                if (char.IsDigit(formulae, a_))
                                {
                                    Retrive = Retrive + formulae.Substring(a_, 1);


                                    if (a_ == formulae.Length - 1)
                                    {

                                        if (H == "-")
                                        {
                                            if (Retrive != "")
                                                add = Convert.ToInt32(Retrive) - add;
                                        }
                                        else
                                        {
                                            if (Retrive != "")
                                                add = Convert.ToInt32(Retrive) + add;
                                        }
                                        formulae = formulae.Replace(atom.ToString() + Retrive.ToString(), atom.ToString() + add.ToString());
                                        z11 = a_;
                                    }
                                }
                                else
                                {

                                    if (H == "-")
                                    {
                                        if (Retrive != "")
                                            add = Convert.ToInt32(Retrive) - add;
                                    }
                                    else
                                    {
                                        if (Retrive != "")
                                            add = Convert.ToInt32(Retrive) + add;
                                    }



                                    formulae = formulae.Replace(atom.ToString() + Retrive.ToString(), atom.ToString() + add.ToString());
                                    z11 = a_;
                                    break;
                                }

                            }

                            if (Retrive == "")
                            {
                                //Retrive = "1";
                                int f = add + 1;
                                formulae = formulae.Replace(atom.ToString() + Retrive.ToString(), atom.ToString() + add.ToString());
                            }



                        }
                        else
                        {


                            if (atom.ToString() != "-" && H != "-")
                                formulae = formulae.Insert(0, atom.ToString() + add.ToString());
                            break;
                        }

                    }
                    else
                    {

                        if (formulae.Contains(atom.ToString()))
                        {
                            if (formulae[z11].ToString() == atom.ToString())
                            {
                                //  y1 = 1;
                                for (a_ = z11 + 1; a_ <= formulae.Length - 1; a_++)
                                {
                                    if (char.IsDigit(formulae, a_))
                                    {
                                        Retrive = Retrive + formulae.Substring(a_, 1);


                                        if (a_ == formulae.Length - 1)
                                        {

                                            if (H == "-")
                                            {
                                                if (Retrive != "")
                                                    add = Convert.ToInt32(Retrive) - add;
                                            }
                                            else
                                            {
                                                if (Retrive != "")
                                                    add = Convert.ToInt32(Retrive) + add;
                                            }
                                            formulae = formulae.Replace(Retrive.ToString(), add.ToString());
                                            z11 = a_;
                                        }
                                    }
                                    else
                                    {

                                        if (H == "-")
                                        {
                                            if (Retrive != "")
                                                add = Convert.ToInt32(Retrive) - add;
                                            else
                                                add = add - 1;
                                        }
                                        else
                                        {
                                            if (Retrive != "")
                                                add = Convert.ToInt32(Retrive) + add;
                                            else
                                                add = add + 1;
                                        }



                                        formulae = formulae.Replace(atom.ToString() + Retrive.ToString(), atom.ToString() + add.ToString());
                                        Retrive = "1";
                                        z11 = a_;
                                        break;
                                    }

                                }


                                if (Retrive == "")
                                {
                                    //  Retrive = "1";
                                    int g = add + 1;
                                    formulae = formulae.Replace(atom.ToString() + Retrive.ToString(), atom.ToString() + g.ToString());
                                }


                            }
                        }
                        else
                        {

                            if (atom.ToString() != "-" && H != "-")
                                formulae = formulae.Insert(0, atom.ToString() + add.ToString());

                            //  if (atom.ToString() != "-")
                            //&formulae = formulae.Insert(0, atom.ToString() + add.ToString());
                            break;
                        }
                    }
                }



                return formulae;

            }

            catch (Exception ex)
            {
                return formulae111;
            }

        }

- Yamini

You do lots of strange things in your code:

for (int v = 0; v <= str11.Length - 1; v++)

You do this one a lot. "v <= str11.Length - 1" is the same as "v < strl11.Length". No need to subtract one all the time, it's just more work.

str11.Substring(v, 1).ToString()

A substring of a string is a string, no need to call ToString() on a string.

char.IsLetter(Convert.ToChar(str11.Substring(v + 1, 1)))

This is overly complicated. A string can be treated like an array of characters, so you can do this: "char.IsLetter(str11[v+1])".

char.IsLetter(Convert.ToChar(str11.Substring(v, 1))) && char.IsLower(str11, v + 1))

If "IsLower" is true, then it's a letter. No need to check that it is a letter and it is lower. Remove the IsLetter calls.

v = v + 1;

It's generally a bad practice to increment your loop variable inside the loop. I know why you did it (because of the way you are processing the string), but there are better ways to do this.

Here is another way to do this using Regex (yes, I could have made it shorter by using more Regex, but I have to leave something for others to do :))

public String ModifyFormula(String formula, String modifier) {
    Regex c = new Regex(@"([A-Za-z]+[0-9]+)");
    Regex a = new Regex(@"([\+\-][A-Za-z]+[0-9]+)");
    Dictionary<String, int> work = new Dictionary<string, int>();

    MatchCollection mc = c.Matches(formula);
    foreach (Match item in mc) {
        int p = 0;
        while (char.IsLetter(item.ToString()[p])) {
            p++;
        }
        work.Add(item.ToString().Substring(0, p), Int32.Parse(item.ToString().Substring(p)));
    }

    MatchCollection ma = a.Matches(modifier);
    foreach (Match item in ma) {
        char action = item.ToString()[0];
        int p = 1;
        while (char.IsLetter(item.ToString()[p])) {
            p++;
        }
        String chem = item.ToString().Substring(1, p - 1);
        int amount = Int32.Parse(item.ToString().Substring(p));
        amount = action == '+' ? amount : amount * -1;

        if (work.ContainsKey(chem)) {
            work[chem] = work[chem] + amount;
        } else {
            work.Add(chem, amount);
        }
    }

    StringBuilder sb = new StringBuilder();
    foreach (String key in work.Keys) {
        sb.Append(key);
        sb.Append(work[key]);
    }

    return sb.ToString();
}

What this does is breaks up the original chemical formula into the element/amount combinations, then splits those and stores them in a dictionary.

It then does the same for each element/amount in the modify string, and alters the dictionary to reflect the changes.

Then it rebuilds the chemical formula from the dictionary and returns the result.

Comments
all valid points
This question has already been answered. Start a new discussion instead.