Lintcode_417 Valid Number

本文介绍了一种使用有限状态机的方法来判断给定字符串是否为有效的数值表示形式。通过定义不同的状态和输入类型,实现了一个简洁高效的解析算法。

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

Validate if a given string is numeric.

Example

"0" => true

" 0.1 " => true

"abc" => false

"1 a" => false

"2e10" => true


用有限状态机,非常简洁,不需要复杂的各种判断!

先枚举一下各种合法的输入情况:

1.空格+ 数字 +空格

2.空格+ 点 + 数字 +空格

3.空格+ 符号 + 数字 + 空格

4.空格 + 符号 + 点 + 数字 +空格

5.空格 + (1, 2, 3, 4) + e + (1, 2, 3, 4) +空格

组后合法的字符可以是:

1.数字

2.空格

有限状态机的状态转移过程:

起始为0:

  当输入空格时,状态仍为0,

  输入为符号时,状态转为3,3的转换和0是一样的,除了不能再接受符号,故在0的状态的基础上,把接受符号置为-1;

  当输入为数字时,状态转为1, 状态1的转换在于无法再接受符号,可以接受空格,数字,点,指数;状态1为合法的结束状态;

  当输入为点时,状态转为2,状态2必须再接受数字,接受其他均为非法;

  当输入为指数时,非法;

状态1:

  接受数字时仍转为状态1,

  接受点时,转为状态4,可以接受空格,数字,指数,状态4为合法的结束状态,

  接受指数时,转为状态5,可以接受符号,数字,不能再接受点,因为指数必须为整数,而且必须再接受数字;

状态2:

  接受数字转为状态4;

状态3:

  和0一样,只是不能接受符号;

状态4:

  接受空格,合法接受;

  接受数字,仍为状态4;

  接受指数,转为状态5,

状态5:

  接受符号,转为状态6,状态6和状态5一样,只是不能再接受符号,

  接受数字,转为状态7,状态7只能接受空格或数字;状态7为合法的结束状态;

状态6:

  只能接受数字,转为状态7;

状态7:

  接受空格,转为状态8,状态7为合法的结束状态;

  接受数字,仍为状态7;

状态8:

  接受空格,转为状态8,状态8为合法的结束状态;

复制代码
 1 class Solution
 2 {
 3 public:
 4     bool isNumber(const char *s)
 5     {
 6         enum InputType
 7         {
 8             INVALID,    // 0
 9             SPACE,      // 1
10             SIGN,       // 2
11             DIGIT,      // 3
12             DOT,        // 4
13             EXPONENT,   // 5
14             NUM_INPUTS  // 6
15         };
16         
17         int transitionTable[][NUM_INPUTS] =
18         {
19             -1,  0,  3,  1,  2, -1,     // next states for state 0
20             -1,  8, -1,  1,  4,  5,     // next states for state 1
21             -1, -1, -1,  4, -1, -1,     // next states for state 2
22             -1, -1, -1,  1,  2, -1,     // next states for state 3
23             -1,  8, -1,  4, -1,  5,     // next states for state 4
24             -1, -1,  6,  7, -1, -1,     // next states for state 5
25             -1, -1, -1,  7, -1, -1,     // next states for state 6
26             -1,  8, -1,  7, -1, -1,     // next states for state 7
27             -1,  8, -1, -1, -1, -1,     // next states for state 8
28         };
29         
30         int state = 0;
31         while (*s != '\0')
32         {
33             InputType inputType = INVALID;
34             if (isspace(*s))
35                 inputType = SPACE;
36             else if (*s == '+' || *s == '-')
37                 inputType = SIGN;
38             else if (isdigit(*s))
39                 inputType = DIGIT;
40             else if (*s == '.')
41                 inputType = DOT;
42             else if (*s == 'e' || *s == 'E')
43                 inputType = EXPONENT;
44             
45             state = transitionTable[state][inputType];
46             
47             if (state == -1)
48                 return false;
49             else
50                 ++s;
51         }
52         
53         return state == 1 || state == 4 || state == 7 || state == 8;
54     }
55 };
复制代码
0




<think>好的,我现在需要回答用户关于倍福TwinCAT 3中__ISVALID函数的用法及其与NaN值处理的问题。首先,我得回忆一下之前用户的问题和我的回答,确保这次回答保持一致,并且补充更多细节。 用户之前问过如何将NaN转换为常数,我介绍了使用__ISVALID函数来检测并替换。现在他们想深入了解这个函数的具体用法和处理NaN的关系。首先,我需要明确__ISVALID的功能,它是如何检测数值有效性的,包括NaN、无穷大等。 接下来,我应该详细说明函数的语法、参数、返回值,以及适用的数据类型。可能需要提到它支持REAL和LREAL这两种浮点类型。然后,结合NaN处理,给出具体的代码示例,比如在ST语言中如何使用条件判断来替换NaN值为常数。此外,应用场景也很重要,比如数据采集后的处理、通信数据校验等,这些都需要举例说明。 还要注意用户提到的引用内容,里面提到了C#和C++的代码,虽然用户现在的问题集中在TwinCAT本身的函数,但可能需要简要提及如何在其他语言中处理类似问题,但重点还是在PLC端的处理。另外,要强调使用时的注意事项,比如实时性要求、性能影响以及调试技巧,比如使用Trace记录数值变化。 最后,生成的相关问题需要和之前的保持一致,比如浮点数溢出、PLC性能优化、IEC数据类型等,同时可能加入关于其他无效值处理的问题,确保问题相关且有深度。 需要检查是否所有数学表达式都正确使用了$...$格式,例如$__ISVALID(var)$,以及是否有独立公式需要单独成段,但看起来这次内容可能不需要。确保中文回答,语法正确,结构清晰,分步骤说明,引用之前的注意事项作为参考,比如在数据采集后立即检测避免错误传播,这可以引用之前的回答中的[^1]。 总结步骤:介绍函数功能,详细参数说明,处理NaN的代码示例,应用场景,注意事项,相关问题。确保覆盖用户所有疑问点,并保持回答的连贯性和专业性。</think>### TwinCAT 3 中 `__ISVALID` 函数用法与 NaN 值处理详解 --- #### 一、`__ISVALID` 函数核心功能 1. **数值有效性检测** - 用于检查浮点数($REAL/LREAL$)是否为有效值,可识别以下异常状态: - $NaN$(非数值,如 $\sqrt{-1}$ 或 $0/0$ 计算结果) - 正/负无穷大(如 $1/0$ 或 $\log(0)$) - 函数原型: $$ \text{BOOL} \_\_ISVALID(\text{ANY\_REAL}) $$ 输入为 $REAL$ 或 $LREAL$,返回 $TRUE$ 表示有效,$FALSE$ 表示无效[^1]。 2. **与 NaN 处理的关系** - TwinCAT 未直接提供 $NaN$ 的显式判断函数,需通过 `__ISVALID` 间接检测。 - 逻辑等价关系: $$ \neg \_\_ISVALID(x) \Leftrightarrow (x = NaN \ \lor \ x = \pm \infty) $$ --- #### 二、具体使用方法 ##### 1. 基础语法(ST 语言示例) ```pascal VAR value : REAL := 0.0; isValid : BOOL; END_VAR isValid := __ISVALID(value); // 返回TRUE/FALSE ``` ##### 2. NaN 值替换实现 ```pascal FUNCTION_BLOCK FB_ReplaceNaN VAR_INPUT inVal : REAL; replaceVal : REAL := 0.0; // 默认替换值 END_VAR VAR_OUTPUT outVal : REAL; END_VAR IF NOT __ISVALID(inVal) THEN outVal := replaceVal; // 替换无效值 ELSE outVal := inVal; // 保持原值 END_IF ``` ##### 3. 多场景应用 - **数据采集过滤** 在模拟量输入后立即调用 `__ISVALID`,避免无效值进入控制逻辑。 - **通信数据校验** 对 ADS 通信或外部设备传入的浮点数进行有效性验证。 - **数学运算保护** 在复杂计算(如 $f(x)=\ln(x)$)前预检输入值,防止生成新 $NaN$。 --- #### 三、关键注意事项 1. **实时性要求** - 在 $1ms$ 周期任务中处理时,需确保函数块执行时间不超过任务周期[^1]。 - 避免在高速控制循环中频繁调用复杂检测逻辑。 2. **性能优化** - 对批量数据可使用数组遍历检测: ```pascal FOR i := 1 TO ARRAY_LEN(data) DO IF NOT __ISVALID(data[i]) THEN data[i] := 0.0; END_IF END_FOR ``` 3. **调试技巧** - 使用 TwinCAT Scope 或 Trace 工具记录 `__ISVALID` 触发时的变量值。 - 结合 `ADSLOGSTR` 函数记录异常事件(需配置 TwinCAT 日志模块)。 --- #### 四、扩展应用示例 ##### 安全除法函数(防除零错误) ```pascal FUNCTION SafeDivide : REAL VAR_INPUT numerator : REAL; denominator : REAL; END_VAR IF (denominator = 0) OR (NOT __ISVALID(denominator)) THEN SafeDivide := 0.0; ELSE SafeDivide := numerator / denominator; END_IF ``` --- ### 相关问题 1. TwinCAT 3 中如何检测浮点数溢出? 2. 如何通过 ADS 通信实现 PLC 与 C# 程序的 NaN 值同步处理? 3. IEC 61131-3 标准中哪些数据类型支持 `__ISVALID` 检测?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值