示例#1
0
        /// <summary>
        /// 数字のみの数式を計算する
        /// </summary>
        /// <param name="f">計算式</param>
        /// <returns>計算結果</returns>
        public static async Task <double> SolveNumFormula(string f)
        {
            f = LaTeXtoFormula(f);

            //monos:単項式ごとに分けられたもの
            var monos = OperateBrackets.FindMonomials(f).ToList();

            monos.Remove("");

            var resmonos = new double[0];

            resmonos = await monos.Select(async (mono) =>
            {
                if (double.TryParse(mono, out double num))//単項式が数字だけなら先に返してしまう
                {
                    return(num);
                }
                else
                {
                    //括弧に隣接する加減算記号を数字として扱う
                    mono = Regex.Replace(mono, "(\\+|\\-)\\(", "${1}1(");
                    mono = Regex.Replace(mono, "(\\+|\\-)\\#", "${1}1*#");

                    var bmap = OperateBrackets.MapingBrackets(mono);

                    //括弧が足りない場合は補完
                    if (bmap.Last() - bmap.First() > 0)
                    {
                        mono += new string(')', bmap.Last() - bmap.First());
                        bmap  = bmap.ToList().Concat(Enumerable.Range(0, bmap.Last() - bmap.First()).Reverse()).ToArray();
                    }

                    //括弧が正常な時の処理
                    if (bmap.First() == bmap.Last())
                    {
                        //演算子で区切る(累乗以外)、括弧はそのまま残す
                        var splitted = OperateBrackets.SplitByOperators(mono);

                        //累乗を計算する
                        while (splitted.Any(x => x.First() == '^'))
                        {
                            var n     = splitted.LastOrDefault(x => x.First() == '^');
                            int index = splitted.LastIndexOf(n);
                            if (index > 0)
                            {
                                string pastn = splitted[index - 1];

                                double pastfigure = 1;
                                double nowfigure  = 1;
                                char opera        = '*';

                                if (pastn.First() == '*' ||
                                    pastn.First() == '/' ||
                                    pastn.First() == '^')
                                {
                                    opera = pastn.First();

                                    if (!double.TryParse(pastn.Substring(1), out pastfigure))
                                    {
                                        pastfigure = await SolveNumFormula(pastn.Substring(2, pastn.Length - 3));
                                    }

                                    if (!double.TryParse(n.Substring(1), out nowfigure))
                                    {
                                        nowfigure = await SolveNumFormula(n.Substring(2, n.Length - 3));
                                    }
                                }
                                else
                                {
                                    if (!double.TryParse(pastn, out pastfigure))
                                    {
                                        pastfigure = await SolveNumFormula(pastn.Substring(1, pastn.Length - 2));
                                    }

                                    if (!double.TryParse(n.Substring(1), out nowfigure))
                                    {
                                        nowfigure = await SolveNumFormula(n.Substring(2, n.Length - 3));
                                    }
                                }

                                splitted.RemoveAt(index);
                                splitted.RemoveAt(index - 1);
                                splitted.Insert(index - 1, opera + Math.Pow(pastfigure, nowfigure).ToString());
                            }
                            else
                            {
                                throw new Exception("累乗でのエラー");
                            }
                        }

                        List <double> Numres = new List <double> {
                        };

                        //各項を処理する
                        foreach (string r in splitted)
                        {
                            string s = r;

                            //最初に"*"がついていたら消す
                            if (s.First() == '*')
                            {
                                s = s.Substring(1);
                            }

                            bool IsInverse = false;
                            if (s.First() == '/')
                            {
                                IsInverse = true;

                                //最初の"/"を消す
                                s = s.Substring(1);
                            }

                            if (s.First() == '#')//関数がある時
                            {
                                string funkname  = Regex.Replace(s, "^#\\$(([a-z|A-Z]|π)*)\\$#.*", "$1");
                                string inBracket = Regex.Replace(s, "^#\\$([a-z|A-Z]|π)*\\$#\\((.*)\\)$", "$2");

                                int[] inbracketmap = OperateBrackets.MapingBrackets(inBracket);

                                string CommaedinBracket = inBracket;
                                int lug = 0;
                                for (int i = 0; i < inBracket.Length; i++)
                                {
                                    if (inBracket[i] == ',' && inbracketmap[i] == 0)
                                    {
                                        CommaedinBracket = CommaedinBracket.Insert(i + lug++, ",");
                                    }
                                }

                                List <double> inBracketValues = (await CommaedinBracket.Split(new string[1] {
                                    ",,"
                                }, StringSplitOptions.None)
                                                                 .Select(async(x) => await SolveNumFormula(x))
                                                                 .WhenAll()).ToList();

                                if (IsInverse)
                                {
                                    Numres.Add(1 / await FuncItemService.RunFunc(inBracketValues, funkname));
                                }
                                else
                                {
                                    Numres.Add(await FuncItemService.RunFunc(inBracketValues, funkname));
                                }
                            }
                            else if (s.First() == '(')//括弧に囲まれたものの時
                            {
                                if (IsInverse)
                                {
                                    Numres.Add(1 / await SolveNumFormula(s.Substring(1, s.Length - 2)));
                                }
                                else
                                {
                                    Numres.Add(await SolveNumFormula(s.Substring(1, s.Length - 2)));
                                }
                            }
                            else//数字のみの時
                            {
                                if (IsInverse)
                                {
                                    Numres.Add(1 / double.Parse(s));
                                }
                                else
                                {
                                    Numres.Add(double.Parse(s));
                                }
                            }
                        }
                        return(Numres.Aggregate((now, next) => now *next));
                    }
                    else
                    {
                        throw new Exception(AppResources.BracketsWrong);
                    }
                }
            }).WhenAll();


            return(resmonos.Sum());
        }
示例#2
0
 public async Task OnNavigatedTo(INavigationParameters parameters)
 {
     FuncItems = await FuncItemService.GetList();
 }
示例#3
0
        /// <summary>
        /// 数式の指定された部分に指定された文字を追加する
        /// </summary>
        /// <param name="nowformula"></param>
        /// <param name="figure"></param>
        /// <param name="locate"></param>
        /// <returns></returns>
        public async static Task <(string, int)> AddfigureManipulation(string nowformula, string figure, int locate)
        {
            string NowFormula = nowformula;

            //一つ前と二つ前の文字を抽出する
            //存在しなかった場合は""となる
            string PastChar     = "";
            string PastPastChar = "";

            try
            {
                PastChar     = NowFormula.Last().ToString();
                PastPastChar = NowFormula.Substring(NowFormula.Length - 2, 1);
            }
            catch { }

            if (figure == "/")//割り算が押された場合は分数を挿入する
            {
                if (NowFormula == "" || PastChar == "{" || PastChar == "(")
                {
                    NowFormula += "~frac{}{}";
                    locate++;
                }
                else
                {
                    int back = 0;
                    for (int i = NowFormula.Length - 1; i >= 0; i--)
                    {
                        if (Regex.IsMatch(NowFormula[i].ToString(), "^(\\+|\\-|\\*|/|\\(|\\{)$"))
                        {
                            back = i + 1;
                            break;
                        }
                        else if (NowFormula[i] == ')')
                        {
                            var locates = OperateBrackets.LocationofInsideofBracket(NowFormula, i);
                            i = locates.Item1;

                            if (i != 0 && NowFormula[i - 1] == '#')
                            {
                                for (int j = i - 2; j >= 0; j--)
                                {
                                    if (NowFormula[j] == '#')
                                    {
                                        i = j;
                                        break;
                                    }
                                }
                            }
                        }
                        else if (NowFormula[i] == '}')
                        {
                            var locates = OperateBrackets.LocationofInsideofBracket(NowFormula, i, "{}");
                            i = locates.Item1;
                        }
                    }

                    var Numor = NowFormula.Substring(back);
                    if (NowFormula != "" && NowFormula.Length > back)
                    {
                        NowFormula = NowFormula.Remove(back);
                    }


                    NowFormula = NowFormula + "~frac{" + Numor + "}{}";

                    locate += 2;
                }
            }
            else if (figure == "root")
            {
                NowFormula += "~root{2}{}";

                locate += 3;
            }
            else if (figure == "^")
            {
                if (!Regex.IsMatch(PastChar, "^(\\+|\\-|\\*|/|\\^|\\(|\\{)$"))
                {
                    NowFormula += "^{}";

                    locate += 1;
                }
            }
            else if (PastChar == "-" && //前が-
                     Regex.IsMatch(PastPastChar, "^(\\*|/|\\^|\\()$") &&//前の前が*,/,^,(
                     Regex.IsMatch(figure, "^(\\+|\\-|\\*|/|\\^|\\))$"))//今のが+,-,*,/,^,)
            {
                switch (figure)
                {
                case "+":
                    (NowFormula, locate) = BackSpace(NowFormula, locate);
                    break;

                case "-":
                    (NowFormula, locate) = BackSpace(NowFormula, locate);
                    NowFormula          += figure;
                    break;

                case "*":
                case "/":
                case "^":
                    (NowFormula, locate) = BackSpace(NowFormula, locate);
                    (NowFormula, locate) = BackSpace(NowFormula, locate);
                    NowFormula          += figure;
                    break;

                case ")":
                    (NowFormula, locate) = BackSpace(NowFormula, locate);
                    (NowFormula, locate) = BackSpace(NowFormula, locate);
                    break;

                default:
                    Trace.WriteLine("内部エラー");
                    break;
                }

                locate++;
            }
            else if (Regex.IsMatch(PastChar, "^(\\+|\\-)$") &&//前が+,-
                     Regex.IsMatch(figure, "^(\\+|\\-|\\*|/|\\^|\\))$"))//今のが+,-,*,/,^,)
            {
                (NowFormula, locate) = BackSpace(NowFormula, locate);
                NowFormula          += figure;

                locate++;
            }
            else if (Regex.IsMatch(PastChar, "^(\\*|/|\\^|\\()$") &&//前が*,/,^,(
                     Regex.IsMatch(figure, "^(\\+|\\*|/|\\^|\\))$"))//今のが+,*,/,^,)
            {
                (NowFormula, locate) = BackSpace(NowFormula, locate);
                NowFormula          += figure;

                locate++;
            }
            else if (figure == "invert" && !Regex.IsMatch(PastChar, "^(\\+|\\-|\\*|/|\\^|\\()$"))//逆数ボタンを押した時
            {
                NowFormula += "^{-1}";

                locate += 4;
            }
            else if (figure == "invert")
            {
            }
            else if (figure.First() == '~')
            {
                if (await FuncItemService.IsExist(figure.Substring(1)))
                {
                    var count = (await FuncItemService.GetByName(figure.Substring(1))).CharCount;

                    if (count == 0)
                    {
                        NowFormula += figure + "{}";
                        locate     += 1;
                    }
                    else
                    {
                        NowFormula += figure + (new StringBuilder()).Insert(0, "{}", count).ToString();
                    }
                }

                locate += 1;
            }
            else if (figure == "." && PastChar == ".")//小数点
            {
            }
            else
            {
                NowFormula += figure;

                locate++;
            }

            return(NowFormula, locate);
        }
示例#4
0
        private async Task ButtonClicked()
        {
            await FuncItemService.Add(DateTime.Now.ToShortDateString(), "Hello");

            FuncItems = await FuncItemService.GetList();
        }