###定义公式解析的问题## 谢谢! 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 using System;namespace dyemp.Components{ /// <summary> /// 内容描述: 通过设置的字符串公式实现四则混合运算 /// 公式要求: 1.公式中不能存在空格 /// 公式要求: 2.公式中运算符间隔的字串解释为字段名 /// 公式要求: 3.公式中运算符间隔的字串需要解释为数值的部份可在数值前加'#'号 /// 公式要求: 例:(abc+bcd)*#15.6 abc,bcd解释为字段名,#15.6解释为数字15.6 /// 公式要求: 4.公式中可包括的运算符: '+','-','*','/','()' /// /// 使用说明: 1.创建CAccount.AccountString事件对应的函数,如: /// 使用说明: private decimal Account(string strAccount) /// 使用说明: { /// 使用说明: ...... /// 使用说明: } /// 使用说明: 2.在需要处理的函数中添加如下方法: /// 使用说明: (1)实例化委托StringToDecimal,如: /// 使用说明: StringToDecimal STD = new StringToDecimal(this.Account); /// 使用说明: (2)将实例化的委托STD添加到CAccount.AccountString事件中去,如: /// 使用说明: CAccount.AccountString += STD; /// 使用说明: (3)执行CAccount.ReMoveBracket方法得到返回值,如: /// 使用说明: textBox8.Text = CAccount.ReMoveBracket("(Box1+Box2)*Box3").ToString("F"); /// 使用说明: (4)将实例化的委托STD从CAccount.AccountString事件中删除,如: /// 使用说明: CAccount.AccountString -= STD; /// </summary> public class CAccount { /// <summary> /// 功能简述: 事件定义为公式运算类的公式字串中字段名转换为数值 /// </summary> public event StringToDecimal AccountString; /// <summary> /// 功能简述: 实现公式计算的主入口函数 /// 实现方法: 计算时先去除公式中的括号,去括号的规则如下 /// 实现方法: 1.先查找公式中的最右边的左括号,然后查找其近临的右括号 /// 实现方法: 2.将这一组括号中的字符串取出并交接Account函数计算. /// 实现方法: 3.将字符串的括号及括号中的字符替换为计算结果.计算结果转为字串并前加'#'号 /// 实现方法: 4.循环上诉过程直到没有括号为止 /// 实现方法: 5.将最后的公式字串交由Account函数计算并返回结果 /// </summary> /// <param name="strFormulary">公式</param> /// <returns>结果</returns> public decimal ReMoveBracket(string strFormulary) { //定义一个字串,用于存贮strFormulary串的备份,并用其进行计算 string strValue = strFormulary; //iLeftIndex存贮左括号的位置,iRightIndex存贮右括号的位置 int iLeftIndex = 0,iRightIndex = 0; //循环,用于去除所有括号 while (iLeftIndex != -1) { //查找最右的左括号 iLeftIndex = strValue.LastIndexOf('('); //如果找到则查找其后的右括号 if (iLeftIndex != -1) { //查找其后的右括号 iRightIndex =strValue.Substring(iLeftIndex + 1).IndexOf(')'); //计算括号中的公式并重新拼接公式 strValue = strValue.Substring (0,iLeftIndex) + "#" + Account(strValue.Substring(iLeftIndex + 1,iRightIndex)).ToString("F") + strValue.Substring(iLeftIndex + iRightIndex + 2); } } //进行最终结果的计算 return Account(strValue); } /// <summary> /// 功能简述: 此函数为递归函数.用以实现公式计算 /// 实现方法: 1.函数运行时依次查找'+','-','*','/'运算符号 /// 实现方法: 当找到对应的运算符号时将公式拆分为两个子公式 /// 实现方法: 对应的'+','-','*','/'运算并将两个子串压入递归直到运算结束为止 /// 实现方法: 2.'+','-','*','/'运算符号先后顺序说明: /// 实现方法: (1) '+','-'号无特定的顺序 /// 实现方法: (2) '*','/'号无特定的顺序 /// 实现方法: (3) '+','-'号放在'*','/'号后,理由:'*','/'号运算优先级高于 /// 实现方法: '+','-'号.递归过程实际上是堆栈操作.先进入递归后执行. /// 实现方法: (4) 查找顺序为从后向前查找,以利用递归操作实现从左向右计算 /// 实现方法: 3.函数最终将字串解释由AccountString事件完成.(即调用用户代码) /// </summary> /// <param name="strFormulary">公式</param> /// <returns>结果</returns> private decimal Account(string strFormulary) { //存贮计算结果 decimal deValue = 0; //存贮运算符位置 int iIndex = 0; //处理'+'号 iIndex = strFormulary.LastIndexOf("+"); if (iIndex != -1) { deValue = Account(strFormulary.Substring (0, iIndex)) + Account(strFormulary.Substring (iIndex + 1)); return deValue; } //处理'-'号 iIndex = strFormulary.Length - 1; //加循环,用以排除数值中(如:#-23.45)的'-'号,防止数值在'-'号前 while (true) { //在索引(Index)后查找'-'号 iIndex = strFormulary.LastIndexOf('-', iIndex - 1); //找到'-'号 if (iIndex != -1) { //判断'-'号是否是数值中的'-'号,即'-'号前是否有'#'号,如不是则继续执行 if (strFormulary.Substring(iIndex - 1 , 1) != "#") { //进行公式计算 deValue = Account(strFormulary.Substring (0, iIndex)) - Account(strFormulary.Substring (iIndex + 1)); return deValue; } } else { break; } } //处理'*'号 iIndex = strFormulary.LastIndexOf('*'); if (iIndex != -1) { deValue = Account(strFormulary.Substring (0, iIndex)) * Account(strFormulary.Substring (iIndex + 1)); return deValue; } //处理'/'号 iIndex = strFormulary.LastIndexOf('/'); if (iIndex != -1) { deValue = Account(strFormulary.Substring (0, iIndex)) / Account(strFormulary.Substring (iIndex + 1)); return deValue; } //如果为数字格式则返回数值(数字格式如:#123.45) if (strFormulary.Substring(0,1) == "#") { return Convert.ToDecimal(strFormulary.Substring(1)); } //返回字符串对应的数值,AccountString为事件对应的委托代码 return AccountString (strFormulary); } } /// <summary> /// 功能简述: 为公式运算类的公式字串中字段名转换为数值提供的委托 /// </summary> public delegate decimal StringToDecimal(string strItem);} superhood(大盗阿飞) 代码干什么用的? 好的,谢谢了--------------superhood(大盗阿飞) 默认定义了#define DEBUG 不是说编译之后能提高速度吗?? Global问题 一个奇怪的,页面跳转问题 请教一个问题~! gridview中两个dropdownlist,两个dropdownlist要实现联动? 各位高手,帮小弟看看,实在是搞不定了。。。。。先谢谢了 DataGrid 控件中实现超级链接。 checkbox在dataGrid控件中的应用?拜托高手请进,很急 gridview 分页后隐藏列 问题求解:简述asp.net与asp的区别 如何用另外的控件在后台代码中设置网页calendar控件的年月日值
{
/// <summary>
/// 内容描述: 通过设置的字符串公式实现四则混合运算
/// 公式要求: 1.公式中不能存在空格
/// 公式要求: 2.公式中运算符间隔的字串解释为字段名
/// 公式要求: 3.公式中运算符间隔的字串需要解释为数值的部份可在数值前加'#'号
/// 公式要求: 例:(abc+bcd)*#15.6 abc,bcd解释为字段名,#15.6解释为数字15.6
/// 公式要求: 4.公式中可包括的运算符: '+','-','*','/','()'
///
/// 使用说明: 1.创建CAccount.AccountString事件对应的函数,如:
/// 使用说明: private decimal Account(string strAccount)
/// 使用说明: {
/// 使用说明: ......
/// 使用说明: }
/// 使用说明: 2.在需要处理的函数中添加如下方法:
/// 使用说明: (1)实例化委托StringToDecimal,如:
/// 使用说明: StringToDecimal STD = new StringToDecimal(this.Account);
/// 使用说明: (2)将实例化的委托STD添加到CAccount.AccountString事件中去,如:
/// 使用说明: CAccount.AccountString += STD;
/// 使用说明: (3)执行CAccount.ReMoveBracket方法得到返回值,如:
/// 使用说明: textBox8.Text = CAccount.ReMoveBracket("(Box1+Box2)*Box3").ToString("F");
/// 使用说明: (4)将实例化的委托STD从CAccount.AccountString事件中删除,如:
/// 使用说明: CAccount.AccountString -= STD;
/// </summary>
public class CAccount
{
/// <summary>
/// 功能简述: 事件定义为公式运算类的公式字串中字段名转换为数值
/// </summary>
public event StringToDecimal AccountString; /// <summary>
/// 功能简述: 实现公式计算的主入口函数
/// 实现方法: 计算时先去除公式中的括号,去括号的规则如下
/// 实现方法: 1.先查找公式中的最右边的左括号,然后查找其近临的右括号
/// 实现方法: 2.将这一组括号中的字符串取出并交接Account函数计算.
/// 实现方法: 3.将字符串的括号及括号中的字符替换为计算结果.计算结果转为字串并前加'#'号
/// 实现方法: 4.循环上诉过程直到没有括号为止
/// 实现方法: 5.将最后的公式字串交由Account函数计算并返回结果
/// </summary>
/// <param name="strFormulary">公式</param>
/// <returns>结果</returns>
public decimal ReMoveBracket(string strFormulary)
{
//定义一个字串,用于存贮strFormulary串的备份,并用其进行计算
string strValue = strFormulary; //iLeftIndex存贮左括号的位置,iRightIndex存贮右括号的位置
int iLeftIndex = 0,iRightIndex = 0; //循环,用于去除所有括号
while (iLeftIndex != -1)
{
//查找最右的左括号
iLeftIndex = strValue.LastIndexOf('('); //如果找到则查找其后的右括号
if (iLeftIndex != -1)
{
//查找其后的右括号
iRightIndex =strValue.Substring(iLeftIndex + 1).IndexOf(')'); //计算括号中的公式并重新拼接公式
strValue = strValue.Substring (0,iLeftIndex) +
"#" +
Account(strValue.Substring(iLeftIndex + 1,iRightIndex)).ToString("F") +
strValue.Substring(iLeftIndex + iRightIndex + 2);
}
} //进行最终结果的计算
return Account(strValue);
} /// <summary>
/// 功能简述: 此函数为递归函数.用以实现公式计算
/// 实现方法: 1.函数运行时依次查找'+','-','*','/'运算符号
/// 实现方法: 当找到对应的运算符号时将公式拆分为两个子公式
/// 实现方法: 对应的'+','-','*','/'运算并将两个子串压入递归直到运算结束为止
/// 实现方法: 2.'+','-','*','/'运算符号先后顺序说明:
/// 实现方法: (1) '+','-'号无特定的顺序
/// 实现方法: (2) '*','/'号无特定的顺序
/// 实现方法: (3) '+','-'号放在'*','/'号后,理由:'*','/'号运算优先级高于
/// 实现方法: '+','-'号.递归过程实际上是堆栈操作.先进入递归后执行.
/// 实现方法: (4) 查找顺序为从后向前查找,以利用递归操作实现从左向右计算
/// 实现方法: 3.函数最终将字串解释由AccountString事件完成.(即调用用户代码)
/// </summary>
/// <param name="strFormulary">公式</param>
/// <returns>结果</returns>
private decimal Account(string strFormulary)
{
//存贮计算结果
decimal deValue = 0; //存贮运算符位置
int iIndex = 0; //处理'+'号
iIndex = strFormulary.LastIndexOf("+"); if (iIndex != -1)
{
deValue = Account(strFormulary.Substring (0, iIndex))
+ Account(strFormulary.Substring (iIndex + 1)); return deValue;
}
//处理'-'号
iIndex = strFormulary.Length - 1; //加循环,用以排除数值中(如:#-23.45)的'-'号,防止数值在'-'号前
while (true)
{
//在索引(Index)后查找'-'号
iIndex = strFormulary.LastIndexOf('-', iIndex - 1); //找到'-'号
if (iIndex != -1)
{
//判断'-'号是否是数值中的'-'号,即'-'号前是否有'#'号,如不是则继续执行
if (strFormulary.Substring(iIndex - 1 , 1) != "#")
{
//进行公式计算
deValue = Account(strFormulary.Substring (0, iIndex))
- Account(strFormulary.Substring (iIndex + 1));
return deValue;
}
}
else
{
break;
}
} //处理'*'号
iIndex = strFormulary.LastIndexOf('*'); if (iIndex != -1)
{
deValue = Account(strFormulary.Substring (0, iIndex))
* Account(strFormulary.Substring (iIndex + 1)); return deValue;
}
//处理'/'号
iIndex = strFormulary.LastIndexOf('/'); if (iIndex != -1)
{
deValue = Account(strFormulary.Substring (0, iIndex))
/ Account(strFormulary.Substring (iIndex + 1)); return deValue;
} //如果为数字格式则返回数值(数字格式如:#123.45)
if (strFormulary.Substring(0,1) == "#")
{
return Convert.ToDecimal(strFormulary.Substring(1));
} //返回字符串对应的数值,AccountString为事件对应的委托代码
return AccountString (strFormulary);
}
} /// <summary>
/// 功能简述: 为公式运算类的公式字串中字段名转换为数值提供的委托
/// </summary>
public delegate decimal StringToDecimal(string strItem);
}