/// <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()); }
public async Task OnNavigatedTo(INavigationParameters parameters) { FuncItems = await FuncItemService.GetList(); }
/// <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); }
private async Task ButtonClicked() { await FuncItemService.Add(DateTime.Now.ToShortDateString(), "Hello"); FuncItems = await FuncItemService.GetList(); }