C# 字符串分数加倍
我需要一个函数来解析用户输入的双倍数字。我不能在客户端做任何事情,也不能改变输入的方式C# 字符串分数加倍,c#,asp.net,string,C#,Asp.net,String,我需要一个函数来解析用户输入的双倍数字。我不能在客户端做任何事情,也不能改变输入的方式 Input | Desired Output "9" | 9 "9 3/4" | 9.75 " 9 1/ 2 " | 9.5 "9 .25" | 9.25 "9,000 1/3" | 9000.33 "1/4" | .25 我看到了这一点,但它使用的是Python,我只是想知道在我花时间编写自己的代码之前,是否有人知道任何奇特的C#处理方法。编写一些
Input | Desired Output
"9" | 9
"9 3/4" | 9.75
" 9 1/ 2 " | 9.5
"9 .25" | 9.25
"9,000 1/3" | 9000.33
"1/4" | .25
我看到了这一点,但它使用的是Python,我只是想知道在我花时间编写自己的代码之前,是否有人知道任何奇特的C#处理方法。编写一些这样的代码看起来并不困难。首先尝试删除所有空格,看看它是否为合法数字。如果不是,找到合法的数字(例如“9 3/4”中的9、3、4,然后做一个简单的算术运算:9+3/4=9.75BCL中没有内置的东西可以做到这一点,但是有很多现有的数字可以做到这一点(尽管在这种特定情况下,这可能会超过顶部)
自己编写一个,对于您发布的有限用例,应该不难。我将使用正则表达式:
Regex re = new Regex(@"^\s*(\d+)(\s*\.(\d*)|\s+(\d+)\s*/\s*(\d+))?\s*$");
string str = " 9 1/ 2 ";
Match m = re.Match(str);
double val = m.Groups[1].Success ? double.Parse(m.Groups[1].Value) : 0.0;
if(m.Groups[3].Success) {
val += double.Parse("0." + m.Groups[3].Value);
} else {
val += double.Parse(m.Groups[4].Value) / double.Parse(m.Groups[5].Value);
}
到目前为止还没有经过测试,但我认为它应该有效
,和。我看到两个部分。第一个空格之前的所有部分都是整数部分。第一个空格之后的所有部分都是小数部分。分离这两个部分后,您可以从小数部分中剥离空格,在/字符上拆分该部分,然后将第一部分除以第二部分(如果有第二部分)。然后将结果添加到积分部分以找到您的答案 此算法应该为每个示例提供正确的结果。它也可能为以下示例提供不正确的结果:“9.25/4”或“9 3/0”,因此这些是需要注意的事项。其他事项包括前导空格、是否允许其他空格、货币符号、是否为“9.25”(无空格)是有效输入,以及如何处理无理分数,如“1/3”、“1/10”(二进制无理)等
我通常不太相信测试驱动的设计(你应该先编写测试,争取100%的覆盖率)对于静态类型语言,但我确实认为单元测试在某些特定情况下有价值,这就是其中的一种情况。我将为一些常见情况和边缘情况组合一些测试,这样您就可以确保您最终使用的任何东西都能正确处理输入以通过测试。我为这项工作编写了以下方法:
private double DoWork(string data)
{
double final = 0;
foreach (string s in data.Split(' '))
{
if (s.Contains('/'))
{
final += double.Parse(s.Split('/')[0]) / double.Parse(s.Split('/')[1]);
}
else
{
double tryparse = 0;
double.TryParse(s, out tryparse);
final += tryparse;
}
}
return final;
}
它对你有用吗
我认为您还可以使用动态编译代码
static void Main(string[] args)
{
var value = "9 3/4";
value = value.Split(' ')[0] + "d + " + value.Split(' ')[1] + "d";
var exp = " public class DynamicComputer { public static double Eval() { return " + value + "; }}";
CodeDomProvider cp = new Microsoft.CSharp.CSharpCodeProvider();
ICodeCompiler icc = cp.CreateCompiler();
CompilerParameters cps = new CompilerParameters();
CompilerResults cres;
cps.GenerateInMemory = true;
cres = icc.CompileAssemblyFromSource(cps, exp);
Assembly asm = cres.CompiledAssembly;
Type t = asm.GetType("DynamicComputer");
double d = (double)t.InvokeMember("Eval",
BindingFlags.InvokeMethod,
null,
null,
null);
Console.WriteLine(d);
Console.Read();
}
以下是我最终使用的:
private double ParseDoubleFromString(string num)
{
//removes multiple spces between characters, cammas, and leading/trailing whitespace
num = Regex.Replace(num.Replace(",", ""), @"\s+", " ").Trim();
double d = 0;
int whole = 0;
double numerator;
double denominator;
//is there a fraction?
if (num.Contains("/"))
{
//is there a space?
if (num.Contains(" "))
{
//seperate the integer and fraction
int firstspace = num.IndexOf(" ");
string fraction = num.Substring(firstspace, num.Length - firstspace);
//set the integer
whole = int.Parse(num.Substring(0, firstspace));
//set the numerator and denominator
numerator = double.Parse(fraction.Split("/".ToCharArray())[0]);
denominator = double.Parse(fraction.Split("/".ToCharArray())[1]);
}
else
{
//set the numerator and denominator
numerator = double.Parse(num.Split("/".ToCharArray())[0]);
denominator = double.Parse(num.Split("/".ToCharArray())[1]);
}
//is it a valid fraction?
if (denominator != 0)
{
d = whole + (numerator / denominator);
}
}
else
{
//parse the whole thing
d = double.Parse(num.Replace(" ", ""));
}
return d;
}
下面的解决方案不适用于负分数。可以通过更改
//is it a valid fraction?
if (denominator != 0)
{
d = whole + (numerator / denominator);
}
to
//is it a valid fraction?
if (denominator != .0)
{
var sign = Math.Sign(whole);
d = whole + sign*(numerator/denominator);
}
你看到问题了吗?如果你删除所有空格,“9 3/4”变成“93/4”。我知道。删除所有空格只是第一次尝试(试图将“9.25”解析为“9.25”)。为了解析“9 3/4”,你必须离开空格。