C (bu)科学的复数求解(两数加减乘除)
这次真的是记录一下思考过程了,反正是个很坎坷复杂的经历。 github地址:https://github.com/csvwolf/Sky-C-Study/tree/master/数据结构 老师给了我们一个结构体的框架,不得不说C的结构体和C++的还是有差别的:http://www.cppblog.com/percyph/archive/2009/03/06/75742.html
由此,我们这样定义一个结构体之后:
1typedef struct
2{
3 float rpart;
4 float ipart;
5} complex;
6
刚开始的时候使用了scanf()
,可以看一下:
http://wellwy.blog.51cto.com/1609602/493663
本来还有考虑过sscanf()
参考:
http://www.csdn123.com/html/blogs/20130425/6379.htm
sscanf()
过去也举过例子:SMU 算法题:Weijie 的客人名单
但鉴于有字符串的限定,在C语言中,字符串毕竟是一个限定规格的数组,显得太过麻烦,故放弃了这一个想法。
scanf()
看他的用法似乎觉得有点类似于sscanf()
可以用正则,实际上则不是这个效果,总之被坑得很惨……最终只能用scanf()
加getchar()
的组合来读取。
第一版的代码如下:
1#include <stdio.h>
2/*
3 关于如何判断i+x,可以选择i后读取符号,再scanf数字,再getchar判断是否正确格式。
4*/
5typedef struct
6{
7 float rpart;
8 float ipart;
9} complex;
10
11void input(complex *num1)
12{
13 float a, b, c, d;
14 while(1) {
15 if (scanf("%f", &a) == 0) {
16 if (getchar() == 'i') {
17 num1->ipart = 1;
18 num1->rpart = 0;
19 fflush(stdin);
20 break;
21 } else {
22 printf("未按正确复数格式输入,请重试\n");
23 fflush(stdin);
24 continue;
25 }
26 } else {
27 if ((c = getchar()) == '+') {
28 num1->rpart = a;
29 if (scanf("%f", &a) == 0) {
30 if (getchar() == 'i') {
31 num1->ipart = 1;
32 fflush(stdin);
33 break;
34 } else {
35 printf("未按正确复数格式输入,请重试\n");
36 continue;
37 }
38 } else {
39 if (getchar() == 'i') {
40 num1->ipart = a;
41 fflush(stdin);
42 } else {
43 printf("未按正确复数格式输入,请重试\n");
44 fflush(stdin);
45 continue;
46 }
47 }
48 fflush(stdin);
49 } else if (c == '-') {
50 num1->rpart = a;
51 if (scanf("%f", &a) == 0) {
52 if (getchar() == 'i') {
53 num1->ipart = -1;
54 fflush(stdin);
55 break;
56 } else {
57 printf("未按正确复数格式输入,请重试\n");
58 continue;
59 }
60 } else {
61 if (getchar() == 'i') {
62 num1->ipart = -a;
63 fflush(stdin);
64 } else {
65 printf("未按正确复数格式输入,请重试\n");
66 fflush(stdin);
67 continue;
68 }
69 }
70 fflush(stdin);
71 } else if (c == 'i') {
72 num1->ipart = a;
73 num1->rpart = 0;
74 } else if (c == '\n'){
75 num1->rpart = a;
76 num1->ipart = 0;
77 } else {
78 printf("未按正确复数格式输入,请重试\n");
79 continue;
80 }
81 }
82 break;
83 }
84
85 fflush(stdin);
86}
87
88void plus(complex num1, complex num2, complex *num3)
89{
90 num3->rpart = num1.rpart + num2.rpart;
91 num3->ipart = num1.ipart + num2.ipart;
92}
93
94void minus(complex num1, complex num2, complex *num3)
95{
96 num3->rpart = num1.rpart - num2.rpart;
97 num3->ipart = num1.ipart - num2.ipart;
98}
99
100void times(complex num1, complex num2, complex *num3)
101{
102 num3->rpart = num1.rpart * num2.rpart - num1.ipart * num2.ipart;
103 num3->ipart = num1.ipart * num2.rpart + num1.rpart * num2.ipart;
104}
105
106int multi(complex num1, complex num2, complex *num3)
107{
108 if (num2.ipart == 0 && num2.rpart == 0) {
109 return 1;
110 } else {
111 num3->rpart = (num1.rpart * num2.rpart + num1.ipart * num2.ipart) / (num2.rpart * num2.rpart + num2.ipart * num2.ipart);
112 num3->ipart = (num1.ipart * num2.rpart - num1.rpart * num2.ipart) / (num2.rpart * num2.rpart + num2.ipart * num2.ipart);
113 return 0;
114 }
115}
116
117void output(complex num3)
118{
119 if (num3.ipart == 1 && num3.rpart != 0) {
120 printf("%g+i\n", num3.rpart);
121 } else if (num3.ipart == -1 && num3.rpart != 0) {
122 printf("%g+i\n", num3.rpart);
123 } else if (num3.ipart == 1 && num3.rpart == 0) {
124 printf("i\n");
125 } else if (num3.ipart == -1 && num3.rpart == 0) {
126 printf("-i\n");
127 } else if (num3.ipart == 0) {
128 printf("%g\n", num3.rpart); // 虚部为0 不显示
129 } else if (num3.rpart == 0) {
130 printf("%gi\n", num3.ipart); // 实部为0 不显示
131 } else if (num3.ipart > 0) {
132 printf("%g+%gi\n", num3.rpart, num3.ipart); // 虚部大于0 手动增加加号
133 } else {
134 printf("%g%gi\n", num3.rpart, num3.ipart);
135 }
136}
137
138int main(void)
139{
140
141
142 complex num1, num2, num3;
143 char c;
144
145 printf("请输入你要进行的操作 w.输入 q.退出\n");
146 while (c = getchar()) {
147 fflush(stdin);
148 if (c == 'w') {
149 printf("请输入你要进行操作的两个复数(暂时只支持a+bi的形式,a b可省略)\n");
150 input(&num1);
151 input(&num2);
152
153 } else if (c == 'q') {
154 break;
155 } else {
156 printf("指令无法识别,请重试\n");
157 continue;
158 }
159 fflush(stdin);
160 printf("请输入需要进行的操作(用小写字母表示):\n\ta.加法, b.减法, c.乘法, d.除法, r.返回上一级(退出或重新输入)\n");
161 while (c = getchar()) {
162 fflush(stdin);
163 if (c == 'a') {
164 plus(num1,num2, &num3);
165 printf("加法 ");
166 } else if (c == 'b') {
167 minus(num1,num2, &num3);
168 printf("减法 ");
169 } else if (c == 'c') {
170 times(num1,num2, &num3);
171 printf("乘法 ");
172 } else if (c == 'd') {
173 if (multi(num1,num2, &num3)) {
174 printf("出错了,被除数不能为0\n");
175 continue;
176 }
177 printf("除法 ");
178 } else if (c == 'r') {
179 printf("请输入你要进行的操作 w.输入 q.退出\n");
180 break;
181 } else {
182 printf("输入错误,请重新输入\n");
183 continue;
184 }
185 printf("结果: ");
186 output(num3);
187 }
188 }
189
190 printf("感谢使用,下次再见~\n");
191
192 //printf("%f %f\n %f %f", num1.rpart, num1.ipart, num2.rpart, num2.ipart);
193/*
194 int a, b;
195
196 if (!scanf("%d", &a)) {
197 printf("hhh");
198 }
199*/
200 return 0;
201
202}
203
这也是第一版的完全体,main()
在这里还是不多做解释了,主要还是利用getchar()
来实现的,剩下的通过读取缓冲区剩余的字符来判断接下来的状况,fflush(stdin);
来清空缓冲区,这点在前面的其中一篇文章中已经有过介绍:C 清空键盘缓冲区若干方法
当然,由于scanf()
中我遇到了如果虚部放在前面输入,会吞负号的瓶颈,于是……最终只能放弃这个,而getchar()
虽然很麻烦,但确实是所有形式的根本所在,于是有了第二个版本:
1#include <stdio.h>
2#include <ctype.h>
3/*
4 实现思路:读取每一个字符进行状态改变,把char转换为int识别和提取出数字的部分,识别效果看人品,就是抄在实验报告上心好累。
5 测试数据:
6 2+3i / 2+i
7 i+2 / 2i+2
8 2+3o
9 fasdr2+rweraweirwe
10 arewartgsd
11*/
12typedef struct
13{
14 float rpart;
15 float ipart;
16} complex;
17
18int input(complex *num1) {
19 char c;
20 float num = 0, thatone;
21 int digitmode = 0, counter = 0, minus = 0, rpart = 0, ipart = 0, point = 0, i, thisone, pcounter = 0;
22 while (c = getchar()) {
23 /* 结果储存部分 */
24 if (!isdigit(c) && c != '-' && c != '.') {
25 digitmode = 0;
26 if (c == 'i' && !ipart && !counter && !pcounter) { // 检测为虚数 虚部未输入
27 if (minus) {
28 num1->ipart = -1;
29 } else {
30 num1->ipart = 1;
31 }
32 ipart = 1;
33 point = minus = counter = pcounter = num = 0;
34 } else if (c == 'i' && !ipart && (counter || pcounter)) { // 前面检测到数字 虚部未输入
35 if (minus) {
36 num1->ipart = -num;
37 } else {
38 num1->ipart = num;
39 }
40 ipart = 1;
41 num = point = minus = pcounter = counter = 0;
42 } else if (c != 'i' && !rpart && (counter || pcounter)) { // 检测为实数 实部未输入 已经检测到前面的数据
43 if (minus) {
44 num1->rpart = -num;
45 } else {
46 num1->rpart = num;
47 }
48 rpart = 1;
49 num = counter = minus = point = pcounter = 0;
50 } else if(rpart && !ipart && (counter || pcounter)) {
51 if (minus) {
52 num1->ipart = -num;
53 } else {
54 num1->ipart = num;
55 }
56 ipart = 1;
57 num = counter = minus = point = pcounter = 0;
58 }
59 /* 读入负号开启负号模式 */
60 } else if (c == '-' && digitmode) {
61 if (minus) {
62 num1->rpart = -num;
63 } else {
64 num1->rpart = num;
65 }
66 digitmode = num = counter = point = pcounter = 0;
67 minus = rpart = 1;
68 } else if (c == '-') {
69 digitmode = 0;
70 minus = 1;
71 /* 读入小数点开始小数点模式 */
72 } else if (c == '.') {
73 digitmode = point = 1;
74 pcounter = 0;
75 /* 小数点模式数据处理 */
76 } else if (isdigit(c) && point) {
77 digitmode = 1;
78 pcounter++;
79 thatone = c - '0';
80
81 for (i = 0; i < pcounter; i++) {
82 thatone /= 10;
83 }
84
85 num += thatone;
86 } else if (isdigit(c)) {
87 digitmode = 1;
88 counter++;
89 thisone = c - '0';
90 num *= 10;
91 num += thisone;
92 }
93
94 if (c == '\n') {
95 break;
96 }
97 }
98 fflush(stdin);
99
100 if (!ipart && !rpart) {
101 printf("发生错误,识别不能,重新输入看看\n");
102 return 1;
103 } else if (!ipart && rpart) {
104 num1->ipart = 0;
105 return 0;
106 } else if (ipart && !rpart) {
107 num1->rpart = 0;
108 return 0;
109 } else {
110 return 0;
111 }
112}
113
114void plus(complex num1, complex num2, complex *num3)
115{
116 num3->rpart = num1.rpart + num2.rpart;
117 num3->ipart = num1.ipart + num2.ipart;
118}
119
120void minus(complex num1, complex num2, complex *num3)
121{
122 num3->rpart = num1.rpart - num2.rpart;
123 num3->ipart = num1.ipart - num2.ipart;
124}
125
126void times(complex num1, complex num2, complex *num3)
127{
128 num3->rpart = num1.rpart * num2.rpart - num1.ipart * num2.ipart;
129 num3->ipart = num1.ipart * num2.rpart + num1.rpart * num2.ipart;
130}
131
132int multi(complex num1, complex num2, complex *num3)
133{
134 if (num2.ipart == 0 && num2.rpart == 0) {
135 return 1;
136 } else {
137 num3->rpart = (num1.rpart * num2.rpart + num1.ipart * num2.ipart) / (num2.rpart * num2.rpart + num2.ipart * num2.ipart);
138 num3->ipart = (num1.ipart * num2.rpart - num1.rpart * num2.ipart) / (num2.rpart * num2.rpart + num2.ipart * num2.ipart);
139 return 0;
140 }
141}
142
143void output(complex num3)
144{
145 if (num3.ipart == 1 && num3.rpart != 0) {
146 printf("%g+i\n", num3.rpart);
147 } else if (num3.ipart == -1 && num3.rpart != 0) {
148 printf("%g-i\n", num3.rpart);
149 } else if (num3.ipart == 1 && !num3.rpart) {
150 printf("i\n");
151 } else if (num3.ipart == -1 && !num3.rpart) {
152 printf("-i\n");
153 } else if (!num3.ipart) {
154 printf("%g\n", num3.rpart); // 虚部为0 不显示
155 } else if (!num3.rpart) {
156 printf("%gi\n", num3.ipart); // 实部为0 不显示
157 } else if (num3.ipart > 0) {
158 printf("%g+%gi\n", num3.rpart, num3.ipart); // 虚部大于0 手动增加加号
159 } else {
160 printf("%g%gi\n", num3.rpart, num3.ipart);
161 }
162}
163
164int main(void)
165{
166 complex num1, num2, num3;
167 char c;
168 int state;
169 printf("天家的复数计算器 V2.0\n");
170 printf("按下键盘上的按键来操作吧(菜单全都区分大小写呢~)! \n\tIt's the beginning. w.输入 h.帮助及关于 q.退出\n");
171 while (c = getchar()) {
172 fflush(stdin);
173 if (c == 'w') {
174 printf("输入两个复数咯~a+bi,b+ai都行,手滑打错也行!我会努力看懂的!\n");
175 state = 0;
176 do {
177 if (state) {
178 printf("对不起我会好好加油的!请再次努力的调教我吧\n");
179 }
180 fflush(stdin);
181 while (input(&num1));
182 printf("唔,我觉得吧,你是想要说这个吧?:");
183 output(num1);
184 printf("按y或回车确认,按其他键重新输入:");
185 state = 1;
186 } while ((c = getchar()) != 'y' && c != '\n');
187
188 printf("机智的我,接下来开始录入第二个吧\n");
189
190 state = 0;
191 fflush(stdin);
192 do {
193 if (state) {
194 printf("对不起我会好好加油的!请再次努力的调教我吧\n");
195 }
196 fflush(stdin);
197 while (input(&num2));
198 printf("所以这次你想输入的数字是这个咯?:");
199 output(num2);
200 printf("按y或回车确认,按其他键重新输入:");
201 } while ((c = getchar()) != 'y' && c != '\n');
202 printf("成功录入第二个数,接下来算吧\n");
203
204 } else if (c == 'h') {
205 printf("改啊改啊改,终于我还是重写了,这也真是醉了。。。讲完了\n\n");
206 printf("按下键盘上的按键来操作吧(菜单全都区分大小写呢~)\n\t! It's the beginning. w.输入 h.帮助及关于 q.退出\n");
207 continue;
208 } else if (c == 'q') {
209 break;
210 } else {
211 printf("你在说什么,我听不懂\n");
212 continue;
213 }
214 fflush(stdin);
215 printf("又到了按键的时候了!(区分大小写):\n\ta.加法, b.减法, c.乘法, d.除法, r.返回上一级(退出或重新输入)\n");
216 while (c = getchar()) {
217 fflush(stdin);
218 if (c == 'a') {
219 plus(num1,num2, &num3);
220 printf("加法 ");
221 } else if (c == 'b') {
222 minus(num1,num2, &num3);
223 printf("减法 ");
224 } else if (c == 'c') {
225 times(num1,num2, &num3);
226 printf("乘法 ");
227 } else if (c == 'd') {
228 if (multi(num1,num2, &num3)) {
229 printf("出错了,被除数不能为0\n");
230 continue;
231 }
232 printf("除法 ");
233 } else if (c == 'r') {
234 printf("按下键盘上的按键来操作吧(菜单全都区分大小写呢~)\n\t! It's the beginning. w.输入 h.帮助及关于 q.退出\n");
235 break;
236 } else {
237 printf("输入错误,请重新输入\n");
238 continue;
239 }
240 printf("我帮你算的结果: ");
241 output(num3);
242 }
243 }
244
245 printf("感谢使用,下次再见~再敲一下键盘我就走啦");
246 getchar();
247/*
248 input(&num1);
249 input(&num2);
250 printf("%f %f\n %f %f", num1.rpart, num1.ipart, num2.rpart, num2.ipart);
251 */
252/*
253 int a, b;
254
255 if (!scanf("%d", &a)) {
256 printf("hhh");
257 }
258*/
259 return 0;
260
261}
262
这个版本的关键是通过各种开关来控制,实际上是以前有写过类似的代码,或者说是得到了师匠讲的getchar()
的启示,怒写之,具体都在注释上了,主要似乎还是拿点东西,只是姿势不一样而已,当然,这里有个更高端的,留待我们研究:
C:
1#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4
5int states[][256] = {
6 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
7 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
8 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
9 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
10 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
11};
12
13int first_token(char *s, int *token_len)
14{
15 int state, new_state, i, len;
16
17 for (state = i = 0, len = strlen(s); i <= len; i++) {
18 new_state = states[state][s[i]];
19 if (new_state == 0) {
20 break;
21 }
22 state = new_state;
23 }
24 *token_len = i;
25 return state;
26}
27
28int main(void)
29{
30 char s[256], tmp;
31 int current, token_type, token_len;
32
33 // get line from stdin
34 fgets(s, 256, stdin);
35
36 for (current = 0; ; current += token_len) {
37 token_type = first_token(&s[current], &token_len);
38 switch (token_type) {
39 case 0:
40 printf("Unknown character %c\n", s[current+token_len]);
41 exit(-1);
42 case 1:
43 case 2:
44 tmp = s[current+token_len];
45 s[current+token_len] = '\0';
46 printf("Real part found %s\n", &s[current]);
47 s[current+token_len] = tmp;
48 break;
49 case 3:
50 tmp = s[current+token_len];
51 s[current+token_len] = '\0';
52 printf("Imag part found %s\n", &s[current]);
53 s[current+token_len] = tmp;
54 break;
55 case 4:
56 exit(0);
57 break;
58 }
59 }
60
61 return 0;
62}
63
C++:
1#include <iostream>
2#include <string>
3#include <cctype>
4#include <cstdlib>
5
6bool parseComplex(std::string& comp, double& real, double& imag)
7{
8 decltype(comp.size()) current = 0;
9
10 auto peekChar = [&]() {
11 return (current >= comp.size()) ? '\0' : comp[current];
12 };
13
14 auto nextChar = [&]() {
15 auto ch = peekChar();
16 if (ch) {
17 current++;
18 }
19 return ch;
20 };
21
22 auto eatSpaces = [&]() {
23 if (isspace(peekChar())) {
24 nextChar();
25 }
26 };
27
28 auto nextNumber = [&](double& result) {
29 char ch;
30 auto start = current;
31 bool inFrac = false;
32 bool succeeded = false;
33
34 eatSpaces();
35
36 if ((ch = peekChar()) == '+' || ch == '-') {
37 nextChar();
38 }
39
40 while ((ch = (eatSpaces(), peekChar()))) {
41 if (ch == '.' && !inFrac) {
42 inFrac = true;
43 } else if (isdigit(ch)) {
44 // go on
45 succeeded = true;
46 } else {
47 break;
48 }
49 nextChar();
50 }
51
52 result = succeeded ? std::atof(std::string(comp, start, current - start).c_str()) : 0;
53 return succeeded;
54 };
55
56 real = 0;
57 imag = 0;
58 for (; peekChar(); ) {
59 int sign = (eatSpaces(), peekChar()) == '-' ? -1 : 1;
60 double n;
61 bool succeeded = nextNumber(n);
62 if ((eatSpaces(), peekChar()) == 'i') {
63 imag += succeeded ? n : sign * 1.0;
64 nextChar();
65 } else {
66 real += n;
67 }
68 }
69
70 return true;
71}
72
73int main()
74{
75 std::string comp = "5i+2i+3+2";
76
77 double real, imag;
78 if (parseComplex(comp, real, imag)) {
79 std::cout << real << ", " << imag << std::endl;
80 }
81
82 return 0;
83}
84
85
评论 (2)
爱因斯坦在哪里啊 这难度
一进技术帝的博客,我就傻眼了,直接看不懂啊。