コード例 #1
0
ファイル: Cell.cs プロジェクト: dperetin/MyExcel
 public void PostaviOvisnosti(Celije cells, string s)
 {
     s = s.ToLower();
     if (s != "")
     {
         string[] celije = s.Split(';');
         foreach (string koo in celije)
         {
             string slovo, broj;
             slovo = Regex.Match(koo, @"[a-z]+").Value;
             broj = Regex.Match(koo, "[0-9]+").Value;
             int c = slovo[0] - 97;
             int r = Convert.ToInt32(broj) - 1;
             KeyValuePair<int, int> i = new KeyValuePair<int, int>(r, c);
             //KeyValuePair<int, int> ova = new KeyValuePair<int, int>(red, stupac);
             if (cells.sveCelije.ContainsKey(i))
             {
                 uFormuli.Add(cells.sveCelije[i]);
             }
             else
             {
                 cells.Dodaj(r, c);
                 uFormuli.Add(cells.sveCelije[i]);
             }
         }
     }
 }
コード例 #2
0
ファイル: Cell.cs プロジェクト: dperetin/MyExcel
        public void evaluateFormula(Celije tCell, Funkcije fje)
        {
            if (this.formula == "")
                return;
            string formula;
            formula = this.formula.ToLower();

            // zamjenjujem oznake celija konkretnim vrijednostima
            // PRETPOSTAVKA: nema razmaka nije dosega
            formula = formula.Replace(" ", "");
            formula = formula.Replace("\r\n", "");

            while (true)
            {
                Match m = Regex.Match(formula, @"[a-z]+[0-9]+:[a-z]+[0-9]+");
                string slovo, broj;
                if (m.Success)
                {
                    string rep = "";
                    string sa = m.Value;
                    string[] oddo = sa.Split(':');
                    slovo = Regex.Match(oddo[0], @"[a-z]+").Value;
                    broj = Regex.Match(oddo[0], "[0-9]+").Value;
                    int c1 = slovo[0] - 97;
                    int r1 = Convert.ToInt32(broj);

                    slovo = Regex.Match(oddo[1], @"[a-z]+").Value;
                    broj = Regex.Match(oddo[1], "[0-9]+").Value;
                    int c2 = slovo[0] - 97;
                    int r2 = Convert.ToInt32(broj);

                    if (c1 == c2 && r1 != r2)
                    {
                        for (int i = r1; i <= r2; i++)
                        {
                            rep += Char.ConvertFromUtf32(c1 + 65) + i.ToString() + ";";

                        }
                    }
                    else if (r1 == r2 && c1 != c2)
                    {
                        for (int i = c1; i <= c2; i++)
                        {
                            rep += Char.ConvertFromUtf32(i + 65) + r1.ToString() + ";";
                        }
                    }
                    else
                    {
                        for (int i = r1; i <= r2; i++)
                            for (int j = c1; j <= c2; j++)
                            {
                                rep += Char.ConvertFromUtf32(j + 65) + i.ToString() + ";";
                            }
                    }
                    rep = rep.TrimEnd(';');
                    formula = formula.Replace(sa, rep);
                }
                else
                {
                    break;
                }
            }

            formula = formula.ToLower();
            while (true)
            {
                Match m = Regex.Match(formula, @"[a-z]+[0-9]+");
                if (m.Success)
                {
                    string cel = m.Value;
                    string slovo = Regex.Match(cel, @"[a-z]+").Value;
                    string broj = Regex.Match(cel, "[0-9]+").Value;
                    int c1 = slovo[0] - 97;
                    int r1 = Convert.ToInt32(broj) - 1;
                    KeyValuePair<int, int> koo = new KeyValuePair<int, int>(r1, c1);

                    if (tCell.sveCelije.ContainsKey(koo) && tCell.sveCelije[koo].Numerical)
                    {
                        string arg = tCell.sveCelije[koo].sadrzaj;
                        double d = double.Parse(arg);
                        if (d < 0)
                        {
                            arg = "(0" + arg+")";
                        }
                        formula = formula.Replace(cel, arg);
                        if (tCell.sveCelije[koo].uFormuli.Contains(this) == false)
                            tCell.sveCelije[koo].uFormuli.Add(this);
                    }
                    else
                    {
                        formula = formula.Replace(cel, "");
                        if (tCell.sveCelije.ContainsKey(koo) == false)
                        {
                            tCell.Dodaj(r1, c1);
                            tCell.sveCelije[koo].uFormuli.Add(this);
                        }
                        else
                        {
                            if (tCell.sveCelije[koo].uFormuli.Contains(this) == false)
                                tCell.sveCelije[koo].uFormuli.Add(this);
                        }
                        Sadrzaj = "NaN";
                        return;
                    }

                }
                else
                {
                    break;
                }
            }

            // razdvajam formulu na tokene

            List<Token> listaTokena = new List<Token>();
            string s = formula.TrimStart('=');
            string function_token = "";
            string zagrada_token = "";
            string separator_token = "";
            string celija_token = "";
            string op_token = "";
            Queue<Token> q = new Queue<Token>();
            Stack<Token> st = new Stack<Token>();
            while (s != "")
            {
                Match m1 = Regex.Match(s, @"^\s*[a-zA-Z]+\s*");
                Match m2 = Regex.Match(s, @"^[)(]");
                Match m3 = Regex.Match(s, @"^;");
                Match m4 = Regex.Match(s, @"^[0-9.,]+");
                Match m5 = Regex.Match(s, @"^[\+\-\*\/\^]");
                if (m1.Success) // FUNKCIJA
                {
                    function_token = m1.Value;
                    s = s.Substring(function_token.Length, s.Length - function_token.Length);
                    listaTokena.Add(new Token("funk", function_token));
                    //continue;
                }

                else if (m2.Success) // ZAGRADA
                {
                    zagrada_token = m2.Value;
                    s = s.Substring(zagrada_token.Length, s.Length - zagrada_token.Length);
                    listaTokena.Add(new Token("zagr", zagrada_token));
                    //continue;
                }

                else if (m3.Success) // SEPARATOR
                {
                    separator_token = m3.Value;
                    s = s.Substring(separator_token.Length, s.Length - separator_token.Length);
                    listaTokena.Add(new Token("sepa", separator_token));
                    //continue;
                }

                else if (m4.Success)
                {
                    celija_token = m4.Value;
                    s = s.Substring(celija_token.Length, s.Length - celija_token.Length);
                    listaTokena.Add(new Token("broj", celija_token));
                    //continue;
                }

                else if (m5.Success) // FUNKCIJA
                {
                    op_token = m5.Value;
                    //st.Push(function_token);
                    s = s.Substring(op_token.Length, s.Length - op_token.Length);
                    Token op = new Token("oper", op_token);
                    op.brArg = 2;
                    if (op_token == "+")
                    {
                        op.prioritet = 0;
                        op.asoc = "L";
                    }
                    else if (op_token == "-")
                    {
                        op.prioritet = 0;
                        op.asoc = "L";
                    }
                    else if (op_token == "*")
                    {
                        op.prioritet = 1;
                        op.asoc = "L";
                    }
                    else if (op_token == "/")
                    {
                        op.prioritet = 1;
                        op.asoc = "L";
                    }
                    else if (op_token == "^")
                    {
                        op.prioritet = 2;
                        op.asoc = "D";
                    }
                    listaTokena.Add(op);
                    //continue;
                }
                else
                {
                    throw new Exception();
                }
            }

            // brojim argumente fja jer imaju varijabilan broj argumenata
            for (int i = 0; i < listaTokena.Count; i++)
            {
                if (listaTokena[i].tip == "funk")
                {
                    int smijemBrojat = -1;
                    for (int j = i + 1; j < listaTokena.Count; j++)
                    {
                        if (smijemBrojat == 0 && listaTokena[j].tip == "sepa")
                        {
                            listaTokena[i].brArg++;
                        }
                        if (listaTokena[j].value == "(")
                        {
                            smijemBrojat++;

                        }
                        if (listaTokena[j].value == ")")
                        {
                            smijemBrojat--;
                        }
                        if (smijemBrojat == -1)
                            break;
                    }
                }
            }

            // Shunting-yard

            foreach (Token t in listaTokena)
            {
                if (t.tip == "oper") // OPERATOR
                {

                    while (st.Count != 0 && st.Peek().tip == "oper" &&
                          ((t.asoc == "L" && t.prioritet <= st.Peek().prioritet) ||
                          (t.asoc == "R" && t.prioritet < st.Peek().prioritet)))
                    {
                        q.Enqueue(st.Pop());
                    }
                    st.Push(t);
                    continue;
                }
                if (t.tip == "funk") // FUNKCIJA
                {

                    st.Push(t);

                    continue;
                }

                if (t.tip == "zagr") // ZAGRADA
                {

                    if (t.value == "(")
                    {
                        st.Push(t);
                    }
                    else if (t.value == ")")
                    {
                        while (st.Peek().value != "(")
                        {
                            q.Enqueue(st.Pop());
                        }
                        st.Pop();

                        if (st.Count != 0 && st.Peek().tip == "funk")
                        {
                            q.Enqueue(st.Pop());
                        }
                    }

                    continue;
                }

                if (t.tip == "sepa") // SEPARATOR
                {

                    while (st.Peek().value != "(")
                    {
                        q.Enqueue(st.Pop());
                    }

                    continue;
                }

                if (t.tip == "broj")
                {

                    q.Enqueue(t);

                    continue;
                }
            }

            while (st.Count != 0)
            {
                q.Enqueue(st.Pop());
            }

            // racunanje izraza

            Stack<double> tmp = new Stack<double>();

            while (q.Count != 0)
            {
                List<double> arg = new List<double>();
                if (q.Peek().tip == "broj")
                {
                    tmp.Push(Double.Parse(q.Dequeue().value));
                    continue;
                }
                if (q.Peek().tip == "funk" || q.Peek().tip == "oper")
                {
                    for (int i = 0; i < q.Peek().brArg; i++)
                    {
                        if (tmp.Count != 0)
                            arg.Add(tmp.Pop());
                    }
                    tmp.Push(fje.SveFunkcije[q.Dequeue().value](arg));
                }
            }
            Sadrzaj = tmp.Pop().ToString();
        }