终于完成了“简单”的个人项目,我内心稍有拨动。由于各种因素,我的个人项目启动稍晚,后来因电脑不好使借了室友的电脑,着实命途多舛。我的开发大概分为两个阶段。第一个阶段是实现读入算式,切分文字,中缀转后缀并计算结果。当然,是小数结果。以算法知识尚在,而一气呵成。第二阶段是写分数类,并实现之。本以为更易,然遇难于实现。我自以为分数类编的十分规范完备,然而想了一整天才想明白如何实现。经测试之后终于完成。
这个是我的分数类:
1 //分数类 2 class fraction 3 { 4 private: 5 int numerator; //分子 6 int denominator; //分母 7 public: 8 fraction() 9 { 10 numerator = 0; 11 denominator = 1; 12 } 13 fraction(int n, int d) 14 { 15 if (d == 0) 16 { 17 cout << "输入有误,分母不能为0!" << endl; 18 } 19 else 20 { 21 numerator = n; 22 denominator = d; 23 } 24 } 25 int getN() 26 { 27 return numerator; 28 } 29 int getD() 30 { 31 return denominator; 32 } 33 void setN(int n) 34 { 35 numerator = n; 36 } 37 void setD(int d) 38 { 39 if (d == 0) 40 { 41 cout << "输入有误,分母不能为0!" << endl; 42 return; 43 } 44 else 45 { 46 denominator = d; 47 } 48 } 49 //约分 50 void yuefen() 51 { 52 int bufn, bufd, buf; 53 bufn = this->numerator; 54 bufd = this->denominator; 55 if (bufn < bufd) 56 { 57 buf = bufn; 58 bufn = bufd; 59 bufd = buf; 60 } 61 while (buf = bufn%bufd) 62 { 63 bufn = bufd; 64 bufd = buf; 65 } 66 if (bufd != 1) 67 { 68 this->numerator /= bufd; 69 this->denominator /= bufd; 70 } 71 if (this->denominator < 0) 72 { 73 this->numerator *= -1; 74 this->denominator *= -1; 75 } 76 } 77 //加法 78 fraction operator+(fraction &f) 79 { 80 fraction fra(this->numerator*f.denominator + f.numerator*this->numerator, this->denominator*f.denominator); 81 fra.yuefen(); 82 return fra; 83 } 84 //减法 85 fraction operator-(fraction &f) 86 { 87 fraction fra(this->numerator*f.denominator - f.numerator*this->numerator, this->denominator*f.denominator); 88 fra.yuefen(); 89 return fra; 90 } 91 //乘法 92 fraction operator*(fraction &f) 93 { 94 fraction fra(this->numerator*f.numerator, this->denominator*f.denominator); 95 fra.yuefen(); 96 return fra; 97 } 98 //除法 99 fraction operator/(fraction &f) 100 { 101 if (f.numerator == 0) 102 { 103 cout << "除数不能为0!" << endl; 104 return f; 105 } 106 else 107 { 108 fraction fra(this->numerator*f.denominator, this->denominator*f.numerator); 109 fra.yuefen(); 110 return fra; 111 } 112 113 } 114 //显示分数 115 void printfrac() 116 { 117 if (denominator == 1) 118 { 119 cout << numerator; 120 } 121 else 122 { 123 cout << numerator << "/" << denominator; 124 } 125 } 126 //判断相等的三个类,可拿分数和分数,int,double比较 127 bool operator==(fraction &f) 128 { 129 if (this->numerator == f.numerator&&this->denominator == f.denominator) 130 { 131 return true; 132 } 133 else 134 { 135 return false; 136 } 137 } 138 bool operator==(int &i) 139 { 140 if (i == (this->numerator / this->denominator)) 141 { 142 return true; 143 } 144 else 145 { 146 return false; 147 } 148 } 149 bool operator==(double &d) 150 { 151 if (d == ((double)this->numerator / this->denominator)) 152 { 153 return true; 154 } 155 else 156 { 157 return false; 158 } 159 } 160 //赋值 161 void operator=(fraction &f) 162 { 163 this->numerator = f.numerator; 164 this->denominator = f.denominator; 165 } 166 };
其中约分用了更好的方法,是网上查的,“辗转相除”法,《九章算术》中的招数。
堆栈类应该都差不多,所以就不贴了。
这个是中缀转后缀:
//中缀转后缀 void infix_to_suffix(const char pre[], char post[], int &n) { int i = 0, j = 0; Stack<char> stack; stack.init(); stack.push(‘=‘); // 首先把“=”放入栈底,结束标志 while (pre[i] != ‘=‘) { if ((pre[i] >= ‘0‘ && pre[i] <= ‘9‘) || pre[i] == ‘.‘) // 遇到数字和小数点直接写入后缀表达式 { post[j++] = pre[i]; n++; } else if (pre[i] == ‘(‘) // 遇到“(”不用比较直接入栈 stack.push(pre[i]); else if (pre[i] == ‘)‘) // 遇到右括号将其对应左括号后的操作符(操作符栈中的)全部写入后缀表达式 { while (stack.gettop() != ‘(‘) { post[j++] = stack.pop(); n++; } stack.pop(); // 将“(”出栈,后缀表达式中不含小括号 } else if (isoperator(pre[i])) { post[j++] = ‘ ‘; // 用空格分开操作数 n++; while (priority(pre[i]) <= priority(stack.gettop())) { // 当前的操作符小于等于栈顶操作符的优先级时,将栈顶操作符写入到后缀表达式,重复此过程 post[j++] = stack.pop(); n++; } stack.push(pre[i]); // 当前操作符优先级大于栈顶操作符的优先级,将该操作符入栈 } i++; } while (stack.top) // 将所有的操作符加入后缀表达式 { post[j++] = stack.pop(); n++; } }
这个是将double数转换成分数:
//Number to fraction fraction Num_to_fra(double n) { fraction f((int)(n * 1000), 1000); f.yuefen(); return f; }
紧接着就是将输入的玩意(字符串)转化成分数:
//将输入的数(字符形式)转化成分数fraction fraction char_to_fraction(char str[]) { int j = 0; double x = read_number(str, &j); fraction f = Num_to_fra(x); return f; }
其中有一些借鉴网上的代码,比如约分的方法。但除此之外的分数类及其实现完全是自己想的自己写的,这也给了我一种不错的体验。
经历了这次紧张的开发,我有点期待未来的小组开发了。
时间: 2024-10-11 05:32:03