Skip to content

Commit a03b040

Browse files
author
linzhijun
committed
fix
1 parent 010fd48 commit a03b040

File tree

1 file changed

+98
-49
lines changed

1 file changed

+98
-49
lines changed

csharp/ToolGood.Algorithm2/Internals/MathVisitor.cs

Lines changed: 98 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ namespace ToolGood.Algorithm.Internals
1515
{
1616
class MathVisitor : AbstractParseTreeVisitor<Operand>, ImathVisitor<Operand>
1717
{
18-
private static readonly Regex sumifRegex = new Regex(@"(<|<=|>|>=|=|==|===|!=|!==|<>) *([-+]?\d+(\.(\d+)?)?)", RegexOptions.Compiled);
1918
public event Func<string, Operand> GetParameter;
2019
public event Func<string, List<Operand>, Operand> DiyFunction;
2120
public int excelIndex;
@@ -2241,8 +2240,8 @@ public virtual Operand VisitAVERAGE_fun(mathParser.AVERAGE_funContext context)
22412240

22422241
public virtual Operand VisitAVERAGEIF_fun(mathParser.AVERAGEIF_funContext context)
22432242
{
2244-
var args = new List<Operand>();
2245-
foreach (var item in context.expr()) { var aa = item.Accept(this); if (aa.IsError) { return aa; } args.Add(aa); }
2243+
var exprs = context.expr(); var args = new List<Operand>(exprs.Length);
2244+
for (int i = 0; i < exprs.Length; i++) { var aa = this.Visit(exprs[i]); if (aa.IsError) { return aa; } args.Add(aa); }
22462245

22472246
List<decimal> list = new List<decimal>();
22482247
var o = F_base_GetList(args[0], list);
@@ -2260,17 +2259,18 @@ public virtual Operand VisitAVERAGEIF_fun(mathParser.AVERAGEIF_funContext contex
22602259
decimal sum;
22612260
int count;
22622261
if (args[1].Type == OperandType.NUMBER) {
2263-
count = MathVisitor.F_base_countif(list, args[1].NumberValue);
2262+
count = F_base_countif(list, args[1].NumberValue);
22642263
sum = count * args[1].NumberValue;
22652264
} else {
22662265
if (decimal.TryParse(args[1].TextValue.Trim(), NumberStyles.Any, CultureInfo.InvariantCulture, out decimal d)) {
2267-
count = MathVisitor.F_base_countif(list, d);
2268-
sum = MathVisitor.F_base_sumif(list, '=' + args[1].TextValue.Trim(), sumdbs);
2266+
count = F_base_countif(list, d);
2267+
sum = F_base_sumif(list, d, sumdbs);
22692268
} else {
22702269
var sunif = args[1].TextValue.Trim();
2271-
if (sumifRegex.IsMatch(sunif)) {
2272-
count = MathVisitor.F_base_countif(list, sunif);
2273-
sum = MathVisitor.F_base_sumif(list, sunif, sumdbs);
2270+
var m2 = sumifMatch(sunif);
2271+
if (m2 != null) {
2272+
count = F_base_countif(list, m2.Item1, m2.Item2);
2273+
sum = F_base_sumif(list, m2.Item1, m2.Item2, sumdbs);
22742274
} else {
22752275
return Operand.Error("Function AVERAGE parameter 2 error!");
22762276
}
@@ -2328,23 +2328,24 @@ public virtual Operand VisitCOUNT_fun(mathParser.COUNT_funContext context)
23282328
}
23292329
public virtual Operand VisitCOUNTIF_fun(mathParser.COUNTIF_funContext context)
23302330
{
2331-
var args = new List<Operand>();
2332-
foreach (var item in context.expr()) { var aa = item.Accept(this); if (aa.IsError) { return aa; } args.Add(aa); }
2331+
var exprs = context.expr(); var args = new List<Operand>(exprs.Length);
2332+
for (int i = 0; i < exprs.Length; i++) { var aa = this.Visit(exprs[i]); if (aa.IsError) { return aa; } args.Add(aa); }
23332333

23342334
List<decimal> list = new List<decimal>();
23352335
var o = F_base_GetList(args[0], list);
23362336
if (o == false) { return Operand.Error("Function COUNTIF parameter error!"); }
23372337

23382338
int count;
23392339
if (args[1].Type == OperandType.NUMBER) {
2340-
count = MathVisitor.F_base_countif(list, args[1].NumberValue);
2340+
count = F_base_countif(list, args[1].NumberValue);
23412341
} else {
23422342
if (decimal.TryParse(args[1].TextValue.Trim(), NumberStyles.Any, CultureInfo.InvariantCulture, out decimal d)) {
2343-
count = MathVisitor.F_base_countif(list, d);
2343+
count = F_base_countif(list, d);
23442344
} else {
23452345
var sunif = args[1].TextValue.Trim();
2346-
if (sumifRegex.IsMatch(sunif)) {
2347-
count = MathVisitor.F_base_countif(list, sunif);
2346+
var m2 = sumifMatch(sunif);
2347+
if (m2 != null) {
2348+
count = F_base_countif(list, m2.Item1, m2.Item2);
23482349
} else {
23492350
return Operand.Error("Function COUNTIF parameter 2 error!");
23502351
}
@@ -2368,8 +2369,8 @@ public virtual Operand VisitSUM_fun(mathParser.SUM_funContext context)
23682369
}
23692370
public virtual Operand VisitSUMIF_fun(mathParser.SUMIF_funContext context)
23702371
{
2371-
var args = new List<Operand>();
2372-
foreach (var item in context.expr()) { var aa = item.Accept(this); if (aa.IsError) { return aa; } args.Add(aa); }
2372+
var exprs = context.expr(); var args = new List<Operand>(exprs.Length);
2373+
for (int i = 0; i < exprs.Length; i++) { var aa = this.Visit(exprs[i]); if (aa.IsError) { return aa; } args.Add(aa); }
23732374

23742375
List<decimal> list = new List<decimal>();
23752376
var o = F_base_GetList(args[0], list);
@@ -2386,14 +2387,15 @@ public virtual Operand VisitSUMIF_fun(mathParser.SUMIF_funContext context)
23862387

23872388
decimal sum;
23882389
if (args[1].Type == OperandType.NUMBER) {
2389-
sum = MathVisitor.F_base_countif(list, args[1].NumberValue) * args[1].NumberValue;
2390+
sum = F_base_countif(list, args[1].NumberValue) * args[1].NumberValue;
23902391
} else {
2391-
if (decimal.TryParse(args[1].TextValue.Trim(), NumberStyles.Any, CultureInfo.InvariantCulture, out _)) {
2392-
sum = MathVisitor.F_base_sumif(list, '=' + args[1].TextValue.Trim(), sumdbs);
2392+
if (decimal.TryParse(args[1].TextValue.Trim(), NumberStyles.Any, CultureInfo.InvariantCulture, out decimal d)) {
2393+
sum = F_base_sumif(list, d, sumdbs);
23932394
} else {
23942395
var sunif = args[1].TextValue.Trim();
2395-
if (sumifRegex.IsMatch(sunif)) {
2396-
sum = MathVisitor.F_base_sumif(list, sunif, sumdbs);
2396+
var m2 = sumifMatch(sunif);
2397+
if (m2 != null) {
2398+
sum = F_base_sumif(list, m2.Item1, m2.Item2, sumdbs);
23972399
} else {
23982400
return Operand.Error("Function SUMIF parameter 2 error!");
23992401
}
@@ -2809,44 +2811,95 @@ public virtual Operand VisitWEIBULL_fun(mathParser.WEIBULL_funContext context)
28092811
return Operand.Create(ExcelFunctions.WEIBULL((double)x, (double)shape, (double)scale, state));
28102812
}
28112813

2814+
private static Tuple<string, decimal> sumifMatch(string s)
2815+
{
2816+
var c = s[0];
2817+
if (c == '>' || c == '>') {
2818+
if (s.Length > 1 && (s[1] == '=' || s[1] == '=')) {
2819+
if (decimal.TryParse(s.AsSpan(2).Trim(), out decimal d)) {
2820+
return Tuple.Create(">=", d);
2821+
}
2822+
} else if (decimal.TryParse(s.AsSpan(1).Trim(), out decimal d)) {
2823+
return Tuple.Create(">", d);
2824+
}
2825+
} else if (c == '<' || c < '<') {
2826+
if (s.Length > 1 && (s[1] == '=' || s[1] == '=')) {
2827+
if (decimal.TryParse(s.AsSpan(2).Trim(), out decimal d)) {
2828+
return Tuple.Create("<=", d);
2829+
}
2830+
} else if (s.Length > 1 && (s[1] == '>' || s[1] == '>')) {
2831+
if (decimal.TryParse(s.AsSpan(2).Trim(), out decimal d)) {
2832+
return Tuple.Create("!=", d);
2833+
}
2834+
} else if (decimal.TryParse(s.AsSpan(1).Trim(), out decimal d)) {
2835+
return Tuple.Create("<", d);
2836+
}
2837+
} else if (c == '=' || c == '=') {
2838+
var index = 1;
2839+
if (s.Length > 1 && (s[1] == '=' || s[1] == '=')) {
2840+
index = 2;
2841+
if (s.Length > 2 && (s[2] == '=' || s[2] == '=')) {
2842+
index = 3;
2843+
}
2844+
}
2845+
if (decimal.TryParse(s.AsSpan(index).Trim(), out decimal d)) {
2846+
return Tuple.Create("=", d);
2847+
}
2848+
} else if (c == '!' || c == '!') {
2849+
var index = 1;
2850+
if (s.Length > 1 && (s[1] == '=' || s[1] == '=')) {
2851+
index = 2;
2852+
if (s.Length > 2 && (s[2] == '=' || s[2] == '=')) {
2853+
index = 3;
2854+
}
2855+
}
2856+
if (decimal.TryParse(s.AsSpan(index).Trim(), out decimal d)) {
2857+
return Tuple.Create("!=", d);
2858+
}
2859+
}
2860+
return null;
2861+
}
28122862
private static int F_base_countif(List<decimal> dbs, decimal d)
28132863
{
28142864
int count = 0;
2815-
//d = Math.Round(d, 12, MidpointRounding.AwayFromZero);
2816-
foreach (var item in dbs) {
2865+
for (int i = 0; i < dbs.Count; i++) {
2866+
var item = dbs[i];
28172867
if (item == d) {
28182868
count++;
28192869
}
2820-
//if (Math.Round(item, 12, MidpointRounding.AwayFromZero) == d) {
2821-
// count++;
2822-
//}
28232870
}
28242871
return count;
28252872
}
2826-
private static int F_base_countif(List<decimal> dbs, string s)
2873+
private static int F_base_countif(List<decimal> dbs, string s, decimal d)
28272874
{
2828-
var m = sumifRegex.Match(s);
2829-
var d = decimal.Parse(m.Groups[2].Value, NumberStyles.Any, CultureInfo.InvariantCulture);
2830-
var ss = m.Groups[1].Value;
28312875
int count = 0;
2832-
2833-
foreach (var item in dbs) {
2834-
if (MathVisitor.F_base_compare(item, d, ss)) {
2876+
for (int i = 0; i < dbs.Count; i++) {
2877+
var item = dbs[i];
2878+
if (F_base_compare(item, d, s)) {
28352879
count++;
28362880
}
28372881
}
28382882
return count;
28392883
}
2840-
2841-
private static decimal F_base_sumif(List<decimal> dbs, string s, List<decimal> sumdbs)
2884+
private static decimal F_base_sumif(List<decimal> dbs, decimal d, List<decimal> sumdbs)
28422885
{
2843-
var m = sumifRegex.Match(s);
2844-
var d = decimal.Parse(m.Groups[2].Value, NumberStyles.Any, CultureInfo.InvariantCulture);
2845-
var ss = m.Groups[1].Value;
28462886
decimal sum = 0;
2847-
28482887
for (int i = 0; i < dbs.Count; i++) {
2849-
if (MathVisitor.F_base_compare(dbs[i], d, ss)) {
2888+
var item = dbs[i];
2889+
if (item == d) {
2890+
sum += sumdbs[i];
2891+
}
2892+
//if (Math.Round(item, 10, MidpointRounding.AwayFromZero) == d) {
2893+
// sum += item;
2894+
//}
2895+
}
2896+
return sum;
2897+
}
2898+
private static decimal F_base_sumif(List<decimal> dbs, string s, decimal d, List<decimal> sumdbs)
2899+
{
2900+
decimal sum = 0;
2901+
for (int i = 0; i < dbs.Count; i++) {
2902+
if (F_base_compare(dbs[i], d, s)) {
28502903
sum += sumdbs[i];
28512904
}
28522905
}
@@ -2873,8 +2926,7 @@ private static bool F_base_compare(decimal a, decimal b, string ss)
28732926
return a != b;
28742927
//return Math.Round(a - b, 12, MidpointRounding.AwayFromZero) != 0;
28752928
}
2876-
2877-
private bool F_base_GetList(List<Operand> args, List<decimal> list)
2929+
private static bool F_base_GetList(List<Operand> args, List<decimal> list)
28782930
{
28792931
foreach (var item in args) {
28802932
if (item.Type == OperandType.NUMBER) {
@@ -2895,7 +2947,7 @@ private bool F_base_GetList(List<Operand> args, List<decimal> list)
28952947
}
28962948
return true;
28972949
}
2898-
private bool F_base_GetList(Operand args, List<decimal> list)
2950+
private static bool F_base_GetList(Operand args, List<decimal> list)
28992951
{
29002952
if (args.IsError) { return false; }
29012953
if (args.Type == OperandType.NUMBER) {
@@ -2915,8 +2967,7 @@ private bool F_base_GetList(Operand args, List<decimal> list)
29152967
}
29162968
return true;
29172969
}
2918-
2919-
private bool F_base_GetList(Operand args, List<string> list)
2970+
private static bool F_base_GetList(Operand args, List<string> list)
29202971
{
29212972
if (args.IsError) { return false; }
29222973
if (args.Type == OperandType.ARRARY) {
@@ -2934,9 +2985,7 @@ private bool F_base_GetList(Operand args, List<string> list)
29342985
}
29352986
return true;
29362987
}
2937-
2938-
2939-
private bool F_base_GetList(List<Operand> args, List<string> list)
2988+
private static bool F_base_GetList(List<Operand> args, List<string> list)
29402989
{
29412990
foreach (var item in args) {
29422991
if (item.Type == OperandType.ARRARY) {

0 commit comments

Comments
 (0)