private double GetIntValue(List <string> matchStrs) { var isEnd = new bool[matchStrs.Count]; for (var i = 0; i < isEnd.Length; i++) { isEnd[i] = false; } double tempValue = 0; long endFlag = 1; //Scan from end to start, find the end word for (var i = matchStrs.Count - 1; i >= 0; i--) { if (RoundNumberSet.Contains(matchStrs[i])) { //if false,then continue //You will meet hundred first, then thousand. if (endFlag > config.RoundNumberMap[matchStrs[i]]) { continue; } isEnd[i] = true; endFlag = config.RoundNumberMap[matchStrs[i]]; } } if (endFlag == 1) { var tempStack = new Stack <double>(); var oldSym = ""; foreach (var matchStr in matchStrs) { var isCardinal = config.CardinalNumberMap.ContainsKey(matchStr); var isOrdinal = config.OrdinalNumberMap.ContainsKey(matchStr); if (isCardinal || isOrdinal) { var matchValue = isCardinal ? config.CardinalNumberMap[matchStr] : config.OrdinalNumberMap[matchStr]; //This is just for ordinal now. Not for fraction ever. if (isOrdinal) { double fracPart = config.OrdinalNumberMap[matchStr]; if (tempStack.Any()) { var intPart = tempStack.Pop(); // if intPart >= fracPart, it means it is an ordinal number // it begins with an integer, ends with an ordinal // e.g. ninety-ninth if (intPart >= fracPart) { tempStack.Push(intPart + fracPart); } // another case of the type is ordinal // e.g. three hundredth else { while (tempStack.Any()) { intPart = intPart + tempStack.Pop(); } tempStack.Push(intPart * fracPart); } } else { tempStack.Push(fracPart); } } else if (config.CardinalNumberMap.ContainsKey(matchStr)) { if (oldSym.Equals("-")) { var sum = tempStack.Pop() + matchValue; tempStack.Push(sum); } else if (oldSym.Equals(config.WrittenIntegerSeparatorTexts.First()) || tempStack.Count() < 2) { tempStack.Push(matchValue); } else if (tempStack.Count() >= 2) { var sum = tempStack.Pop() + matchValue; sum = tempStack.Pop() + sum; tempStack.Push(sum); } } } else { var complexValue = config.ResolveCompositeNumber(matchStr); if (complexValue != 0) { tempStack.Push(complexValue); } } oldSym = matchStr; } foreach (var stackValue in tempStack) { tempValue += stackValue; } } else { var lastIndex = 0; double mulValue = 1; double partValue = 1; for (var i = 0; i < isEnd.Length; i++) { if (isEnd[i]) { mulValue = config.RoundNumberMap[matchStrs[i]]; partValue = 1; if (i != 0) { partValue = GetIntValue(matchStrs.GetRange(lastIndex, i - lastIndex)); } tempValue += mulValue * partValue; lastIndex = i + 1; } } //Calculate the part like "thirty-one" mulValue = 1; if (lastIndex != isEnd.Length) { partValue = GetIntValue(matchStrs.GetRange(lastIndex, isEnd.Length - lastIndex)); tempValue += mulValue * partValue; } } return(tempValue); }
// Same behavior as base but accounts for regional Hindi cases like डेढ/सवा/ढाई public override double GetIntValue(List <string> matchStrs) { var isEnd = new bool[matchStrs.Count]; for (var i = 0; i < isEnd.Length; i++) { isEnd[i] = false; } double tempValue = 0; long endFlag = 1; // Scan from end to start, find the end word for (var i = matchStrs.Count - 1; i >= 0; i--) { var matchI = matchStrs[i].ToLowerInvariant(); if (RoundNumberSet.Contains(matchI)) { var mappedValue = Config.RoundNumberMap[matchI]; // If false, then continue. Will meet hundred first, then thousand. if (endFlag > mappedValue) { continue; } isEnd[i] = true; endFlag = mappedValue; } } // If no multiplier found if (endFlag == 1) { var tempStack = new Stack <double>(); var oldSym = string.Empty; foreach (var matchStr in matchStrs) { var isCardinal = Config.CardinalNumberMap.ContainsKey(matchStr); var isOrdinal = Config.OrdinalNumberMap.ContainsKey(matchStr); if (isCardinal || isOrdinal) { var matchValue = isCardinal ? Config.CardinalNumberMap[matchStr] : Config.OrdinalNumberMap[matchStr]; // This is just for ordinal now. Not for fractions. if (isOrdinal) { double fracPart = Config.OrdinalNumberMap[matchStr]; if (tempStack.Any()) { var intPart = tempStack.Pop(); // If intPart >= fracPart, it means it is an ordinal number // it begins with an integer, ends with an ordinal // e.g. ninety-ninth if (intPart >= fracPart) { tempStack.Push(intPart + fracPart); } else { // Another case where the type is ordinal // e.g. three hundredth while (tempStack.Any()) { intPart = intPart + tempStack.Pop(); } tempStack.Push(intPart * fracPart); } } else { tempStack.Push(fracPart); } } else if (Config.CardinalNumberMap.ContainsKey(matchStr)) { if (oldSym.Equals("-", StringComparison.Ordinal)) { var sum = tempStack.Pop() + matchValue; tempStack.Push(sum); } else if (oldSym.Equals(Config.WrittenIntegerSeparatorTexts.First(), StringComparison.Ordinal) || tempStack.Count < 2) { tempStack.Push(matchValue); } else if (tempStack.Count >= 2) { var sum = tempStack.Pop() + matchValue; sum = tempStack.Pop() + sum; tempStack.Push(sum); } } } else { // Used to parse regional Hindi cases like डेढ/सवा/ढाई // They are Indian Language specific cases and holds various meaning when prefixed with Number unit. var complexVal = Config.ResolveUnitCompositeNumber(matchStr); if (complexVal != 0) { tempStack.Push(complexVal); } var complexValue = Config.ResolveCompositeNumber(matchStr); if (complexValue != 0) { tempStack.Push(complexValue); } } oldSym = matchStr; } foreach (var stackValue in tempStack) { tempValue += stackValue; } } else { var lastIndex = 0; double mulValue = 1; double partValue = 1; for (var i = 0; i < isEnd.Length; i++) { if (isEnd[i]) { mulValue = Config.RoundNumberMap[matchStrs[i]]; partValue = 1; if (i != 0) { partValue = GetIntValue(matchStrs.GetRange(lastIndex, i - lastIndex)); } tempValue += mulValue * partValue; lastIndex = i + 1; } } // Calculate the part like "thirty-one" mulValue = 1; if (lastIndex != isEnd.Length) { partValue = GetIntValue(matchStrs.GetRange(lastIndex, isEnd.Length - lastIndex)); tempValue += mulValue * partValue; } } return(tempValue); }