有人已经实现了配平的方法,在此不再重复介绍。

https://www.cnblogs.com/Elfish/p/7631603.html

但是,上述的方法所提供的代码还是存在着问题,需要进一步修改。

首先,因为 frac 这个结构的成员函数和其它操作函数已被声明并定义至一个单一的文件里,

因此,首先要将它的声明和定义分开来。把 frac 结构体抽离至封装的类以外,作为前置声明。

因为原代码是直接 printf() 输出的,而我们需要的是获取它输出的结果。

所以,改变它输出的位置,声明一个 string ,将配好以后的结果直接赋值到 string 里。

最终代码实现:

[C++ 源代码]

  1. /* Exzh Cross Platfrom Toolkit (ECPT) Qt Version
  2. * (This file is the part of the ECPT Project)
  3. * Author: Exzh_PMGI
  4. * E-mail: realexzh@gmail.com
  5. * License: LGPL v3.0 / Exzh Commerical License
  6. * Copyright: (C) Exzh_PMGI
  7. * Qt Framework 5.10 has been tested successfully
  8. * If you want to use the code for business,
  9. * please contact me by my email.
  10. */
  11.  
  12. #include "exequationbalancer.h"
  13.  
  14. #include <QDebug>
  15.  
  16. int gcd(int x, int y) {
  17. return x % y == ? y : gcd(y, x%y);
  18. }
  19.  
  20. int lcm(int x, int y) {
  21. return x * y / gcd(x, y);
  22. }
  23.  
  24. frac createFrac(int a, int b)
  25. {
  26. frac tmp = { a,b };
  27. return tmp;
  28. }
  29.  
  30. frac Abs(frac x) {
  31. int p = x.a> ? x.a : -x.a, q = x.b> ? x.b : -x.b;
  32. return createFrac(p, q);
  33. }
  34.  
  35. string exEquationBalancer::getResult(string inputstr)
  36. {
  37. strcpy(s,inputstr.c_str());
  38. int lst = ;
  39. for (int i = ;i<strlen(s);i++) {
  40. if (i == strlen(s) - )scan(lst, i);
  41. if (s[i] == '+' || s[i] == '=')
  42. {
  43. scan(lst, i - );
  44. lst = i + ;
  45. }
  46. if (s[i] == '=')flag = -; //等号后面的系数变负
  47. }
  48. if (Solve())
  49. for (int i = ;i <= c2 - ;i++)
  50. ans[i] = M[i][N + ];
  51. else output+="No Solution";
  52. int tmp = lcm(ans[].b, ans[].b);
  53. for (int i = ;i <= c2;i++)tmp = lcm(tmp, ans[i].b);
  54. for (int i = ;i <= c2;i++)Ans[i] = ans[i].a*tmp / ans[i].b; //取分母Lcm,把分数变整数
  55. for (int i = ;i <= c2;i++)
  56. {
  57. if (Ans[i]>) output+=to_string(Ans[i]);
  58. for (int j = ;j<strlen(mat[i]);j++)
  59. output+=mat[i][j];
  60. if (i == c2)
  61. {
  62. return output;
  63. qDebug()<<QString::fromStdString(output);
  64. }
  65. else if (i == c1) output+="=";
  66. else output+="+";
  67. }
  68. }
  69.  
  70. bool exEquationBalancer::Solve() { //解方程 (矩阵 高cnt,宽c2+1,c2+1列常数全0)
  71. ans[c2] = ; //令最后一个解为1
  72. for (int i = ;i <= cnt;i++) {
  73. for (int j = ;j <= c2;j++)
  74. M[i][j] = fun[i][j];
  75. }
  76. for (int i = ;i <= cnt;i++)
  77. M[i][c2].a = -M[i][c2].a; //移到常数
  78. //高斯消元过程
  79. N = c2 - , K = cnt;
  80. for (int k = ;k <= N;k++) {
  81. frac maxm = createFrac(-, );
  82. int maxi;
  83. for (int i = k;i <= K;i++)
  84. if (maxm<Abs(M[i][k]))
  85. maxm = Abs(M[i][k]), maxi = i;
  86. if (maxm == createFrac(, ))
  87. return false;
  88. if (maxi != k)
  89. for (int j = ;j <= N + ;j++) {
  90. swap(M[k][j], M[maxi][j]);
  91. }
  92. frac tmp = M[k][k];
  93. for (int j = ;j <= N + ;j++)
  94. M[k][j] = M[k][j] / tmp;
  95. for (int i = k - ? : ;i <= K;i++) {
  96. if (i == k)continue;
  97. frac tmp = M[i][k];
  98. for (int j = ;j <= N + ;j++)
  99. M[i][j] = M[i][j] - tmp * M[k][j];
  100. }
  101. }
  102. return true;
  103. }
  104.  
  105. void exEquationBalancer::scan(int l, int r) { //处理物质
  106. c2++;
  107. for (int i = ;i <= r - l;i++)mat[c2][i] = s[l + i]; //存下元素的名字
  108. if (flag == )c1++; //统计一下反应物数量
  109. int tmp = ; //tmp是小括号倍数
  110. for (int i = l;i <= r;i++) {
  111. if (s[i] == ')')tmp = ;
  112. if (s[i] == '(') {
  113. int j = i + ;while (s[j] != ')')j++; //找这个括号的范围
  114. tmp = getint(j); //读")"右边的数字
  115. }
  116. if (s[i] >= 'A'&&s[i] <= 'Z') { //发现元素
  117. int x = s[i] - 'A' + , y = ;
  118. if (s[i + ] >= 'a'&&s[i] <= 'z') //看一眼是一个字母的还是两个的
  119. y = s[i + ] - 'a' + ;
  120. if (!Map[x][y])Map[x][y] = ++cnt; //判重
  121. fun[Map[x][y]][c2] += flag * getint(i)*tmp; //把这个物质里的这种元素数量放进矩阵里,坐标(map[x][y],c2)
  122. }
  123. }
  124. }
  125.  
  126. int exEquationBalancer::getint(int pos) { //读数
  127. pos++;
  128. if (s[pos] >= 'a'&&s[pos] <= 'z')pos++;
  129. if (s[pos]<'' || s[pos]>'')return ; //没数就是1
  130. else {
  131. int x = ;
  132. while (s[pos] >= ''&&s[pos] <= '')x = x * + s[pos] - '', pos++; //读元素后面的数字
  133. return x;
  134. }
  135. }
  136.  
  137. void exEquationBalancer::print() {
  138. output += to_string(N);
  139. output += " ";
  140. output += to_string(K);
  141. output += "\n";
  142. for (int i = ;i <= K;i++) {
  143. for (int j = ;j <= N + ;j++)
  144. {
  145. output += to_string(M[i][j].a);
  146. output += " ";
  147. }
  148. output += "\n";
  149. }
  150. output += "\n";
  151. }

[C++ 头文件]

  1. /* Exzh Cross Platfrom Toolkit (ECPT) Qt Version
  2. * (This file is the part of the ECPT Project)
  3. * Author: Exzh_PMGI
  4. * E-mail: realexzh@gmail.com
  5. * License: LGPL v3.0 / Exzh Commerical License
  6. * Copyright: (C) Exzh_PMGI
  7. * Qt Framework 5.10 has been tested successfully
  8. * If you want to use the code for business,
  9. * please contact me by my email.
  10. */
  11.  
  12. #ifndef EXEQUATIONBALANCER_H
  13. #define EXEQUATIONBALANCER_H
  14.  
  15. #include <string>
  16. #include "../exstdc++.h"
  17.  
  18. using namespace std;
  19. static string output;
  20. int lcm(int x, int y);
  21. int gcd(int x, int y);
  22.  
  23. struct frac { //分数类
  24. int a, b;
  25. void reduce() {
  26. int x = gcd(a, b);
  27. a /= x, b /= x;
  28. }
  29. frac createFrac(int a, int b)
  30. {
  31. frac tmp = { a,b };
  32. return tmp;
  33. }
  34. frac operator = (int x) {
  35. a = x, b = ;
  36. return *this;
  37. }
  38. frac operator = (const frac x) {
  39. a = x.a, b = x.b;
  40. reduce();
  41. return *this;
  42. }
  43. frac operator + (const frac x) {
  44. return createFrac(b*x.a + a * x.b, b*x.b);
  45. }
  46. frac operator - (const frac x) {
  47. return createFrac(a*x.b - b * x.a, b*x.b);
  48. }
  49. frac operator * (const frac x) {
  50. return createFrac(a*x.a, b*x.b);
  51. }
  52. frac operator / (const frac x) {
  53. return createFrac(a*x.b, b*x.a);
  54. }
  55. bool operator < (const frac x) {
  56. return a * x.b<b*x.a;
  57. }
  58. bool operator == (const frac x) {
  59. return a * x.b == b * x.a;
  60. }
  61. void print() {
  62. if (b == )
  63. {
  64. output += to_string(a);
  65. output += "\n";
  66. }
  67. else
  68. {
  69. output += to_string(a);
  70. output += "/";
  71. output += to_string(b);
  72. }
  73. }
  74. };
  75.  
  76. frac createFrac(int a, int b);
  77. frac Abs(frac x);
  78.  
  79. class exEquationBalancer
  80. {
  81. public:
  82. string getResult(string inputstr);
  83.  
  84. private:
  85. bool Solve();
  86. void scan(int l, int r);
  87. int getint(int pos);
  88. void print();
  89.  
  90. char s[];
  91. int fun[][];
  92. int Map[][]; //手动MAP
  93. frac M[][]; //求解矩阵
  94. frac ans[]; //解
  95. int Ans[]; //整数解
  96. int cnt, c1, c2, flag = , N, K; //cnt数元素,c1数反应物,c2总数 (未知数的数量)
  97. char mat[][]; //存储物质的名称
  98. };
  99.  
  100. #endif // EXEQUATIONBALANCER_H

[C++] 配平化学方程式算法的封装的更多相关文章

  1. 配平化学方程式的C++代码实现

    配平化学方程式的C++代码实现 纪念一下我今天写过了 20171006. (去年的这个时候我就有了这个大胆的想法, 当时的思路是:字符串处理->暴力搜系数,可是太年轻写不对,我那会还是个只会模拟 ...

  2. Python趣用—配平化学方程式

    不知不觉已经毕业多年了,不知道大家是否还记得怎么配平化学方程式呢?反正小编我是已经记不太清了,所以今天的文章除了分享如何用python配平化学方程式,顺带着还会复习 一些化学方程式的知识,希望广大化学 ...

  3. 用c++后缀自动机实现最大公共字符串算法,并封装成Python库

    后缀自动机的C++代码转自https://e-maxx.ru/algo/suffix_automata,其余封装为自写. 在C++文件同级目录建立setup.py文件,代码如下: # !/usr/bi ...

  4. 【HiJ1m】在NOIP2017前写过的有用的东西汇总

    http://www.cnblogs.com/Elfish/p/7544623.html 高级树状数组 http://www.cnblogs.com/Elfish/p/7554420.html BST ...

  5. CCF-CSP题解 201912-3 化学方程式

    判断化学方程式是否配平. 字符串处理. 有点编译原理递归下降法的感觉. 考场源码,比较粗糙. // INFO BEGIN // // User = 201911513451(陶杨) // Group ...

  6. 1.K近邻算法

    (一)K近邻算法基础 K近邻(KNN)算法优点 思想极度简单 应用数学知识少(近乎为0) 效果好 可以解释机器学习算法使用过程中的很多细节问题 更完整的刻画机器学习应用的流程 图解K近邻算法 上图是以 ...

  7. scikit-learn 支持向量机算法库使用小结

    之前通过一个系列对支持向量机(以下简称SVM)算法的原理做了一个总结,本文从实践的角度对scikit-learn SVM算法库的使用做一个小结.scikit-learn SVM算法库封装了libsvm ...

  8. Android 设计模式实战之关于封装计费代码库的策略模式详谈

    写在之前 这周生活上出现了很多的不如意,从周一开始就觉得哪里出现了问题,然后就是各种烦躁的情绪,后来事情还真是如预感的那样发生了,很是心痛,但也无可奈何,希望大家都好好珍惜自己身边的人:友人,亲人,家 ...

  9. 6种基础排序算法java源码+图文解析[面试宝典]

    一.概述 作为一个合格的程序员,算法是必备技能,特此总结6大基础算法.java版强烈推荐<算法第四版>非常适合入手,所有算法网上可以找到源码下载. PS:本文讲解算法分三步:1.思想2.图 ...

随机推荐

  1. sqlite 数据库 相关知识

    一基本简单介绍 SQLite 是一个自持的(self-contained).无server的.零配置的.事务型的关系型数据库引擎.由于他非常小,所以也能够作为嵌入式数据库内建在你的应用程序中. SQL ...

  2. 5分钟Serverless实践 | 构建无服务器图片鉴黄Web应用

    Serverless是什么 Serverless中文译为“无服务器”,最早可以追溯到2012年Ken Fromm发表的<Why The Future Of Software And Apps I ...

  3. Sql2005常用函数大全

    --聚合函数use pubsgoselect avg(distinct price) --算平均数from titleswhere type='business'go use pubsgoselect ...

  4. 在LNMP或Nginx上配置NameCheap免费SSL证书

  5. shell脚本-循环选择语句

    shell脚本-循环选择语句 过程式编程语言: 顺序执行 选择执行 循环执行 注:条件中的变量,可以在执行语句中使用,不用在加上"$". if语句 根据命令的退出状态来执行命令 单 ...

  6. AbstractRoutingDataSource动态选择数据源

    当我们项目变大后,有时候需要多个数据源,接下来我们讲一种能等动态切换数据源的例子. 盗一下图: 单数据源的场景(一般的Web项目工程这样配置进行处理,就已经比较能够满足我们的业务需求) 多数据源多Se ...

  7. [Apple开发者帐户帮助]八、管理档案(3)创建App Store配置文件

    您可以创建自己的App Store配置文件,以便在将应用程序上载到App Store Connect时使用. 有关完整的App Store工作流程,请转到通过 Xcode帮助中的App Store分发 ...

  8. Idea使用Maven搭建SpringMVC的HelloSpringMvc并配置插件Maven和Jetty

    这篇博文只是纯粹的搭建一个SpringMVC的项目, 并不会涉及里面配置文件该写些什么. 只是纯粹的搭建一个初始的Hello SpringMVC的项目. 废话不多说,上图. 1.  打开IDEA 并且 ...

  9. ACM_绝对值排序

    Why Males And Females Apart? Time Limit: 2000/1000ms (Java/Others) Problem Description: In so many o ...

  10. Hadoop Hive概念学习系列之hive里的优化和高级功能(十四)

    在一些特定的业务场景下,使用hive默认的配置对数据进行分析,虽然默认的配置能够实现业务需求,但是分析效率可能会很低. Hive有针对性地对不同的查询进行了优化.在Hive里可以通过修改配置的方式进行 ...