PTA 切分表达式——写个tokenizer吧

这篇博客介绍了一个针对低年级C语言学习者的编程题目,要求将四则运算表达式的每个token(运算数、运算符、括号)正确切分。题目保证输入表达式合法,主要难点在于判断正负号是运算符还是符号。代码示例给出了如何通过字符判断和移动字符串来实现切分,并给出了详细的解释和判断逻辑。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

[先说点出题背景]

这个题是为低年级同学、学C语言的同学准备的,因为,对这部分同学,这个题目编写起来略有一点复杂。如果是高年级、学过了正则表达式(Regular Expression)的同学或者学过了Java等OO语言的同学做这个题,应当发现这题比较简单吧。哦,对了,什么是tokenizer?请自行查询解决。反正在此处不应翻译成“令牌解析器”。

[正题]

四则运算表达式由运算数(必定包含数字,可能包含正或负符号小数点)、运算符(包括+-*/)以及小括号(())组成,每个运算数、运算符和括号都是一个token(标记)。现在,对于给定的一个四则运算表达式,请把她的每个token切分出来。题目保证给定的表达式是正确的,不需要做有效性检查。

输入格式:

在一行中给出长度不超过40个字符的表达式,其中没有空格,仅由上文中token的字符组成

输出格式:

依次输出表达式中的tokens,每个token占一行。

输入样例:

32*((2-2)+5)/(-15)

输出样例:

32
*
(
(
2
-
2
)
+
5
)
/
(
-15
)

 代码:

#include<stdio.h>
#include<string.h>


void move(char a[])
// 作用是把输入的字符串往后移一个单位,然后把第0个元素替换为-1
{
    int len = strlen(a);
    for (int i = len; i >= 1; i--)
    {
        a[i] = a[i - 1];
    }
    a[0] = -1;
}


int judge(char ch)
// 判断字符的类型,分为运算数和符号两大类, 运算数(包括小数点)——>0
// 符号可以细分为 正负号——>1    乘除和右括号)——>2   左括号(——>3
{
    if ((ch <= '9' && ch >= '0') || ch == '.') return 0; 
    if (ch == '+' || ch == '-') return 1;
    if (ch == '*' || ch == '/' || ch == ')') return 2;
    if (ch == '(') return 3;
    else return -1;  // 其他类返回-1(为了第0个字符特别准备
}


int main()
{
    char str[50] = {0};
    scanf("%s", str); move(str);  // 输入和转化
    int len = strlen(str);

    for (int i = 1; i < len; i++)
    {
        int judge_this = judge(str[i]);  // 分别判断此字符,上一个字符,下一个字符的类型
        int judge_next = judge(str[i + 1]);
        int judge_before = judge(str[i - 1]);

        printf("%c", str[i]); 

        // 以下是重点
        // 运算数——>0  正负号——>1  乘除和右括号)——>2  左括号(——>3  其他类返回-1

        // 乘除和括号自己就是一个token,不可能与后来的字符组成别的token,直接打印回车
        if (judge_this == 2 || judge_this == 3) printf("\n");

        // 运算数后必须要跟着运算数才能组成一个token,否则回车
        if (judge_this == 0 && judge_next != 0) printf("\n");

        // 加减号如果上一个字符是左括号 或者 是第一个字符 才可能跟后面的数字(后面一定是数字) 组成token
        // 之前定义的 move 把字符串向后移动一位的作用就在这
        if (judge_this == 1 && (judge_before != 3 && judge_before != -1)) printf("\n");
    }
    return 0;
}

总结:

因为题目说输入都是合法的,所以小数点必定不会出现在运算数的结尾
本题的难点判断在+-号上,到底是运算符还是正负号

如何判断:

        如果孤零零的在开头,肯定是正负号

        如果不在开头,但是前面是左括号,也是正负号

        其他情况都是运算符

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值