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.htm
sscanf()过去也举过例子: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;
}

植入部分

如果您觉得文章不错,可以通过赞助支持我。

如果您不希望打赏,也可以通过关闭广告屏蔽插件的形式帮助网站运作。

标签: 成品, 源码, 代码段, 语法

已有 2 条评论

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

  2. 爱因斯坦在哪里啊 这难度

添加新评论