C (bu)科学的复数求解(两数加减乘除)
这次真的是记录一下思考过程了,反正是个很坎坷复杂的经历。
github地址:https://github.com/csvwolf/Sky-C-Study/tree/master/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84
老师给了我们一个结构体的框架,不得不说C的结构体和C++的还是有差别的:http://www.cppblog.com/percyph/archive/2009/03/06/75742.html
由此,我们这样定义一个结构体之后:
typedef struct
{
float rpart;
float ipart;
} complex;
刚开始的时候使用了scanf()
,可以看一下:
http://wellwy.blog.51cto.com/1609602/493663
本来还有考虑过sscanf()
参考:
http://www.csdn123.com/html/blogs/20130425/6379.htmsscanf()
过去也举过例子:SMU 算法题:Weijie 的客人名单
但鉴于有字符串的限定,在C语言中,字符串毕竟是一个限定规格的数组,显得太过麻烦,故放弃了这一个想法。
scanf()
看他的用法似乎觉得有点类似于sscanf()
可以用正则,实际上则不是这个效果,总之被坑得很惨……最终只能用scanf()
加getchar()
的组合来读取。
第一版的代码如下:
#include <stdio.h>
/*
关于如何判断i+x,可以选择i后读取符号,再scanf数字,再getchar判断是否正确格式。
*/
typedef struct
{
float rpart;
float ipart;
} complex;
void input(complex *num1)
{
float a, b, c, d;
while(1) {
if (scanf("%f", &a) == 0) {
if (getchar() == 'i') {
num1->ipart = 1;
num1->rpart = 0;
fflush(stdin);
break;
} else {
printf("未按正确复数格式输入,请重试\n");
fflush(stdin);
continue;
}
} else {
if ((c = getchar()) == '+') {
num1->rpart = a;
if (scanf("%f", &a) == 0) {
if (getchar() == 'i') {
num1->ipart = 1;
fflush(stdin);
break;
} else {
printf("未按正确复数格式输入,请重试\n");
continue;
}
} else {
if (getchar() == 'i') {
num1->ipart = a;
fflush(stdin);
} else {
printf("未按正确复数格式输入,请重试\n");
fflush(stdin);
continue;
}
}
fflush(stdin);
} else if (c == '-') {
num1->rpart = a;
if (scanf("%f", &a) == 0) {
if (getchar() == 'i') {
num1->ipart = -1;
fflush(stdin);
break;
} else {
printf("未按正确复数格式输入,请重试\n");
continue;
}
} else {
if (getchar() == 'i') {
num1->ipart = -a;
fflush(stdin);
} else {
printf("未按正确复数格式输入,请重试\n");
fflush(stdin);
continue;
}
}
fflush(stdin);
} else if (c == 'i') {
num1->ipart = a;
num1->rpart = 0;
} else if (c == '\n'){
num1->rpart = a;
num1->ipart = 0;
} else {
printf("未按正确复数格式输入,请重试\n");
continue;
}
}
break;
}
fflush(stdin);
}
void plus(complex num1, complex num2, complex *num3)
{
num3->rpart = num1.rpart + num2.rpart;
num3->ipart = num1.ipart + num2.ipart;
}
void minus(complex num1, complex num2, complex *num3)
{
num3->rpart = num1.rpart - num2.rpart;
num3->ipart = num1.ipart - num2.ipart;
}
void times(complex num1, complex num2, complex *num3)
{
num3->rpart = num1.rpart * num2.rpart - num1.ipart * num2.ipart;
num3->ipart = num1.ipart * num2.rpart + num1.rpart * num2.ipart;
}
int multi(complex num1, complex num2, complex *num3)
{
if (num2.ipart == 0 && num2.rpart == 0) {
return 1;
} else {
num3->rpart = (num1.rpart * num2.rpart + num1.ipart * num2.ipart) / (num2.rpart * num2.rpart + num2.ipart * num2.ipart);
num3->ipart = (num1.ipart * num2.rpart - num1.rpart * num2.ipart) / (num2.rpart * num2.rpart + num2.ipart * num2.ipart);
return 0;
}
}
void output(complex num3)
{
if (num3.ipart == 1 && num3.rpart != 0) {
printf("%g+i\n", num3.rpart);
} else if (num3.ipart == -1 && num3.rpart != 0) {
printf("%g+i\n", num3.rpart);
} else if (num3.ipart == 1 && num3.rpart == 0) {
printf("i\n");
} else if (num3.ipart == -1 && num3.rpart == 0) {
printf("-i\n");
} else if (num3.ipart == 0) {
printf("%g\n", num3.rpart); // 虚部为0 不显示
} else if (num3.rpart == 0) {
printf("%gi\n", num3.ipart); // 实部为0 不显示
} else if (num3.ipart > 0) {
printf("%g+%gi\n", num3.rpart, num3.ipart); // 虚部大于0 手动增加加号
} else {
printf("%g%gi\n", num3.rpart, num3.ipart);
}
}
int main(void)
{
complex num1, num2, num3;
char c;
printf("请输入你要进行的操作 w.输入 q.退出\n");
while (c = getchar()) {
fflush(stdin);
if (c == 'w') {
printf("请输入你要进行操作的两个复数(暂时只支持a+bi的形式,a b可省略)\n");
input(&num1);
input(&num2);
} else if (c == 'q') {
break;
} else {
printf("指令无法识别,请重试\n");
continue;
}
fflush(stdin);
printf("请输入需要进行的操作(用小写字母表示):\n\ta.加法, b.减法, c.乘法, d.除法, r.返回上一级(退出或重新输入)\n");
while (c = getchar()) {
fflush(stdin);
if (c == 'a') {
plus(num1,num2, &num3);
printf("加法 ");
} else if (c == 'b') {
minus(num1,num2, &num3);
printf("减法 ");
} else if (c == 'c') {
times(num1,num2, &num3);
printf("乘法 ");
} else if (c == 'd') {
if (multi(num1,num2, &num3)) {
printf("出错了,被除数不能为0\n");
continue;
}
printf("除法 ");
} else if (c == 'r') {
printf("请输入你要进行的操作 w.输入 q.退出\n");
break;
} else {
printf("输入错误,请重新输入\n");
continue;
}
printf("结果: ");
output(num3);
}
}
printf("感谢使用,下次再见~\n");
//printf("%f %f\n %f %f", num1.rpart, num1.ipart, num2.rpart, num2.ipart);
/*
int a, b;
if (!scanf("%d", &a)) {
printf("hhh");
}
*/
return 0;
}
这也是第一版的完全体,main()
在这里还是不多做解释了,主要还是利用getchar()
来实现的,剩下的通过读取缓冲区剩余的字符来判断接下来的状况,fflush(stdin);
来清空缓冲区,这点在前面的其中一篇文章中已经有过介绍:C 清空键盘缓冲区若干方法
当然,由于scanf()
中我遇到了如果虚部放在前面输入,会吞负号的瓶颈,于是……最终只能放弃这个,而getchar()
虽然很麻烦,但确实是所有形式的根本所在,于是有了第二个版本:
#include <stdio.h>
#include <ctype.h>
/*
实现思路:读取每一个字符进行状态改变,把char转换为int识别和提取出数字的部分,识别效果看人品,就是抄在实验报告上心好累。
测试数据:
2+3i / 2+i
i+2 / 2i+2
2+3o
fasdr2+rweraweirwe
arewartgsd
*/
typedef struct
{
float rpart;
float ipart;
} complex;
int input(complex *num1) {
char c;
float num = 0, thatone;
int digitmode = 0, counter = 0, minus = 0, rpart = 0, ipart = 0, point = 0, i, thisone, pcounter = 0;
while (c = getchar()) {
/* 结果储存部分 */
if (!isdigit(c) && c != '-' && c != '.') {
digitmode = 0;
if (c == 'i' && !ipart && !counter && !pcounter) { // 检测为虚数 虚部未输入
if (minus) {
num1->ipart = -1;
} else {
num1->ipart = 1;
}
ipart = 1;
point = minus = counter = pcounter = num = 0;
} else if (c == 'i' && !ipart && (counter || pcounter)) { // 前面检测到数字 虚部未输入
if (minus) {
num1->ipart = -num;
} else {
num1->ipart = num;
}
ipart = 1;
num = point = minus = pcounter = counter = 0;
} else if (c != 'i' && !rpart && (counter || pcounter)) { // 检测为实数 实部未输入 已经检测到前面的数据
if (minus) {
num1->rpart = -num;
} else {
num1->rpart = num;
}
rpart = 1;
num = counter = minus = point = pcounter = 0;
} else if(rpart && !ipart && (counter || pcounter)) {
if (minus) {
num1->ipart = -num;
} else {
num1->ipart = num;
}
ipart = 1;
num = counter = minus = point = pcounter = 0;
}
/* 读入负号开启负号模式 */
} else if (c == '-' && digitmode) {
if (minus) {
num1->rpart = -num;
} else {
num1->rpart = num;
}
digitmode = num = counter = point = pcounter = 0;
minus = rpart = 1;
} else if (c == '-') {
digitmode = 0;
minus = 1;
/* 读入小数点开始小数点模式 */
} else if (c == '.') {
digitmode = point = 1;
pcounter = 0;
/* 小数点模式数据处理 */
} else if (isdigit(c) && point) {
digitmode = 1;
pcounter++;
thatone = c - '0';
for (i = 0; i < pcounter; i++) {
thatone /= 10;
}
num += thatone;
} else if (isdigit(c)) {
digitmode = 1;
counter++;
thisone = c - '0';
num *= 10;
num += thisone;
}
if (c == '\n') {
break;
}
}
fflush(stdin);
if (!ipart && !rpart) {
printf("发生错误,识别不能,重新输入看看\n");
return 1;
} else if (!ipart && rpart) {
num1->ipart = 0;
return 0;
} else if (ipart && !rpart) {
num1->rpart = 0;
return 0;
} else {
return 0;
}
}
void plus(complex num1, complex num2, complex *num3)
{
num3->rpart = num1.rpart + num2.rpart;
num3->ipart = num1.ipart + num2.ipart;
}
void minus(complex num1, complex num2, complex *num3)
{
num3->rpart = num1.rpart - num2.rpart;
num3->ipart = num1.ipart - num2.ipart;
}
void times(complex num1, complex num2, complex *num3)
{
num3->rpart = num1.rpart * num2.rpart - num1.ipart * num2.ipart;
num3->ipart = num1.ipart * num2.rpart + num1.rpart * num2.ipart;
}
int multi(complex num1, complex num2, complex *num3)
{
if (num2.ipart == 0 && num2.rpart == 0) {
return 1;
} else {
num3->rpart = (num1.rpart * num2.rpart + num1.ipart * num2.ipart) / (num2.rpart * num2.rpart + num2.ipart * num2.ipart);
num3->ipart = (num1.ipart * num2.rpart - num1.rpart * num2.ipart) / (num2.rpart * num2.rpart + num2.ipart * num2.ipart);
return 0;
}
}
void output(complex num3)
{
if (num3.ipart == 1 && num3.rpart != 0) {
printf("%g+i\n", num3.rpart);
} else if (num3.ipart == -1 && num3.rpart != 0) {
printf("%g-i\n", num3.rpart);
} else if (num3.ipart == 1 && !num3.rpart) {
printf("i\n");
} else if (num3.ipart == -1 && !num3.rpart) {
printf("-i\n");
} else if (!num3.ipart) {
printf("%g\n", num3.rpart); // 虚部为0 不显示
} else if (!num3.rpart) {
printf("%gi\n", num3.ipart); // 实部为0 不显示
} else if (num3.ipart > 0) {
printf("%g+%gi\n", num3.rpart, num3.ipart); // 虚部大于0 手动增加加号
} else {
printf("%g%gi\n", num3.rpart, num3.ipart);
}
}
int main(void)
{
complex num1, num2, num3;
char c;
int state;
printf("天家的复数计算器 V2.0\n");
printf("按下键盘上的按键来操作吧(菜单全都区分大小写呢~)! \n\tIt's the beginning. w.输入 h.帮助及关于 q.退出\n");
while (c = getchar()) {
fflush(stdin);
if (c == 'w') {
printf("输入两个复数咯~a+bi,b+ai都行,手滑打错也行!我会努力看懂的!\n");
state = 0;
do {
if (state) {
printf("对不起我会好好加油的!请再次努力的调教我吧\n");
}
fflush(stdin);
while (input(&num1));
printf("唔,我觉得吧,你是想要说这个吧?:");
output(num1);
printf("按y或回车确认,按其他键重新输入:");
state = 1;
} while ((c = getchar()) != 'y' && c != '\n');
printf("机智的我,接下来开始录入第二个吧\n");
state = 0;
fflush(stdin);
do {
if (state) {
printf("对不起我会好好加油的!请再次努力的调教我吧\n");
}
fflush(stdin);
while (input(&num2));
printf("所以这次你想输入的数字是这个咯?:");
output(num2);
printf("按y或回车确认,按其他键重新输入:");
} while ((c = getchar()) != 'y' && c != '\n');
printf("成功录入第二个数,接下来算吧\n");
} else if (c == 'h') {
printf("改啊改啊改,终于我还是重写了,这也真是醉了。。。讲完了\n\n");
printf("按下键盘上的按键来操作吧(菜单全都区分大小写呢~)\n\t! It's the beginning. w.输入 h.帮助及关于 q.退出\n");
continue;
} else if (c == 'q') {
break;
} else {
printf("你在说什么,我听不懂\n");
continue;
}
fflush(stdin);
printf("又到了按键的时候了!(区分大小写):\n\ta.加法, b.减法, c.乘法, d.除法, r.返回上一级(退出或重新输入)\n");
while (c = getchar()) {
fflush(stdin);
if (c == 'a') {
plus(num1,num2, &num3);
printf("加法 ");
} else if (c == 'b') {
minus(num1,num2, &num3);
printf("减法 ");
} else if (c == 'c') {
times(num1,num2, &num3);
printf("乘法 ");
} else if (c == 'd') {
if (multi(num1,num2, &num3)) {
printf("出错了,被除数不能为0\n");
continue;
}
printf("除法 ");
} else if (c == 'r') {
printf("按下键盘上的按键来操作吧(菜单全都区分大小写呢~)\n\t! It's the beginning. w.输入 h.帮助及关于 q.退出\n");
break;
} else {
printf("输入错误,请重新输入\n");
continue;
}
printf("我帮你算的结果: ");
output(num3);
}
}
printf("感谢使用,下次再见~再敲一下键盘我就走啦");
getchar();
/*
input(&num1);
input(&num2);
printf("%f %f\n %f %f", num1.rpart, num1.ipart, num2.rpart, num2.ipart);
*/
/*
int a, b;
if (!scanf("%d", &a)) {
printf("hhh");
}
*/
return 0;
}
这个版本的关键是通过各种开关来控制,实际上是以前有写过类似的代码,或者说是得到了师匠讲的getchar()
的启示,怒写之,具体都在注释上了,主要似乎还是拿点东西,只是姿势不一样而已,当然,这里有个更高端的,留待我们研究:
C:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int states[][256] = {
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,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
};
int first_token(char *s, int *token_len)
{
int state, new_state, i, len;
for (state = i = 0, len = strlen(s); i <= len; i++) {
new_state = states[state][s[i]];
if (new_state == 0) {
break;
}
state = new_state;
}
*token_len = i;
return state;
}
int main(void)
{
char s[256], tmp;
int current, token_type, token_len;
// get line from stdin
fgets(s, 256, stdin);
for (current = 0; ; current += token_len) {
token_type = first_token(&s[current], &token_len);
switch (token_type) {
case 0:
printf("Unknown character %c\n", s[current+token_len]);
exit(-1);
case 1:
case 2:
tmp = s[current+token_len];
s[current+token_len] = '\0';
printf("Real part found %s\n", &s[current]);
s[current+token_len] = tmp;
break;
case 3:
tmp = s[current+token_len];
s[current+token_len] = '\0';
printf("Imag part found %s\n", &s[current]);
s[current+token_len] = tmp;
break;
case 4:
exit(0);
break;
}
}
return 0;
}
C++:
#include <iostream>
#include <string>
#include <cctype>
#include <cstdlib>
bool parseComplex(std::string& comp, double& real, double& imag)
{
decltype(comp.size()) current = 0;
auto peekChar = [&]() {
return (current >= comp.size()) ? '\0' : comp[current];
};
auto nextChar = [&]() {
auto ch = peekChar();
if (ch) {
current++;
}
return ch;
};
auto eatSpaces = [&]() {
if (isspace(peekChar())) {
nextChar();
}
};
auto nextNumber = [&](double& result) {
char ch;
auto start = current;
bool inFrac = false;
bool succeeded = false;
eatSpaces();
if ((ch = peekChar()) == '+' || ch == '-') {
nextChar();
}
while ((ch = (eatSpaces(), peekChar()))) {
if (ch == '.' && !inFrac) {
inFrac = true;
} else if (isdigit(ch)) {
// go on
succeeded = true;
} else {
break;
}
nextChar();
}
result = succeeded ? std::atof(std::string(comp, start, current - start).c_str()) : 0;
return succeeded;
};
real = 0;
imag = 0;
for (; peekChar(); ) {
int sign = (eatSpaces(), peekChar()) == '-' ? -1 : 1;
double n;
bool succeeded = nextNumber(n);
if ((eatSpaces(), peekChar()) == 'i') {
imag += succeeded ? n : sign * 1.0;
nextChar();
} else {
real += n;
}
}
return true;
}
int main()
{
std::string comp = "5i+2i+3+2";
double real, imag;
if (parseComplex(comp, real, imag)) {
std::cout << real << ", " << imag << std::endl;
}
return 0;
}
植入部分
如果您觉得文章不错,可以通过赞助支持我。
如果您不希望打赏,也可以通过关闭广告屏蔽插件的形式帮助网站运作。
一进技术帝的博客,我就傻眼了,直接看不懂啊。
爱因斯坦在哪里啊 这难度