
一 前言
在编程中,对字符串进行操作是很常见的。但是TI-Nsipre 对字符进行操作的函数有限,缺少一些如在字符串中插入字符、删除字符等常用功能,给编程带来不便。笔者经过研究,实现了在字符串中插入字符、删除字符、拆分字符的方法,并将它们编写成了相应的函数,可以在编程中直接调用,提高了字符串处理编程的效率。
二 总览
TI-Nspire 系列中,字符串是操作系统自带数据类型之一。通过 GetType() 函数[1],我们可以求证这一点。

对于该数据类型,TI-BASIC 提供了多种操作函数,但并不完善 / 不符合直觉。本文旨在简述这些函数的应用,并实现一些常用功能。
接下来笔者将介绍它的一些奇怪之处,读者一定要注意。
1. 字符串和字符的关系
一般的编程语言中,字符串是字符数组的语法糖[2]。但在 TI-BASIC 中,并没有所谓“字符”的概念。如果想要表示“字符”,TI-BASIC 使用的是长度为 1 的字符串。
2. 随机访问

由于 TI-BASIC 没有“字符”的概念,字符串也不是字符数组,自然不能使用下标随机访问字符。如果有随机访问的需求,需要使用函数替代。该操作在后文将会提到。
3. 与列表的关系
虽然 TI-BASIC 的字符串不是列表,但以下列出的许多函数都同时适用于列表和字符串。但很关键的一点是,countIf() 不支持字符串而仅支持列表。后文将给出笔者对 countIfStr() 的实现。
三 常用系统函数汇总
TI-BASIC 为字符串提供了多种函数和运算符。这些函数和运算符的说明在官方 reference 文档中分布过于散乱,在此处给出汇总。
1. dim(str) -> len

返回字符串 str 的长度 len。
2. mid(str, beg, len) -> substr

倒着dim(大雾,划掉)
返回字符串 str 从第 beg 位开始的长度为 len 的子字符串。
可以用于随机访问字符串中的某一个字符。
3. left(str, pos) -> substr

返回字符串 str 从左至右第 pos 个字符及以前的所有字符组成的子字符串。
4. right(str, pos) -> substr

返回字符串 str 从右至左第 pos 个字符及以后的所有字符组成的子字符串。
5. inString(str, sub [, beg]) -> pos

在字符串 str 中查找子字符串 sub,可选指定查找起始点 beg。
返回 sub 在 str 中第一次出现的首位字符位置。
如果未找到,则返回 0。
6. expr(str) -> result

将字符串 str 当作表达式进行求值,返回计算结果。
CAS 机型能够计算含未知参数的表达式,而非 CAS 机型遇到未知参数将会报错。
值得注意的是,str 中如果存在 TI-BASIC 语句,也将会被正确执行。

在 TI-BASIC 的传统中,冒号 (':') 会被作为换行的替代符号[3]。因此,即便TI-BASIC不支持转义字符,使用 expr 函数执行储存在字符串中的多行代码也是完全可行的。
结合其他字符串操作函数,该函数为今后实现类并进行面向对象编程,甚至函数式编程,打下了坚实的基础。
ps:亲爱的读者们,如果有人问你们,TI-BASIC 里边除了三角函数之外还有哪一对函数是在一个可用的函数后添加一个字符依然是可用函数名的,你们可以回答“exp() 和 expr()”。
7. string(expr) -> str

将表达式 expr 求值后的结果转换为字符串 str 并返回。
在计算过程中,CAS 机型会将未知参数名直接转换为字符串,非 CAS 机型会报错。
如果尝试将一个字符串转换为一个字符串,则它会被加上一对英文引号。
8. format(val, fmt) -> str

将值 val 以格式控制字符串 fmt 指定的格式转化为字符串 str。
fmt 的可选格式引用自官方文档:
fmt 必须是如下形式的字符 串:“F[n]”、“S[n]”、“E[n]”、“G[n][c]”,其 中 [ ] 表示可选的部分。
F[n]:Fixed 格式。n 为小数点后显示的位数。
S[n]:Scientific 格式。n 为小数点后显示的位数。
E[n]:Engineering 格式。n 为第一个有效数字后的位数。指数将调整为三的倍数,并且小数点向右移零位、一位或两位。
G[n][c]:与固定格式相同,但也将小数点左边的数位每三个分为一组。如果 c 为句号,则小数点将显示为逗号。
[Rc]:上述指定符可以加上一个以 Rc 小数点标记的后缀,其中 c 是单个字符, 指明替代小数点的符号。
9. str1 & str2 (字符串联结运算符)

该运算符用于将两个字符串连接起来。可以连续使用。
10. #(str) (间接运算符)

该运算符用于将字符串 str 转换为变量或函数名,以创建 / 修改 / 调用变量或函数。
11. char(int) -> str 和 ord(str) -> int

这两个函数是一对。
char() 用于将整数参数 int 转换为其在 TI-Nspire 字符集中对应的字符组成的单字符字符串 str,而 ord(str) 将传入的字符串 str 的首位字符转化为其在 TI-Nspire 字符集中的序号 int。
12. 附注
TI-BASIC 还提供了一些令人不明用途的函数。
例如 rotate() 被用于字符串的用法,过于诡异以至于令人无法理解如何运用于实际,在此暂且不作说明。如果有兴趣,可以在 ReferenceGuide 中查找 rotate() 和 shift() 这两个函数。
四 常用功能实现
结合以上所有函数及常规编程知识,可以实现一些令字符串操作更加便捷的实用函数。
1. 在一个字符串 str 中的指定位置 pos 处插入一个子串 tgt
Define insert(str,pos,tgt)=
Func
Return left(str,pos-1) & tgt & right(str,dim(str)-pos+1)
EndFunc
2. 在一个字符串 str 中从指定位置 pos 开始,移除之后的 len 个字符
Define erase(str,pos,len)=
Func
Return left(str,pos-1)&right(str,dim(str)-(pos+len)+1)
EndFunc
3. countIf 的字符串版本
Define countifstr(str,chr)=
Func
Local i,cnt
0→cnt
For i,1,dim(str)If mid(str,i,1)=chr Thencnt+1→cntEndIf
EndFor
Return cnt
EndFunc
4. 以指定的 chr 为分隔符,将字符串 str 拆分为字符串单行矩阵
Define split(str,chr)=
Func
Local i,len,ls,cur,cnt
""→cur
1→cnt
countifstr(str,chr)+1→len
newMat(1,len)→ls
For i,1,dim(str)If mid(str,i,1)=chr Thencur→ls[1,cnt]cnt+1→cnt""→curElsecur&mid(str,i,1)→curEndIf
EndFor
cur→ls[1,cnt]
Return ls
EndFunc
5. 将字符串 str 拆分成字符单行矩阵
Define str2lst(str)=
Func
Local ls,i
newMat(1,dim(str))→ls
:For i,1,dim(str)mid(str,i,1)→ls[1,i]
EndFor
Return ls
EndFunc
6. 移除目标字符串 str 中的所有目标子字符串 sub
Define rmsub(str,sub)=
Func
Local ret
str→ret
While inString(ret,sub)≠0erase(ret,inString(ret,sub),dim(sub))→ret
EndWhile
Return ret
EndFunc
诸如此类的常用函数还能够实现很多。
五 结语
在 TI-BASIC 领域,字符串的应用空间极为广阔,而本文的这些总结和实现只是微不足道的一部分。
21 世纪是字符串的世纪(大雾),我们应当在字符串上投入足够的研究与思考,取得更好的成绩。
六 附件
这是包含了本文中所有代码实现的库。函数均以 LibPub 方式声明,可以直接将该文件拷贝到计算器的 MyLib 目录下进行体验。
参考
- ^TI-BASIC 用于获取变量类型的函数
- ^比如 C 语言
- ^这个传统似乎是从 Z80 系列开始的