欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 编程资源 > 编程问答 >内容正文

编程问答

----化学方程式配平工具----

发布时间:2023/12/20 编程问答 33 豆豆
生活随笔 收集整理的这篇文章主要介绍了 ----化学方程式配平工具---- 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

(利用待定化学计量数法配平,先根据每种元素列出方程组,然后解方程组,就可以解出计量数之比)

ChemistryEquationStringProcess.h文件:

#pragma once #include <stdio.h> #include <stdlib.h> #include <string.h> #include <memory.h> #include <math.h> #include "EquationSetSolve.h" typedef int BOOL; #define TRUE 1 #define FALSE 0typedef struct _ELEMENT {char Name[128]; //元素名称;int Num; //数量;struct _ELEMENT *next; }ELEMENT;typedef struct _SUBSTANCE {char kName[64]; //给系数设置元;char Name[128]; //物质名称;char UsedName[128]; //Used Name;ELEMENT *elements; //组成物质的元素;struct _SUBSTANCE *next; }SUBSTANCE;typedef struct _SUBSTANCEPOINTER {SUBSTANCE*pAddress;struct _SUBSTANCEPOINTER*next; }SUBSTANCEPOINTER;char kName = 'A'; //每种物质前的元;SUBSTANCE *LeftSubsHead = 0; //储存左边的物质; SUBSTANCE *LeftSubsTail = 0;SUBSTANCE *RightSubsHead = 0; //储存右边的物质; SUBSTANCE *RightSubsTail = 0; //储存右边的物质;ELEMENT*AllEleCLas = 0; //储存所有的元素; int AllEleClasCount = 0; //记录元素的个数;SUBSTANCEPOINTER *AllSubsAddrsHead = NULL; //记录所有元素的地址; SUBSTANCEPOINTER *AllSubsAddrsTail = NULL;char szEquationSet[128]; //储存生成的方程组; char szEquation[2048]; //储存方程式; char szRetEquation[2048]; //储存方程式; char szLeftEqua[1024]; //左部分方程式; char szRightEqua[1024]; //右部分方程式; //是否在元素链表中; ELEMENT* InElementList(char*ElementName, ELEMENT*ListHead) {ELEMENT*pEle;for (pEle = ListHead; pEle != NULL; pEle = pEle->next){if (!strcmp(pEle->Name, ElementName))break;}return pEle; }//清空字符数组; void Init() {memset(szEquation, 0, sizeof(szEquation));memset(szEquation, 0, sizeof(szRetEquation));memset(szLeftEqua, 0, sizeof(szLeftEqua));memset(szRightEqua, 0, sizeof(szRightEqua)); } //分割方程式,失败反回FALSE,成功返回TRUE; BOOL DevideEquation() {char *p;memset(szLeftEqua, 0, sizeof(szLeftEqua));memset(szRightEqua, 0, sizeof(szRightEqua));p = szEquation;//等号左边没有东西;if (*p == '=')return FALSE;while (*p != '='&& *p != NULL) p++;//没有等于号;if (*p == NULL)return FALSE;//储存方程式左部分;memcpy(szLeftEqua, szEquation, p - szEquation);//移到方程式右部分开始处;while (*p == '='&& *p != NULL) p++;//等号右边没有东西;if (*p == NULL)return FALSE;//储存右边的方程式;strcpy(szRightEqua, p);//方便后面分割各种物质;strcat(szLeftEqua, "+");strcat(szRightEqua, "+");return TRUE; } //分割各种物质; BOOL CallDevideSubstance(char*szPartEquation, SUBSTANCE**SubsListHead, SUBSTANCE**SubsListTail) {char*pSubsStart, *pSubsEnd;pSubsStart = pSubsEnd = szPartEquation;while (*pSubsEnd != NULL){//是一种元素的尾端;if (*pSubsEnd == '+'){//添加到SubsList中;//尾为空,头不存在;if (*SubsListTail == NULL){*SubsListHead = *SubsListTail = (SUBSTANCE*)malloc(sizeof(SUBSTANCE));}//尾不为空,在尾的后面添加;else{(*SubsListTail)->next = (SUBSTANCE*)malloc(sizeof(SUBSTANCE));*SubsListTail = (*SubsListTail)->next;}/*--------------------------------添加到AllSubsAddrsList中----------------------------*/if (AllSubsAddrsTail == NULL){AllSubsAddrsHead = AllSubsAddrsTail = (SUBSTANCEPOINTER*)malloc(sizeof(SUBSTANCEPOINTER));}else{AllSubsAddrsTail->next = (SUBSTANCEPOINTER*)malloc(sizeof(SUBSTANCEPOINTER));AllSubsAddrsTail = AllSubsAddrsTail->next;}AllSubsAddrsTail->next = NULL;AllSubsAddrsTail->pAddress = *SubsListTail;/*-----------------------------------------------------------------------------------*///设置新SUBSTANCE的值;memset((*SubsListTail)->kName, 0, sizeof((*SubsListTail)->kName));memset((*SubsListTail)->Name, 0, sizeof((*SubsListTail)->Name));memset((*SubsListTail)->UsedName, 0, sizeof((*SubsListTail)->UsedName));(*SubsListTail)->elements = NULL;(*SubsListTail)->next = NULL;*(*SubsListTail)->kName = kName++;//忽略已经填写的系数;while (*pSubsStart >= '0' && *pSubsStart <= '9')pSubsStart++;//常数项,没有元素名称;if (pSubsEnd == pSubsStart)return FALSE;memcpy((*SubsListTail)->Name, pSubsStart, pSubsEnd - pSubsStart);memcpy((*SubsListTail)->UsedName, pSubsStart, pSubsEnd - pSubsStart);pSubsStart = pSubsEnd + 1;}pSubsEnd++;}return TRUE; } BOOL DevideSubstance() {//分割左边的物质;if (!CallDevideSubstance(szLeftEqua, &LeftSubsHead, &LeftSubsTail))return FALSE;//分割右边的物质;if (!CallDevideSubstance(szRightEqua, &RightSubsHead, &RightSubsTail))return FALSE;return TRUE; } //将点转换为括号; void CallChangePoint(SUBSTANCE*pSubs) {char *pPointStart, *pPointEnd;int value = 0, len = 0;char buff[128] = { 0 };while (1){pPointEnd = pSubs->UsedName;//查找开始点;while (*pPointEnd != '.' && *pPointEnd != NULL)pPointEnd++;pPointStart = pPointEnd;//不存在点;if (*pPointStart == NULL)break;pPointEnd++;//查找结束点;while (*pPointEnd != '.' && *pPointEnd != NULL)pPointEnd++;//开始转换点;//如果点后面为数字;if (*(pPointStart + 1) >= '0' && *(pPointStart + 1) <= '9'){//将结束点后(包括点)复制到buff中;memcpy(buff, pPointEnd, pSubs->UsedName + strlen(pSubs->UsedName) - pPointEnd);//将结束点后(包括点)置为0memset(pPointEnd, 0, pSubs->UsedName + strlen(pSubs->UsedName) - pPointEnd);strcat(pSubs->UsedName, ")");len = StrToNum(pPointStart + 1, &value);//添加数字到后面;NumToStr(pPointEnd + 1/*多了')',加1*/, value);strcat(pSubs->UsedName, buff);/*-------------------------------*/memset(buff, 0, sizeof(buff));memcpy(buff, pPointStart + len + 1, pSubs->UsedName + strlen(pSubs->UsedName) - (pPointStart + len + 1));memset(pPointStart, 0, pSubs->UsedName + strlen(pSubs->UsedName) - pPointStart);strcat(pSubs->UsedName, "(");strcat(pSubs->UsedName, buff);}else{strcpy(buff, pPointStart + 1);memset(pPointStart, 0, pSubs->UsedName + strlen(pSubs->UsedName) - pPointStart);strcat(pSubs->UsedName, buff);}} } //在个数为1的元素后面加'1'; void CallUpdateSubsName(SUBSTANCE*pSubs) {char str[128];int j = 0,i;memset(str, 0, sizeof(str));for (i = 0; i < strlen(pSubs->UsedName); i++){str[j] = pSubs->UsedName[i];j++;if ((pSubs->UsedName[i] >= 'a'&&pSubs->UsedName[i] <= 'z') ||(pSubs->UsedName[i] >= 'A'&&pSubs->UsedName[i] <= 'Z')){//当前元素结尾没有数字;if ((pSubs->UsedName[i + 1] >= 'A'&&pSubs->UsedName[i + 1] <= 'Z') ||pSubs->UsedName[i + 1] == 0 ||pSubs->UsedName[i + 1] == '(' ||pSubs->UsedName[i + 1] == ')'){str[j] = '1';j++;}}}memset(pSubs->UsedName, 0, sizeof(pSubs->UsedName));strcpy(pSubs->UsedName, str); } //去除物质中的括号; BOOL RemoveParentheses(SUBSTANCE*pSubs) {char buff[128];char*pParenthesesLeft, *pParenthesesRight;while (1){pParenthesesLeft = pParenthesesRight = pSubs->UsedName;//转移到最内层括号处;while (*pParenthesesRight != ')'&&*pParenthesesRight != NULL){if (*pParenthesesRight == '(')pParenthesesLeft = pParenthesesRight;pParenthesesRight++;}//没有右边括号;if (*pParenthesesRight == NULL){//但是还有左边括号;if (*pParenthesesLeft == '(')//不匹配;return FALSE;//正常,没有括号,退出循环;break;}//找到右括号,但左面无括号,错误;if (*pParenthesesLeft != '(')return FALSE;//括号右边为数字;if (*(pParenthesesRight + 1) >= '0'&&*(pParenthesesRight + 1) <= '9'){char *p;int Value, Len;Len = StrToNum(pParenthesesRight + 1, &Value);memset(buff, 0, sizeof(buff));//将括号右边数字右边部分复制;strcpy(buff, pParenthesesRight + Len + 1);//清除括号右边;memset(pParenthesesRight + 1, 0, pSubs->UsedName + strlen(pSubs->UsedName) - (pParenthesesRight + 1));//加上buff(实际是去了数字部分);strcat(pSubs->UsedName, buff);/*-----------------------------------------------------*/p = pParenthesesLeft + 1;//遍历括号内,将数字乘上括号后的数字;while (p < pParenthesesRight){if (*p >= '0'&&*p <= '9'){char szNewNum[128] = { 0 };int nNow, lenNow, nNew, lenNew;//变化的长度;int dtLen;//获取当前数字和长度;lenNow = StrToNum(p, &nNow);//计算新的数字;nNew = Value*nNow;//将新的数字转为字符串,保存长度;lenNew = NumToStr(szNewNum, nNew);//计算变化的长度;dtLen = lenNew - lenNow;memset(buff, 0, sizeof(buff));//将当前数字右边复制到buff;strcpy(buff, p + lenNow);//将数字和右面置为0;memset(p, 0, pSubs->UsedName + strlen(pSubs->UsedName) - p);//加上新长度;strcat(pSubs->UsedName, szNewNum);//加上buff;strcat(pSubs->UsedName, buff);//右括号向右移动dtLen长度;pParenthesesRight += dtLen;//p移动到新数字后面;p += lenNew;}elsep++;}}//去掉两边括号;memset(buff, 0, sizeof(buff));strcpy(buff, pParenthesesRight + 1);memset(pParenthesesRight, 0, pSubs->UsedName + strlen(pSubs->UsedName) - pParenthesesRight);strcat(pSubs->UsedName, buff);/*--------------------------------------------------------------------------------------------*/memset(buff, 0, sizeof(buff));strcpy(buff, pParenthesesLeft + 1);memset(pParenthesesLeft, 0, pSubs->UsedName + strlen(pSubs->UsedName) - pParenthesesLeft);strcat(pSubs->UsedName, buff);}return TRUE; } //分割物质组成元素; void DevideElement(SUBSTANCE*pSubs) {char *pEleStart, *pEleEnd;pEleStart = pEleEnd = pSubs->UsedName;while (*pEleStart != NULL){//用数字分割元素;if (*pEleEnd >= '0'&&*pEleEnd <= '9'){int Value, Len;ELEMENT*pEle;char EleName[64] = { 0 };memcpy(EleName, pEleStart, pEleEnd - pEleStart);pEle = InElementList(EleName, pSubs->elements);if (pEle == NULL){ELEMENT*pEle = NULL;pEle = (ELEMENT*)malloc(sizeof(ELEMENT));pEle->next = pSubs->elements;pSubs->elements = pEle;memset(pEle->Name, 0, sizeof(pEle->Name));memcpy(pEle->Name, pEleStart, pEleEnd - pEleStart);Len = StrToNum(pEleEnd, &pEle->Num);}else{Len = StrToNum(pEleEnd, &Value);pEle->Num += Value;}pEleEnd += Len;pEleStart = pEleEnd;}elsepEleEnd++;} } //检测左右元素种类是否守恒; BOOL IsCovered() {//将方程式左边的元素添加到AllEleClaslist中;SUBSTANCE*pSubs;int RightEleClasCount = 0;ELEMENT*pEle;for (pSubs = LeftSubsHead; pSubs != NULL; pSubs = pSubs->next){for (pEle = pSubs->elements; pEle != NULL; pEle = pEle->next){if (NULL == InElementList(pEle->Name, AllEleCLas)){ELEMENT*pNewEle = (ELEMENT*)malloc(sizeof(ELEMENT));memset(pNewEle, 0, sizeof(ELEMENT));strcpy(pNewEle->Name, pEle->Name);pNewEle->Num = 1;pNewEle->next = AllEleCLas;AllEleCLas = pNewEle;AllEleClasCount++;}}}//与方程式右边的元素比较;for (pSubs = RightSubsHead; pSubs != NULL; pSubs = pSubs->next){for (pEle = pSubs->elements; pEle != NULL; pEle = pEle->next){ELEMENT*ele = InElementList(pEle->Name, AllEleCLas);if (NULL == ele){strcpy(szRetEquation, "ERROR:方程式左右两边元素种类不相同!");return FALSE;}elseele->Num++;}}for (pEle = AllEleCLas; pEle != NULL; pEle = pEle->next){if (pEle->Num == 1){strcpy(szRetEquation, "ERROR:方程式左右两边元素种类不相同!");return FALSE;}}return TRUE; } //处理每一种物质; BOOL BeginProcessStr() {SUBSTANCEPOINTER*pSubsAddr;for (pSubsAddr = AllSubsAddrsHead; pSubsAddr != NULL; pSubsAddr = pSubsAddr->next){//将点转换为括号;CallChangePoint(pSubsAddr->pAddress);//在个数为1的元素后面加'1'CallUpdateSubsName(pSubsAddr->pAddress);//去除物质中的括号;if (!RemoveParentheses(pSubsAddr->pAddress)){strcpy(szRetEquation, "ERROR:括号不匹配!");return FALSE;}//分割物质组成元素;DevideElement(pSubsAddr->pAddress);}return TRUE; } //生成方程组; void MakeEquationSet() {char buff[128] = { 0 };ELEMENT*pCurEle;for (pCurEle = AllEleCLas; pCurEle != NULL; pCurEle = pCurEle->next){SUBSTANCEPOINTER*pSubsAddr;for (pSubsAddr = AllSubsAddrsHead; pSubsAddr != NULL; pSubsAddr = pSubsAddr->next){ELEMENT*pEle;//这种物质是方程右边的第一种物质;if (pSubsAddr->pAddress == RightSubsHead && strlen(szEquationSet) != 0){strcpy(szEquationSet + strlen(szEquationSet) - 1, "==");}for (pEle = pSubsAddr->pAddress->elements; pEle != NULL; pEle = pEle->next){if (!strcmp(pCurEle->Name, pEle->Name)){sprintf(buff, "%d%s+", pEle->Num, pSubsAddr->pAddress->kName);strcat(szEquationSet, buff);}}//这种物质是方程中最后一种物质;if (pSubsAddr == AllSubsAddrsTail && strlen(szEquationSet) != 0){strcpy(szEquationSet + strlen(szEquationSet) - 1, ";");}}} } //释放内存; void FreeMemory() {SUBSTANCEPOINTER*pSubsAddr;for (pSubsAddr = AllSubsAddrsHead; pSubsAddr != NULL;){SUBSTANCEPOINTER*tp;ELEMENT*pEle;for (pEle = pSubsAddr->pAddress->elements; pEle != NULL;){ELEMENT *tp = pEle;pEle = pEle->next;free(tp);}free(pSubsAddr->pAddress);tp = pSubsAddr;pSubsAddr = pSubsAddr->next;free(tp);} } //显示处理过程; void ShowProcess() {SUBSTANCEPOINTER*pSubsAddr;for (pSubsAddr = AllSubsAddrsHead; pSubsAddr != NULL; pSubsAddr = pSubsAddr->next){ELEMENT*pEle;if (pSubsAddr->pAddress == LeftSubsHead)printf("-----------------------------Left----------------------------\n\n");else if (pSubsAddr->pAddress == RightSubsHead)printf("\n----------------------------Right----------------------------\n\n");printf("::K:%s\tName:%s\tUsedName:%s\n", pSubsAddr->pAddress->kName, pSubsAddr->pAddress->Name, pSubsAddr->pAddress->UsedName);printf("---------------------------elements--------------------------\n");for (pEle = pSubsAddr->pAddress->elements; pEle != NULL; pEle = pEle->next){printf("::::element:%s\tnum:%d\n", pEle->Name, pEle->Num);}printf("-------------------------------------------------------------\n");}printf("-------------------------EquationSet-------------------------\n");printf(szEquationSet);printf("\n-------------------------------------------------------------\n"); } //结束 void EndChemistryEquationStringProcess() {//释放内存;FreeMemory(); }//处理化学方程字符串; BOOL ChemistryEquationStringProcess(char*szChemistryEquation) {//清空字符数组;Init();//--------------------------------------------------------------------------//char szChemistryEquation[] = "Al2(SO4)3+NH3.H2O====Al(OH)3+(NH4)2SO4";strcpy(szEquation, szChemistryEquation);//--------------------------------------------------------------------------//分割方程式,失败反回FALSE,成功返回TRUE;if (!DevideEquation())return FALSE;//分割各种物质;if (!DevideSubstance())return FALSE;//处理每一种物质;if (!BeginProcessStr())return FALSE;//检测左右元素种类是否守恒;if (!IsCovered()){strcat(szRetEquation,"元素种类不守恒!");return FALSE;}//生成方程组;MakeEquationSet();//显示处理过程;ShowProcess();return TRUE; }

EquationSetSolve.h文件:

#pragma once #include <stdio.h> #include <memory.h> #include <stdlib.h> #include <string.h> #include <math.h> #define TYPE_UNKNOWN 1 #define TYPE_CONSTANT 0 #define SUCCESS 0 #define NEXT 1 #define FAIL -1 typedef int BOOL; typedef unsigned int UINT; #define TRUE 1 #define FALSE 0 //分数类型; typedef struct _NUM {int Molecule; //分子;UINT Denominator; //分母,都为正; }NUM; typedef struct _Item {int nType; //是否为未知项;char szName[32]; //名称;NUM k; //系数;struct _Item* next; }Item; typedef struct _Equation {Item*FirstItem; //储存各个项;struct _Equation* next; }Equation; typedef struct _EquationSet {Equation* FirstEquation; //储存方程式;struct _EquationSet* next; }EquationSet; //保存结果; typedef struct _Unknown {char Name[32];NUM value;struct _Unknown*next; }Unknown; //储存输入的方程式; typedef struct _EquationString {char szEquation[256];char szEquationLeft[128];char szEquationRight[128];struct _EquationString* next; }EquationString; //储存多组解; typedef struct _Ret {Unknown*unknown;struct _Ret*next; }Ret; EquationSet *EquationSetHead = NULL; //储存方程组的结构; EquationString * EquationStrHead = NULL; //储存输入的方程组字符串; Unknown *AllUnknown = NULL; //储存所有元的名称; int UnknownCount = 0; //记录元的个数; Unknown *Definite = NULL; //确定的元; Unknown *Varied = NULL; //主动变化的元; Unknown *_Varied = NULL; //被动变化的元; Ret *RetSolution = NULL; //结果链表首地址; int MaxSolution = 1; //最多求出几组解; int CurSoluton = 0; //已经求出的解的组数; int MaxValue = 3; //主动变化元最大值; #define IsInAllUnknown(name) InUnknownList(AllUnknown,name) #define IsDefinite(name) InUnknownList(Definite,name) #define IsVaried(name) InUnknownList(Varied,name) #define Is_Varied(name) InUnknownList(_Varied,name) //统计确定元的个数; int GetDefiniteNum() {int n = 0;Unknown*uk;for (uk = Definite; uk != NULL; uk = uk->next)n++;return n; } //是否在unknownlist中; Unknown* InUnknownList(Unknown*List, char *Name) {Unknown *uk;for (uk = List; uk != NULL; uk = uk->next){if (!strcmp(uk->Name, Name))return uk;} return NULL; } //将字符串起始部分的数字字符转为整数,返回长度; int StrToNum(char *str, int *n) {char *p = str;int len = 0,i;*n = 0;while (*p >= '0'&&*p <= '9'){p++;len++;}p = str;for (i = 0; i < len; i++, p++){*n += (int)(*p - '0')*pow(10.0, len - 1 - i);}return len; } //将整数转为字符串,返回长度; int NumToStr(char *buff, int n) {sprintf(buff, "%d", n);return strlen(buff); } //释放Unknownlist; void DelUnknownList(Unknown*UkListHead) {Unknown*TempUnknown, *pUk = UkListHead;while (pUk != NULL){TempUnknown = pUk;pUk = pUk->next;free(TempUnknown);} } //释放Item; #define DelItem(pItem) free(pItem) //释放方程; void DelEquation(Equation*eqt) {Item*TempItem,*pItem = eqt->FirstItem;while (pItem != NULL){TempItem = pItem;pItem = pItem->next;DelItem(TempItem);}free(eqt); } //释放方程组; void DelEquationSet(EquationSet*EqtSet) {Equation*TempEqt, *pEqt = EqtSet->FirstEquation;while (pEqt != NULL){TempEqt = pEqt;pEqt = pEqt->next;DelEquation(TempEqt);}free(EqtSet); } //释放方程组的集合; void DelEquationSetSet(EquationSet*EquationSetListHead) {EquationSet*TempEqtSet, *pEqtSet = EquationSetListHead;while (pEqtSet != NULL){TempEqtSet = pEqtSet;pEqtSet = pEqtSet->next;DelEquationSet(TempEqtSet);} } //释放储存的方程字符串; void DelEquationStr() {EquationString*EqtStr = EquationStrHead,*Temp;while(EqtStr){Temp=EqtStr;EqtStr = EqtStr->next;free(Temp);} } //取字符串中的分子分母和元,存到Item中; BOOL GetStrItem(char *str, Item*pItem) {char *p = str;int StrLen = strlen(str),Sign;int Molecule, Denominator,MoleculeLen, DenominatorLen;if (StrLen == 0) //长度为0无效,返回false;return FALSE;Sign = 1;if (*p == '-')Sign = -1;p++;if (*p < '0' || *p > '9') //第一个字符(除了正负号)不是数字,将整个字符串当作元名称;{pItem->nType = TYPE_UNKNOWN;strcpy(pItem->szName, p);pItem->k.Molecule = 1, pItem->k.Denominator = 1; //分子分母都为1;goto success;}//----------------------------------------------------------------------//储存分子;MoleculeLen = StrToNum(p, &Molecule);if (*(p + MoleculeLen) == NULL) //只有一个数是常数项;{pItem->nType = TYPE_CONSTANT;pItem->k.Molecule = Molecule, pItem->k.Denominator = 1;goto success;}if (*(p + MoleculeLen) == '/' && (*(p + MoleculeLen + 1) >= '0' && *(p + MoleculeLen + 1) <= '9')) //找到分数线且分数线后是一个数;{DenominatorLen = StrToNum(p + MoleculeLen + 1, &Denominator);if ((DenominatorLen + MoleculeLen + 2/*分数线和第一个正负号*/) == StrLen) //只有分数;{pItem->nType = TYPE_CONSTANT;}else //是分数和一个元;{pItem->nType = TYPE_UNKNOWN;strcpy(pItem->szName, p + MoleculeLen + DenominatorLen + 1);}pItem->k.Molecule = Molecule, pItem->k.Denominator = Denominator;if (pItem->k.Denominator == 0) //分母为0,无效;return FALSE;goto success;}else //一个整数加元;{pItem->nType = TYPE_UNKNOWN;strcpy(pItem->szName, p + MoleculeLen);pItem->k.Denominator = 1, pItem->k.Molecule = Molecule;goto success;} success:pItem->k.Molecule *= Sign;return TRUE; } //取绝对值; UINT ABS(int n) {return n > 0 ? n : -n; } //取最大公因数; UINT GetMaxCommonFactor(int a, int b) {int r = 0;a = ABS(a), b = ABS(b);if (a == 0 || b == 0)return 1;do{if (a < b) a = a^b, b = a^b, a = a^b;r = a%b;a = b, b = r;} while (r);return a; } //取最小公倍数; UINT GetMinCommonMultiple(int a, int b) {a = ABS(a), b = ABS(b);return a*b / GetMaxCommonFactor(a, b); } //在一个unknownlist中创建一项; Unknown*CreateUnknownInUkList(Unknown**UkListHead) {Unknown*pNew = (Unknown*)malloc(sizeof(Unknown));memset(pNew, 0, sizeof(Unknown));pNew->next = (*UkListHead);(*UkListHead) = pNew;return pNew; } //在一个方程组链表中创建一个方程组; EquationSet * CreateEquationSetInEqtSetList(EquationSet**EqtSetListHead) {//头插法;EquationSet* pEqtSet = (EquationSet*)malloc(sizeof(EquationSet));pEqtSet->next = (*EqtSetListHead);(*EqtSetListHead) = pEqtSet;(*EqtSetListHead)->FirstEquation = NULL;return pEqtSet; } //在一个方程组中创建一个方程; Equation *CreateEquationInEqtSet(EquationSet*EqtSet) {//头插法;Equation *pEqt = (Equation*)malloc(sizeof(Equation));pEqt->FirstItem = NULL;pEqt->next = EqtSet->FirstEquation;EqtSet->FirstEquation = pEqt;return pEqt; } //在一个方程组创建一个项; Item* CreateItemInEqt(Equation*Eqt) {//头插法;Item *pItem = (Item*)malloc(sizeof(Item));memset(pItem, 0, sizeof(Item));pItem->next = Eqt->FirstItem;Eqt->FirstItem = pItem;return pItem; } //用';'分割方程组; BOOL DevideEquationSet(char*szEquation) {char *pStart, *pEnd;char *DevideSign;pStart = pEnd = szEquation;while (1){if (*pStart == NULL){break;}if (*pEnd == ';' || *pEnd == NULL){EquationString*Eqt = (EquationString*)malloc(sizeof(EquationString));Eqt->next = EquationStrHead;EquationStrHead = Eqt;//将整个方程存到->szEquation中;memset(EquationStrHead->szEquation, 0, sizeof(EquationStrHead->szEquation));memcpy(EquationStrHead->szEquation, pStart, pEnd - pStart);memset(EquationStrHead->szEquationLeft, 0, sizeof(EquationStrHead->szEquationLeft));memset(EquationStrHead->szEquationRight, 0, sizeof(EquationStrHead->szEquationRight));EquationStrHead->szEquationLeft[0] = '+';EquationStrHead->szEquationRight[0] = '+';//----------------------------------------------------------------------------------//分割方程左右两部份;//找到等于号;DevideSign = EquationStrHead->szEquation;//等号左边没有东西;if (*DevideSign == '=') return FALSE;while (*DevideSign != '='&&*DevideSign != NULL) DevideSign++;//没有等于号;if (*DevideSign == NULL) return FALSE;//储存左边;memcpy(EquationStrHead->szEquationLeft+1, EquationStrHead->szEquation, DevideSign - EquationStrHead->szEquation);while (*DevideSign == '=' && *DevideSign != NULL) DevideSign++;// 等号右边没有东西;if (*DevideSign == NULL) return FALSE;strcpy(EquationStrHead->szEquationRight+1, DevideSign);//----------------------------------------------------------------------------------if (*pEnd != NULL)pEnd++;pStart = pEnd;}else{pEnd++;}}return TRUE; } //设置起始方程组; BOOL SetStartEquationSet() {char buff[256];Item*pItem;EquationSet*EqtSet = CreateEquationSetInEqtSetList(&EquationSetHead);EquationString*EqtStr;for (EqtStr = EquationStrHead; EqtStr != NULL; EqtStr = EqtStr->next){Equation *NewEquation = CreateEquationInEqtSet(EqtSet);char *pStart,*pEnd;int i;for (i = 0; i < 2; i++){//第一次分割左部分,第二次分割右部分;if (i == 0)pStart = EqtStr->szEquationLeft;elsepStart = EqtStr->szEquationRight;pEnd = pStart + 1;while (1){if (*pStart == NULL)break;if (*pEnd == '+' ||*pEnd=='-' ||*pEnd == NULL){memset(buff, 0, sizeof(buff));memcpy(buff, pStart, pEnd - pStart);pItem = CreateItemInEqt(NewEquation);if (!GetStrItem(buff, pItem))return FALSE; //无效的项;//第一次出现的元,在allunknownlist中添加;if (pItem->nType == TYPE_UNKNOWN && !IsInAllUnknown(pItem->szName)){Unknown*pUk = CreateUnknownInUkList(&AllUnknown);UnknownCount++;strcpy(pUk->Name, pItem->szName);}//分割右边的项每个系数乘-1;if (i == 1)pItem->k.Molecule *= -1;pStart = pEnd;if (pEnd != NULL)pEnd++;}else{pEnd++;}}}}return TRUE; } //化简每一项(约分); void SimplyItem(Item*pItem) {int MaxCommonFactor = GetMaxCommonFactor(pItem->k.Molecule, pItem->k.Denominator);pItem->k.Molecule /= MaxCommonFactor;pItem->k.Denominator /= MaxCommonFactor; } //是否为同类项; BOOL IsSameClassItem(Item*pItem1, Item*pItem2) {return ((pItem1->nType == pItem2->nType) && !strcmp(pItem1->szName, pItem2->szName)); } //合并两项储存到第一项中; void MergeItem(Item*pItem1, Item*pItem2) {//计算分母的最小公倍数;int MinCommonMutiple = GetMinCommonMultiple(pItem1->k.Denominator, pItem2->k.Denominator);//通分;pItem1->k.Molecule *= MinCommonMutiple / pItem1->k.Denominator;pItem2->k.Molecule *= MinCommonMutiple / pItem2->k.Denominator;pItem1->k.Denominator = pItem2->k.Denominator = MinCommonMutiple;//分子相加;pItem1->k.Molecule += pItem2->k.Molecule; } //化简方程式; void SimplyEquation(Equation*eqt) {int MaxCommonFactor = 0;//-----------------------------------合并同类项----------------------------;Item*pItem1,*pItem2,*front,*pItem;for (pItem1 = eqt->FirstItem; pItem1 != NULL;pItem1=pItem1->next){for (pItem2 = pItem1->next, front = pItem1; pItem2 != NULL;){if (IsSameClassItem(pItem1,pItem2)){MergeItem(pItem1, pItem2);front->next = pItem2->next;DelItem(pItem2);pItem2 = front->next;}else{front = front->next;pItem2 = pItem2->next;}}}//-------------------------------------清除系数为0的项---------------------------;for (pItem = eqt->FirstItem,front=NULL; pItem != NULL; ){if (0 == pItem->k.Molecule){if (front == NULL){eqt->FirstItem = pItem->next;DelItem(pItem);pItem = eqt->FirstItem;}else{front->next = pItem->next;DelItem(pItem);pItem = front->next;}}else{if (front == NULL)front = eqt->FirstItem;elsefront = front->next;pItem = front->next;}}//每一项约分;for (pItem = eqt->FirstItem; pItem != NULL; pItem = pItem->next){SimplyItem(pItem);}//获取所有项的最大公因数;for (pItem = eqt->FirstItem; pItem != NULL; pItem = pItem->next){if (MaxCommonFactor == 0)MaxCommonFactor = pItem->k.Molecule;elseMaxCommonFactor = GetMaxCommonFactor(MaxCommonFactor, pItem->k.Molecule);}//每一项同除以最大公因数;if (MaxCommonFactor != 1){for (pItem = eqt->FirstItem; pItem != NULL; pItem = pItem->next){pItem->k.Molecule /= MaxCommonFactor;}} } //获取常数项或元个数; int GetConstOrUnknownNum(Equation*Eqt,int nType) {int n=0;Item*pItem;for(pItem = Eqt->FirstItem;pItem!=NULL;pItem=pItem->next){if(pItem->nType == nType)n++;}return n; } //方程中是否存在某一个元; Item* EqtExistItem(Equation *eqt,int nType,char *szUnknownName) {Item*pItem;for (pItem = eqt->FirstItem; pItem != NULL; pItem = pItem->next){if ((nType == pItem->nType) && !strcmp(pItem->szName, szUnknownName))break;}return pItem; } 获取方程组出现次数最少的元,储存到Name中; void GetLeastUnknown(EquationSet*EqtSet, char*Name,int size) {Unknown *UnknInfo = NULL,*LeastUnknown = NULL,*pFindUnk = NULL,*pNewUnkn = NULL,*pUnknInfo = NULL;Equation*eqt;Item*pItem;//把所有的元储存到链表中并记录出现的次数;for (eqt = EqtSet->FirstEquation; eqt != NULL; eqt = eqt->next){for (pItem = eqt->FirstItem; pItem != NULL; pItem = pItem->next){if (pItem->nType == TYPE_UNKNOWN){//查找是否存在;pFindUnk = InUnknownList(UnknInfo,pItem->szName);//不存在,加到链表中;if (pFindUnk == NULL){pNewUnkn = CreateUnknownInUkList(&UnknInfo);pNewUnkn->value.Molecule = 1;strcpy(pNewUnkn->Name, pItem->szName);}else{pFindUnk->value.Molecule++;}}}}for (pUnknInfo = UnknInfo; pUnknInfo != NULL; pUnknInfo = pUnknInfo->next){//如果是第一个且出现次数大于1;if (LeastUnknown == NULL && pUnknInfo->value.Molecule > 1)LeastUnknown = pUnknInfo;//否则,如果小于leastUnknown则设置LeastUnknown==pUnknInfo;else if (pUnknInfo->value.Molecule > 1 && pUnknInfo->value.Molecule<LeastUnknown->value.Molecule)LeastUnknown = pUnknInfo;}memset(Name, 0, size);if (LeastUnknown != NULL)//每个元只出现了一次为空;strcpy(Name, LeastUnknown->Name);//释放内存;DelUnknownList(UnknInfo); } //化解每个方程并删除方程组中的空方程; void SimplyEquationSet(EquationSet*EqtSet) {Equation*Eqt = NULL,*front = NULL;//删除空方程;for(Eqt = EqtSet->FirstEquation,front = NULL;Eqt!=NULL;){SimplyEquation(Eqt);//空方程删除;if(Eqt->FirstItem==NULL){if(front==NULL){EqtSet->FirstEquation=Eqt->next;DelEquation(Eqt);Eqt = EqtSet->FirstEquation;}else{front->next=Eqt->next;DelEquation(Eqt);Eqt=front->next;}}else{if(front == NULL)front=EqtSet->FirstEquation;elsefront=front->next;Eqt=front->next;}} } //两个方程消元,反回新的方程; Equation* ClearEquationUnknown(Equation*eqt1, Equation*eqt2,Item*pItem1,Item*pItem2) {Item*pItem,*NewItem,*FindItem;Equation*NewEquation;int DenoMinCommonMultiple,MoleMinCommonMultiple,Eqt1Multiply,Eqt2Multiply;//记录两个方程相加还是相减;BOOL bChangeSign;bChangeSign = (pItem1->k.Molecule*pItem2->k.Molecule)>=0;//取分母最小公倍数;DenoMinCommonMultiple = GetMinCommonMultiple(pItem1->k.Denominator, pItem2->k.Denominator);pItem1->k.Molecule*= DenoMinCommonMultiple / pItem1->k.Denominator;pItem2->k.Molecule *= DenoMinCommonMultiple / pItem2->k.Denominator;pItem1->k.Denominator= pItem2->k.Denominator = DenoMinCommonMultiple;//取分子最小公倍数;MoleMinCommonMultiple = GetMinCommonMultiple(pItem1->k.Molecule, pItem2->k.Molecule);//计算第一个方程每一项要乘的数;Eqt1Multiply = MoleMinCommonMultiple / ABS(pItem1->k.Molecule);//计算第一个方程每一项要乘的数;Eqt2Multiply = MoleMinCommonMultiple / ABS(pItem2->k.Molecule);//给第一个方程的每一项乘上Eqt1Multiply;for (pItem = eqt1->FirstItem; pItem != NULL; pItem = pItem->next){pItem->k.Molecule*=Eqt1Multiply;}//给第一个方程的每一项乘上Eqt1Multiply;for (pItem = eqt2->FirstItem; pItem != NULL; pItem = pItem->next){pItem->k.Molecule*=Eqt2Multiply;//如果同号,将方程2所有的符号取反;if (bChangeSign){pItem->k.Molecule*=-1;}}//储存生成的新方程;NewEquation = (Equation*)malloc(sizeof(Equation));memset(NewEquation,0,sizeof(Equation));//先把eqt1复制到NewEquation中;for (pItem = eqt1->FirstItem; pItem != NULL; pItem = pItem->next){NewItem = CreateItemInEqt(NewEquation);memcpy(NewItem, pItem, sizeof(Item)-4/*减去四个字节(next指针)*/);}//遍历eqt2各个项,在NewEquation中查找是否存在,不存在添加,存在合并;for (pItem = eqt2->FirstItem; pItem != NULL; pItem = pItem->next){FindItem = EqtExistItem(NewEquation, pItem->nType, pItem->szName);if (FindItem == NULL) //不存在;{//在NewEquation中添加该项Item*NewItem = CreateItemInEqt(NewEquation);memcpy(NewItem, pItem, sizeof(Item)-4/*减去四个字节(next指针)*/);}else //存在该项;MergeItem(FindItem, pItem);}SimplyEquation(eqt1);SimplyEquation(eqt2);SimplyEquation(NewEquation);return NewEquation; } //方程组开始消元; void BeginEliminationUnknown() {char LeastUnknown[32] = { 0 };while(1){int EqtSetExist = 0;Equation*eqt1,*eqt2,*front;EquationSet*EqtSet = EquationSetHead;SimplyEquationSet(EqtSet);//找出出现次数最少的元;GetLeastUnknown(EqtSet, LeastUnknown, sizeof(LeastUnknown));//不存在出现次数最少的元;if (*LeastUnknown == '\0')break;for (eqt1 = EqtSet->FirstEquation, front = NULL; eqt1 != NULL;){Item*FindItem1 = EqtExistItem(eqt1, TYPE_UNKNOWN, LeastUnknown);Item*FindItem2;//标记只创建一个下一个方程组;//如果不存在最少次数元,把这个方程放到下一个方程组;if (FindItem1 == NULL){if(EqtSetExist==0){CreateEquationSetInEqtSetList(&EquationSetHead);EqtSetExist=1;}//移动这个方程,下一个方程组是EquationSetHead;if (front == NULL){EqtSet->FirstEquation = eqt1->next;eqt1->next = EquationSetHead->FirstEquation;EquationSetHead->FirstEquation= eqt1;eqt1 = EqtSet->FirstEquation;}else{front->next = eqt1->next;eqt1->next = EquationSetHead->FirstEquation;EquationSetHead->FirstEquation= eqt1;eqt1 = front->next;}}else //如果这个方程存在出现最少次数元,则从下一个方程开始寻找;{for (eqt2 = eqt1->next; eqt2 != NULL; eqt2 = eqt2->next){FindItem2 = EqtExistItem(eqt2, TYPE_UNKNOWN, LeastUnknown);if (FindItem2 != NULL){Equation*NewEquation = ClearEquationUnknown(eqt1,eqt2,FindItem1,FindItem2);//不存在下一个方程组添加;if (EqtSetExist==0){CreateEquationSetInEqtSetList(&EquationSetHead);EqtSetExist=1;}NewEquation->next = EquationSetHead->FirstEquation;EquationSetHead->FirstEquation = NewEquation;}}if (front == NULL)front = EqtSet->FirstEquation;elsefront = front->next;eqt1 = front->next;}}} } //将方程组中的方程按未知项个数排序; void SortEquation(EquationSet*EqtSet) {//记录方程个数;int EquationNum = 0;int i,j;Equation*Eqt;for(Eqt = EqtSet->FirstEquation;Eqt!=NULL;Eqt=Eqt->next)EquationNum++;for (i = 0; i < EquationNum - 1; i++){Equation*CurEqt = EqtSet->FirstEquation, *front = NULL;for (j = 0; j < EquationNum-1-i; j++){//如果当前的方程式未知项项数多于下一项,交换位置;if (GetConstOrUnknownNum(CurEqt,TYPE_UNKNOWN)>GetConstOrUnknownNum(CurEqt->next,TYPE_UNKNOWN)){if (front == NULL){EqtSet->FirstEquation = CurEqt->next;front = EqtSet->FirstEquation;CurEqt->next = CurEqt->next->next;front->next = CurEqt;}else{front->next = CurEqt->next;CurEqt->next = CurEqt->next->next;front->next->next = CurEqt;front = front->next;}}else{if (front == NULL)front = EqtSet->FirstEquation;elsefront = front->next;CurEqt = front->next;}}} } //从EqtSet最后一组起设置确定量和变化量 BOOL SetDefinite(EquationSet*EqtSetHead) {EquationSet*CurEqtSet;for (CurEqtSet = EqtSetHead; CurEqtSet != NULL; CurEqtSet = CurEqtSet->next){Equation*eqt;SimplyEquationSet(CurEqtSet);//按项数多少排序;SortEquation(CurEqtSet);for (eqt = CurEqtSet->FirstEquation; eqt != NULL; eqt = eqt->next){//查找元的值是否确定,将确定的值带入其中;Unknown* FindUnknown = NULL;Item*pItem;int UnknownNum,ConstNum,_VariedSet = 0;;for (pItem = eqt->FirstItem; pItem != NULL; pItem = pItem->next){if (pItem->nType == TYPE_UNKNOWN){FindUnknown = IsDefinite(pItem->szName);//值已经确定;if (FindUnknown != NULL){//设为常数项;pItem->nType = TYPE_CONSTANT;memset(pItem->szName, 0, sizeof(pItem->szName));//分子相乘,分母相乘;pItem->k.Molecule*= FindUnknown->value.Molecule;pItem->k.Denominator*=FindUnknown->value.Denominator;}}}//化简一次;SimplyEquation(eqt);UnknownNum = GetConstOrUnknownNum(eqt,TYPE_UNKNOWN);ConstNum = GetConstOrUnknownNum(eqt,TYPE_CONSTANT);//所有项都消完;if (UnknownNum == 0 && ConstNum == 0)continue;//左边没有未知项,只有常数项且不等于0;if (UnknownNum == 0 && ConstNum != 0)return FALSE;//只有一个未知项,可以确定值;if (UnknownNum == 1){Item*pUnknownItem,*pConstItem;Unknown*pNew;if (eqt->FirstItem->nType == TYPE_UNKNOWN){ pUnknownItem = eqt->FirstItem;pConstItem = pUnknownItem->next;}else{pConstItem = eqt->FirstItem;pUnknownItem = pConstItem->next;}//如果是被动变化量,尾插法;if (Is_Varied(pUnknownItem->szName)){Unknown*pTail = Definite;while (pTail != NULL && pTail->next != NULL)pTail = pTail->next;pNew = (Unknown*)malloc(sizeof(Unknown));if (pTail == NULL)Definite = pNew;elsepTail->next = pNew;memset(pNew,0,sizeof(Unknown));}else//头插法;pNew = CreateUnknownInUkList(&Definite);pNew->value.Molecule=pNew->value.Denominator=1;//复制名称;strcpy(pNew->Name, pUnknownItem->szName);if (pConstItem == 0) //元的值为0;pNew->value.Molecule=0;else //元的值不为0;{pNew->value.Molecule = ABS(pUnknownItem->k.Denominator)*ABS(pConstItem->k.Molecule);pNew->value.Denominator=ABS(pUnknownItem->k.Molecule)*ABS(pConstItem->k.Denominator);if(pUnknownItem->k.Molecule*pConstItem->k.Molecule>0) //结果为负;pNew->value.Molecule*=-1;}continue;}//留一个被动变化值的位置;for (pItem = eqt->FirstItem; pItem != NULL; pItem = pItem->next){if (pItem->nType == TYPE_UNKNOWN && !IsVaried(pItem->szName) && !Is_Varied(pItem->szName)){//还没有设置被动变化量;if(_VariedSet == 0){//加到被动变化量中;Unknown*unk = CreateUnknownInUkList(&_Varied);strcpy(unk->Name, pItem->szName);_VariedSet = 1;}else{//加到主动变化量中;Unknown*unk = CreateUnknownInUkList(&Varied);unk->value.Molecule=1;unk->value.Denominator=1;strcpy(unk->Name, pItem->szName);}}}}}return TRUE; } //创建EquationSet的副本 EquationSet* CopyEquationSet() {EquationSet*RetEquationSet = NULL,*NewCurEqtSet = NULL,*EqtSet;for (EqtSet = EquationSetHead; EqtSet != NULL; EqtSet = EqtSet->next){Equation*eqt;//没有头,尾插法;if (NewCurEqtSet == NULL)NewCurEqtSet = RetEquationSet =(EquationSet*)malloc(sizeof(EquationSet));else{NewCurEqtSet->next = (EquationSet*)malloc(sizeof(EquationSet));NewCurEqtSet = NewCurEqtSet->next;}memset(NewCurEqtSet,0,sizeof(EquationSet));for (eqt = EqtSet->FirstEquation; eqt != NULL; eqt = eqt->next){Equation * NewEquation = CreateEquationInEqtSet(NewCurEqtSet);Item*pItem;for (pItem = eqt->FirstItem; pItem != NULL; pItem = pItem->next){Item*NewItem = CreateItemInEqt(NewEquation);memcpy(NewItem, pItem, sizeof(Item)-4);}}}return RetEquationSet; } //保存结果; void SaveRet() {Unknown *NewUnknown = NULL,*uk;Ret*pRet = (Ret*)malloc(sizeof(Ret));pRet->unknown = NULL;pRet->next = RetSolution;RetSolution = pRet;for (uk = Definite; uk != NULL; uk = uk->next){if (NewUnknown == NULL)NewUnknown = pRet->unknown = (Unknown*)malloc(sizeof(Unknown));else{NewUnknown->next = (Unknown*)malloc(sizeof(Unknown));NewUnknown = NewUnknown->next;}NewUnknown->next = NULL;memcpy(NewUnknown, uk, sizeof(Unknown)-4);} } //当存在主动变化值时用枚举法解出给定个数组解; int Solve(Unknown * unknown) {//没有主动变化量,都是确定的量;if (Varied == NULL)return SUCCESS;//主动变化量链表尾端,主动变化量已经设置好;if (unknown == NULL){EquationSet*TempEquationSet;//已经解完,退出;if (CurSoluton >= MaxSolution)return SUCCESS;//创建方程组s的副本;TempEquationSet = CopyEquationSet();if (FALSE == SetDefinite(TempEquationSet)) //无解,退出;{//删除方程组s的副本;DelEquationSet(TempEquationSet);return FAIL;}else //保存该组解;{CurSoluton++;SaveRet();//删除方程组s的副本;DelEquationSet(TempEquationSet);return NEXT;}}else //设置该主动变化量的值;{while (1){int ret;//-----------------------------------------------------------------------------//在Definite中添加该项Unknown*unk = Definite,*_unk,*front;while (unk != NULL && unk->next!=NULL)unk = unk->next;if (unk == NULL)unk = Definite = (Unknown*)malloc(sizeof(Unknown));else{unk->next = (Unknown*)malloc(sizeof(Unknown));unk = unk->next;}memset(unk, 0, sizeof(Unknown));memcpy(unk, unknown, sizeof(Unknown)-4);//-----------------------------------------------------------------------------ret = Solve(unknown->next);//-----------------------------------------------------------------------------//删除Definite中当前元及后面的项;for (_unk = Definite,front = NULL; _unk != NULL;){Unknown*__unk;if (strcmp(_unk->Name, unknown->Name) == 0){if (front == NULL)Definite = NULL;elsefront->next = NULL;for (__unk = _unk; __unk != NULL;){Unknown*tp = __unk;__unk = __unk->next;free(tp);}break;}else{front = _unk;_unk = front->next;}}//-----------------------------------------------------------------------------if (ret == FAIL)return FAIL;if (ret == SUCCESS)return SUCCESS;if (ret == NEXT){if (unknown->value.Molecule >= MaxValue){if (unknown == Varied){Unknown*last;MaxValue += 3;//找到最后一个Varied,值加一;last = Varied;while (last->next != NULL)last = last->next;last->value.Molecule++;}elsereturn NEXT;}elseunknown->value.Molecule++;}}} } //结束; void EndEquationSetSolve() {Ret*pRet = RetSolution,*temp;while(pRet){DelUnknownList(pRet->unknown);temp = pRet;pRet = pRet->next;free(temp);}DelEquationStr();DelEquationSet(EquationSetHead); } BOOL EquationSetSolve(char*szEquationSet) {EquationSet*EqtSet;//B==2D;5B==3C+8D;2A==1C;3A==1D;12A+B==3C+4D;if(FALSE == DevideEquationSet(szEquationSet))return FALSE;if(FALSE == SetStartEquationSet())return FALSE;//开始两两消元;BeginEliminationUnknown();if(FALSE == SetDefinite(EquationSetHead))return FALSE;if(GetDefiniteNum() == UnknownCount)return FALSE;if(FAIL == Solve(Varied))return FALSE;return TRUE; }

main.c文件:

#include "ChemistryEquationStringProcess.h" #include "EquationSetSolve.h"int main(int argc,char* argv[]) {SUBSTANCEPOINTER*pSubsAddr;char szRet[256] = {0};char buff[32];Unknown*uk;int MinCommonMultiple = 0;if(argc!=2){ printf("%s:Invalid Chemistry Equation!\n",argv[0]);return 0;}if(FALSE == ChemistryEquationStringProcess(argv[1])){printf("Invalid Chemistry Equation!\n");printf("%s\n",szRetEquation);return 0;}if(FALSE == EquationSetSolve(szEquationSet)){printf("Sorry,this chemistry equation doesn't have solution!\n");return 0;}//----------------------取分母最小公倍数---------------------;for(uk = RetSolution->unknown;uk!=NULL;uk=uk->next){if(MinCommonMultiple == 0)MinCommonMultiple = uk->value.Denominator;elseMinCommonMultiple = GetMinCommonMultiple(uk->value.Denominator,MinCommonMultiple);}//----------------------通分-----------------------------;for(uk = RetSolution->unknown;uk!=NULL;uk=uk->next)uk->value.Molecule*=MinCommonMultiple/uk->value.Denominator;//----------------------------生成结果--------------------------;strcat(szRet,"\n------------------------result-----------------------\n");for(pSubsAddr = AllSubsAddrsHead;pSubsAddr!=NULL;pSubsAddr=pSubsAddr->next){Unknown*uk;for(uk = RetSolution->unknown;uk!=NULL;uk=uk->next){if(!strcmp(uk->Name,pSubsAddr->pAddress->kName)){if(uk->value.Molecule!=1){sprintf(buff,"%d",uk->value.Molecule);strcat(szRet,buff);}strcat(szRet,pSubsAddr->pAddress->Name);if(pSubsAddr->pAddress->next != NULL && pSubsAddr->next->pAddress != RightSubsHead)strcat(szRet,"+");if(pSubsAddr->next!=NULL &&pSubsAddr->next->pAddress == RightSubsHead)strcat(szRet,"===");}}}strcat(szRet,"\n------------------------result-----------------------\n");//--------------------------输出结果--------------------------;printf(szRet);//释放内存;EndChemistryEquationStringProcess();EndEquationSetSolve();return 0; }

能力有限,用了2000多行代码
大神勿喷

总结

以上是生活随笔为你收集整理的----化学方程式配平工具----的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。