CodeSky 代码之空

随手记录自己的学习过程

C (bu)科学的复数求解(两数加减乘除)

2014-09-26 19:43分类: C评论: 2

这次真的是记录一下思考过程了,反正是个很坎坷复杂的经历。 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)

屌丝日记2014年10月5日 09:40

爱因斯坦在哪里啊 这难度

焱烬2014年9月28日 16:03

一进技术帝的博客,我就傻眼了,直接看不懂啊。