第5章:5.2 字符数组(MATLAB入门课程)

这篇具有很好参考价值的文章主要介绍了第5章:5.2 字符数组(MATLAB入门课程)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

讲解视频:可以在bilibili搜索“MATLAB教程新手入门篇——数学建模清风主讲”。

MATLAB教程新手入门篇(数学建模清风主讲,适合零基础同学观看)_哔哩哔哩_bilibili

5.2.1 单个字符  

上一小节提过:字符(char)是文本的最基本单元。MATLAB中,单个字符使用单引号引起来,例如:'a''0'''。(一定要是英文输入法下的单引号,中文的会报错)

下面我们介绍两个简单的函数,它能实现字符和对应的Unicode编码的转换。

double函数可以获取字符对应的Unicode编码(十进制)。

第5章:5.2 字符数组(MATLAB入门课程),MATLAB教程新手入门篇(数学建模清风主讲),数学建模,matlab

char函数可以将Unicode编码(十进制)转换为对应的字符。

第5章:5.2 字符数组(MATLAB入门课程),MATLAB教程新手入门篇(数学建模清风主讲),数学建模,matlab

在MATLAB中,字符在计算机的内存中是以其UTF-16格式对应的Unicode编码值存储的,这意味着我们可以在它们之间进行算术运算。当对字符进行算术运算时,MATLAB会自动将其转换为对应的十进制编码。

第5章:5.2 字符数组(MATLAB入门课程),MATLAB教程新手入门篇(数学建模清风主讲),数学建模,matlab

与字符之间的算术运算类似,MATLAB也允许将字符与数值一起计算。

第5章:5.2 字符数组(MATLAB入门课程),MATLAB教程新手入门篇(数学建模清风主讲),数学建模,matlab

另外,字符向量也支持关系运算,例如'A' == 65会返回逻辑值1,'A' > 'a'会返回逻辑值0.

下面我们来看一个思考题:用户输入一个英文字母,如果该字母是大写,则输出它的小写;如果该字母是小写,则输出它的大写(不需要考虑用户输入非英文字母的情况,也不需要考虑用户输入多个字符的情况)。

第5章:5.2 字符数组(MATLAB入门课程),MATLAB教程新手入门篇(数学建模清风主讲),数学建模,matlab

5.2.2 字符向量

在上一小节中,我们了解到单个字符(即字符标量)是使用单引号引起来的。当我们将多个字符连续放置在同一对单引号中,就创建了一个字符向量,例如:'abc'、'001'、'我喜欢你'。字符向量中的每个元素都是字符标量,类似于数值向量中的每个元素都为数值标量。

在第三章,我们提到了向量(在不引起混淆的情况下,数值向量我们通常简称为向量)是由中括号括起来的。其中,向量中元素如果由逗号或空格隔开,构成的是行向量;如果由分号或回车键隔开,构成的是列向量。对字符向量而言,生成方式也是类似的:

第5章:5.2 字符数组(MATLAB入门课程),MATLAB教程新手入门篇(数学建模清风主讲),数学建模,matlab

通常,行字符向量可用于表示单词、句子等文本,我们将多个字符放置在同一对单引号中的本质就是生成了一个行字符向量,因此它的应用场景比列字符向量更为广泛。后续章节中,在不引起混淆的情况下,我们通常将行字符向量简称为字符向量

我们可以对字符向量使用double函数,这样可以得到该字符向量中各字符元素对应的Unicode编码(十进制),返回的是一个数值向量。

第5章:5.2 字符数组(MATLAB入门课程),MATLAB教程新手入门篇(数学建模清风主讲),数学建模,matlab

类似的,我们也可以将一个数值向量使用char函数转换为字符向量。

第5章:5.2 字符数组(MATLAB入门课程),MATLAB教程新手入门篇(数学建模清风主讲),数学建模,matlab

和单个字符类似,字符向量也能进行算术运算和关系运算,例如:

第5章:5.2 字符数组(MATLAB入门课程),MATLAB教程新手入门篇(数学建模清风主讲),数学建模,matlab

注意,第三章中我们介绍了MATLAB支持的五种算术运算的兼容模式,字符向量的计算也要满足这五种兼容模式,否则MATLAB就会报错:

第5章:5.2 字符数组(MATLAB入门课程),MATLAB教程新手入门篇(数学建模清风主讲),数学建模,matlab

和数值向量类似,字符向量也能通过索引的方式进行引用、修改和删除,下面我们来看几个例子。

第5章:5.2 字符数组(MATLAB入门课程),MATLAB教程新手入门篇(数学建模清风主讲),数学建模,matlab

此外,我们还可以对字符向量进行拼接、重复、排序、翻转等操作,这些操作和第三章中介绍的对数值向量的操作非常相似。

第5章:5.2 字符数组(MATLAB入门课程),MATLAB教程新手入门篇(数学建模清风主讲),数学建模,matlab

下面我们再来介绍几个要重点关注的地方:

1. 字符向量中有单引号怎么办

我们知道,字符向量是使用单引号引起来的,如果字符向量中也出现了单引号,就需要使用两个连续的单引号来表示它,例如我们想使用字符向量表示文本:I'm Li Hua.

第5章:5.2 字符数组(MATLAB入门课程),MATLAB教程新手入门篇(数学建模清风主讲),数学建模,matlab

2. 字符向量中如何添加换行符

换行符对应的Unicode编码为10,因此我们可以使用char(10)得到一个换行符。假如我们想在古诗'春眠不觉晓,处处闻啼鸟。'中的逗号后面换行,那么可以这么做:

第5章:5.2 字符数组(MATLAB入门课程),MATLAB教程新手入门篇(数学建模清风主讲),数学建模,matlab

上面代码中用到了字符向量的引用和拼接,这样就能将换行符添加到逗号后面。另外,MATLAB中提供了创建换行符的函数newline,它和char(10)完全相同,但增加了代码的可读性。因此,上面代码的最后一行我们也可以改成:c_new = [c1, newline, c2]

事实上,MATLAB中也提供了相应的内置函数insertBefore和insertAfter,它们能实现在指定的文本前后插入新的文本的功能,本章后面会介绍。

3. 计算字符向量中字符的数量

和数值向量类似,我们可以使用length 函数或 numel 函数计算字符向量中字符的数量,如果使用size函数,那么将同时返回字符向量的行数和列数。

第5章:5.2 字符数组(MATLAB入门课程),MATLAB教程新手入门篇(数学建模清风主讲),数学建模,matlab

4. 比较两个字符向量是否相同

在第三章中介绍过,我们可以使用关系运算符==来比较两个数值向量的元素是否相同,两个数值向量的大小必须满足算术运算中介绍的五种兼容模式才能进行比较,并返回一个逻辑数组。要比较两个字符向量的元素是否相同也可以使用==,它们的大小也必须满足五种兼容模式,我们来看下面的例题:

第5章:5.2 字符数组(MATLAB入门课程),MATLAB教程新手入门篇(数学建模清风主讲),数学建模,matlab

注意,如果要比较两个字符向量是否完全相同(现在要比较的不是元素,而是整体),我们可以使用strcmp函数,如果完全相同就会返回逻辑值1;否则返回逻辑值0。

第5章:5.2 字符数组(MATLAB入门课程),MATLAB教程新手入门篇(数学建模清风主讲),数学建模,matlab

另外,还有三个内置函数和strcmp非常相似,它们分别是:strcmpi、strncmp和strncmpi.

下面这张表格可以帮助大家区分这四个函数的功能:

第5章:5.2 字符数组(MATLAB入门课程),MATLAB教程新手入门篇(数学建模清风主讲),数学建模,matlab

如何记忆:str是string(字符串)的缩写,cmp是compare(比较)的缩写。如果最后有i,则表示对字母的大小写insensitive(不敏感);str和cmp中间如果有n,则表示比较的是前n个字符。我们后续用的最多的就是strcmp函数。

下面举几个例子帮助大家理解:

第5章:5.2 字符数组(MATLAB入门课程),MATLAB教程新手入门篇(数学建模清风主讲),数学建模,matlab

事实上,这几个函数不仅能用于字符向量的比较,还能用于本章后面要讲的字符矩阵、字符向量元胞数组、字符串数组的比较。大家可以在MATLAB官网查看strcmp函数的帮助文档,可以很清楚的看到输入参数所支持的数据类型:

第5章:5.2 字符数组(MATLAB入门课程),MATLAB教程新手入门篇(数学建模清风主讲),数学建模,matlab

下面我们一起来做几道练习题,这些练习题将更好的帮助大家掌握本小节的内容。

(1)给定一个字符向量,请将字符向量中的小写英文字母转换为大写英文字母,其他的字符保持不变。

c = '我会Matlab、Python、Spss等软件!';
d = double(c);
% 97至122代表小写字母 'a' 至 'z',65至90代表大写字母 'A' 至 'Z'
ind = d >= 97 & d <= 122; % 筛选出d中数值位于97和122之间的元素
d(ind) = d(ind) - 32;  
cc = char(d)  % 转换回字符向量
%  cc =  '我会MATLAB、PYTHON、SPSS等软件!'  (思考:你可以不借助double函数吗?)

上述代码的思路如下:

  • 将字符向量c通过double函数转换成对应的Unicode编码,并保存在数值向量d中。
  • 接下来,通过关系运算和逻辑运算创建了一个索引向量ind,这个向量是一个逻辑数组,用于标记d中所有小写字母的位置(小写字母的Unicode编码范围是97至122)。
  • 然后,使用这个逻辑索引更新向量d中的这些特定位置的值,将它们转换成大写字母的Unicode编码。由于Unicode编码中小写字母和对应的大写字母之间的差值恒定为32,所以只需要从小写字母的编码中减去32即可得到对应的大写字母编码。
  • 最后,将更新后的数值向量d再转换回字符向量cc,这是通过char(d)实现的,此时所有原始字符向量c中的小写字母都已经被转换为大写字母,而其他字符保持不变。

事实上,MATLAB的内置函数upper就能实现这一功能:newStr = upper(str) 将 str 中的所有小写字母转换为相应的大写字母并保留所有其他字符不变;相应地,内置函数lower可以将所有的大写字母转换为相应的小写字母,并保留所有其他字符不变。

第5章:5.2 字符数组(MATLAB入门课程),MATLAB教程新手入门篇(数学建模清风主讲),数学建模,matlab

(2)实现内置函数strcmp的功能(仅需要考虑比较的两个文本都是字符向量的类型)。

% 要比较的两个字符向量分别为c1和c2
c1 = 'abc';
c2 = 'Abc';  
% flag是标志变量,为逻辑值1则代表c1和c2完全相同,为逻辑值0则说明不同
flag = all(size(c1) == size(c2)) && ...  三个点 ... 用来表示行的延续
    all(c1 == c2)  % 实际上这一行代码是上一行中没写完的部分

上述代码的思路如下:

条件1:使用size(c1) == size(c2)比较两个字符向量的大小是否相同。注意size函数会返回包含两个元素的向量,分别代表字符向量的行数和列数,因此size(c1) == size(c2)会返回一个长度为2的逻辑向量,我们对这个逻辑向量使用了一个all函数:all(size(c1) == size(c2)),只有行数和列数均相同时才会返回逻辑值1。

条件2:如果c1和c2的大小相同,此时使用关系运算符c1==c2检查它们在各个位置的字符是否都相同。字符均相同时c1==c2会返回全为逻辑值1的逻辑向量,此时all函数会返回逻辑值1;只要有任意一个位置的字符不相同,all函数就会返回逻辑值0。

如果条件1和条件2都满足,那么flag为true,表示两个字符向量相同,否则为false。

注意,这里只能使用具有短路功能的逻辑与&&,不能使用普通的&。这是因为如果字符向量c1和c2的大小不兼容(例如c1='abc' ; c2 = 'abcd' ),使用c1==c2会报错。&& 的短路功能确保了如果第一个条件为逻辑值0(大小不相同),则不会判断第二个条件(即不会尝试比较元素),这样可以避免潜在的报错。

拓展:…(三个点/省略号) 表示行的延续。有时候一行代码很长,为了便于阅读和理解,我们可以使用 ... 将这行代码分割到多行。因此,上述代码中的 ... 使得我们可以在&&结束后,将剩下的 all(c1 == c2) 移到下一行,这不会改变代码的功能,只是为了提高代码的可读性。

如果行末尾之前存在三个或更多个点,则 MATLAB 会忽略该行的其余部分而直接延续到下一行。这相当于将当前行第一次出现的三个点之后的任何内容作为注释。

第5章:5.2 字符数组(MATLAB入门课程),MATLAB教程新手入门篇(数学建模清风主讲),数学建模,matlab

注意:在使用…分割代码之前,必须保证代码的完整性。例如你不能将3+66这样分割:

第5章:5.2 字符数组(MATLAB入门课程),MATLAB教程新手入门篇(数学建模清风主讲),数学建模,matlab

另外,要将…分割的多行命令中的一行注释掉,请在该行的开头使用 ...。如果使用 % 将某一行注释掉,MATLAB会报错(左侧是错误的写法,右侧才是正确的写法):

第5章:5.2 字符数组(MATLAB入门课程),MATLAB教程新手入门篇(数学建模清风主讲),数学建模,matlab

(3)本题很重要:统计字符向量中元音字母(aeiouAEIOU)出现的频率。

c = 'I wish you and your family good health, and all the best.';
ind = ismember(c,'aeiouAEIOU');
num = sum(ind)  % 元音字母出现的次数
pl = num / numel(c)  % 计算频率

上述代码的思路如下(配套的讲解视频中还给出了另外两种计算的思路):

首先,定义了一个字符向量c;

接着使用ismember函数来创建一个逻辑向量ind,ismember函数检查c中的每个字符是否为元音字母(即'aeiouAEIOU'中的任何一个字符)。如果是,在对应的位置为逻辑值1,否则为逻辑值0,因此这里的ind 等于[1 0 0 1 0 0 0 0 1 1 0 1 0 0 0 0 1 1 0 0 0 1 0 1 0 0 0 0 1 1 0 0 0 1 1 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 1 0 0 1 0 0 0] (注意:空格、标点符号等都要被判断哦!);

使用sum(ind)计算逻辑向量ind中逻辑值1的总数,也就是元音字母在字符向量c中出现的次数,将这个值存储在变量num中,得到num等于17;

最后,将元音字母出现的次数num除以字符向量c的总长度numel(c),这样就能计算c中元音字母出现的频率pl。

(4)凯撒密码是一种最简单的加密英文句子的方法,它通过将字母表中的字母向右或向左移动固定的偏移量来加密文本。例如,当偏移量是+3(正数表示向右移动)时,字母A变成了D,字母B变成了E,依此类推。同样地,字母Z会回绕到字母表的开头,变成C。

第5章:5.2 字符数组(MATLAB入门课程),MATLAB教程新手入门篇(数学建模清风主讲),数学建模,matlab

现在给你一个字符向量,请对它进行凯撒密码加密,其中偏移量设置为+3。其中,所有的非字母字符(如空格和标点符号)应保持不变、且字母的大小写也保持不变,大写字母加密后仍为大写,小写字母加密后仍为小写。(例如'I love you!'加密后为'L oryh brx!')

c = 'Retreat to the countryside tomorrow morning.';
cc = c; % 初始化加密后的字符向量等于c
offset = 3; % 定义偏移量
for i = 1:numel(c)  % 遍历字符向量c的每个字符
        if c(i) >= 'A' && c(i) <= 'Z'  % 判断当前字符是否为大写字母
            cc(i) = char(mod(c(i) - 'A' + offset, 26) + 'A');
        elseif c(i) >= 'a' && c(i) <= 'z'  % 判断当前字符是否为小写字母
            cc(i) = char(mod(c(i) - 'a' + offset, 26) + 'a');
        end   % 这里不需要else,对于非字母字符,它们保持不变
end
% 输出加密后的字符向量
disp(cc)
% Uhwuhdw wr wkh frxqwubvlgh wrpruurz pruqlqj.
% 注意,使用disp函数将字符向量输出到屏幕上时,不会显示字符向量的单引号

上述代码的思路如下(配套的讲解视频中还给出了另外两种思路,但不具有通用性):

变量cc被初始化为与c相同的值,即加密前的文本。offset设置为3,表示每个字母将向右移动3个位置。

接下来我们使用for循环遍历字符向量c的每个字符。

如果字符是大写字母(在'A'到'Z'之间),我们将其转换为一个0到25的数字(通过减去'A'),然后加上偏移量offset,接着使用mod函数进行模26运算。模26运算确保字母在超过'Z'后会回绕到字母表的开头。之后再加上'A'并将数字转回Unicode编码对应的大写字母。

以字符'Y'为例,'Y' - 'A' + 3等于27,mod(27,26)等于1,然后用1加上'A'并转换回相应字符后得到'B'。

小写字母的处理方法与大写字母相同,只是基于'a'进行转换。

在这段代码中,不需要加上else语句来处理非字母字符的情况,因为初始化cc = c时已经保留了非字母字符,只有当字符是字母时才会进行修改。

(5)编写程序将十进制正整数转换为对应的二进制字符向量。例如6对应的二进制字符向量为'110', 38对应的二进制字符向量为'100110'

具体的转换方法为:将这个十进制正整数除以2,得到对应的商和余数;接着再将商除以2,又会得到一个商和余数,如此重复下去,直到商为0时停止。最终将余数按照从后往前的顺序连起来,就能得到二进制数。以十进制数38为例,示意图如下:

第5章:5.2 字符数组(MATLAB入门课程),MATLAB教程新手入门篇(数学建模清风主讲),数学建模,matlab

绘图思路参考:知乎用户小雷孙

n = 38;  % 需要转换的十进制正整数
c = '';  % 初始化转换后的二进制数为空的字符向量
quotient = n;  % 初始化商等于n
while quotient > 0
remainder = mod(quotient, 2);  % 除以2的余数
quotient = fix(quotient / 2);  % 更新商
    c = [num2str(remainder), c];   % 更新c
end
disp(c)
% 100110

上述代码的思路如下:

初始化变量:定义要转换的十进制数n,空字符向量c用于存放最后的二进制结果,以及变量quotient用于在循环中存放商。

循环除以2:通过while循环,持续将quotient除以2,直到quotient为0为止。在每一次循环中,都会执行两个关键步骤:

(1)使用mod(quotient, 2)计算当前quotient除以2的余数;

(2)使用fix(quotient / 2)计算新的商,并赋值给quotient。

构建二进制字符向量:在每次循环中,将计算得到的余数使用num2str函数转换为字符,并添加到二进制字符向量c的最前面。这样做是因为余数是按照从后往前的顺序连起来的,即后计算得到的余数需要放在二进制字符向量c的前面。

输出结果:循环结束后,使用disp(c)输出转换后的二进制字符向量。

拓展一:上面代码中我们用到了num2str函数,它能将数字转换成字符的形式。下面我们通过几个简单的例子来了解它的基础用法:

第5章:5.2 字符数组(MATLAB入门课程),MATLAB教程新手入门篇(数学建模清风主讲),数学建模,matlab

前面几个例子都很容易理解,我们重点来看最后一个例子。

最后一个例子中,我们输入的是一个3行2列的数值矩阵,转换后得到了一个3×5 字符数组,即一个二维的字符矩阵。这个字符矩阵有3行、每一行有5个字符(第一列的数字后面跟有一定数量的空格,保证每一行的字符数量相同),而我们这一小节介绍的其他例子要么只有1行(行字符向量),要么只有1列(列字符向量)。在第三章我们介绍过:向量和矩阵都属于数组,只不过向量的维度是一维的,矩阵的维度是二维的。这里的字符向量和字符矩阵也是类似的,字符向量也可以看成字符矩阵的特例,我们下一小节会详细介绍字符矩阵。

另外,num2str函数支持使用格式化文本格式化文本是指具有某些特定显示形式的文本,例如文本的宽度、数值显示的精度、辅助说明的符号等。在下一章文本处理进阶篇中,我们会详细介绍相关的知识点。

拓展二:MATLAB中提供的dec2base函数可以将十进制(decimalism)整数转换为其 n 进制表示形式: dec2base(D, n) 返回十进制整数 D 的 n 进制表示形式。

第5章:5.2 字符数组(MATLAB入门课程),MATLAB教程新手入门篇(数学建模清风主讲),数学建模,matlab

5.2.3 字符矩阵

在上一小节中,我们介绍了字符向量,字符向量的行数或者列数为1。我们用的最多的就是行字符向量,它可以用来表示一段文本。如果我们想在同一个变量中表示多段文本,那么就可以使用字符矩阵。例如我们想保存两个单词:good和fine:

第5章:5.2 字符数组(MATLAB入门课程),MATLAB教程新手入门篇(数学建模清风主讲),数学建模,matlab

上面两种写法生成的字符矩阵c1和c2是完全一样的,大家可以使用strcmp函数验证c1和c2是否完全相同,执行strcmp(c1,c2)会返回逻辑值1。

左侧的写法和我们第三章介绍的数值矩阵一致:同行元素(这里是单个字符)之间用逗号或者空格分隔,行与行之间用分号或回车键分隔。这种写法可以清楚的看到各个位置上对应的字符元素,例如矩阵第1行第4列对应的字符为'd'。

右侧的写法通常更符合我们的需求,我们可以将矩阵的每一行看成一段文本。为什么这种写法可行呢?在第三章介绍的数值矩阵中,如果a和b两个矩阵的列数相同,我们可以使用[a; b]的语法在竖直方向纵向拼接a和b两个矩阵,而这里的'good'和'fine'是两个长度相同的行字符向量,因此使用['good'; 'fine']可以将它们拼接到一个字符矩阵中,这种拼接方法等价于使用cat或者vertcat函数,因此我们也可以写成vertcat('good','fine')或cat(1,'good','fine'),返回的结果也是一样的(复习:cat函数的第一个输入参数表示维度dim,dim等于1表示沿着行方向从上往下进行拼接,即纵向拼接)。

思考:如何在字符矩阵中表示good和great这两个单词?

第5章:5.2 字符数组(MATLAB入门课程),MATLAB教程新手入门篇(数学建模清风主讲),数学建模,matlab

MATLAB报错的原因是要串联的数组的维度不一致,这是因为字符向量'good'中有4个字符,而字符向量'great'中却有5个字符,因此不满足纵向拼接的条件。

那么应该如何解决呢?我们可以在good后面加上一个空格:

第5章:5.2 字符数组(MATLAB入门课程),MATLAB教程新手入门篇(数学建模清风主讲),数学建模,matlab

然而,当字符向量较多时,手动添加空格使得它们的字符数量相同效率太低,我们可以借助MATLAB的char函数自动拼接。(拓展:blanks(n)可以生成n个空格构成的字符向量)

我们之前介绍过,char函数可以将Unicode编码转换为对应的字符,下面介绍它的另一种用法:C = char(A1,A2,...,An) 将输入的数组 A1,A2,...,An(通常是字符向量、字符矩阵,也能支持数值向量、数值矩阵等)转换为单个字符数组,输入的A1,A2,...,An会变为 C 中的行。char 函数会自动在每一行最后使用空格填充来保证每行字符数量相同,如果任何输入数组是空字符数组,则 C 中相应的行是一行空格。(本段内容节选自MATLAB官方文档,为了帮助大家理解,我进行了一定的调整,帮助文档中的数组你可以理解为向量和矩阵)

例如,如果我们有几个不同长度的字符向量,例如 'good'、'' (空字符向量)、'great' 和 'perfect',并希望将它们组合成一个字符矩阵,我们可以使用以下命令:

第5章:5.2 字符数组(MATLAB入门课程),MATLAB教程新手入门篇(数学建模清风主讲),数学建模,matlab

下面再来看个例子,这个例子选自MATLAB官方文档:

第5章:5.2 字符数组(MATLAB入门课程),MATLAB教程新手入门篇(数学建模清风主讲),数学建模,matlab

A1是一个数值矩阵,A1中的数字可以看作Unicode编码:65至68分别对应'A''D'。当我们调用 char(A1, A2) 时,MATLAB会先将 A1 这个数值矩阵转换为对应的字符矩阵;然后,它将 A1 转换后的字符矩阵和 A2 字符向量组合成一个新的字符矩阵 C。在组合过程中,char 函数通过在较短的行末尾添加空格来确保所有行具有相同数量的字符。

另外,strvcat函数也可以用于纵向拼接字符数组,它和char函数的区别在于:拼接过程中,char函数不会忽略空字符向量'' (会使用空格填充这行),而strvcat会忽略空字符向量''

第5章:5.2 字符数组(MATLAB入门课程),MATLAB教程新手入门篇(数学建模清风主讲),数学建模,matlab

使用strvcat函数时,MATLAB可能会出现下面的警告:

第5章:5.2 字符数组(MATLAB入门课程),MATLAB教程新手入门篇(数学建模清风主讲),数学建模,matlab

这是因为strvcat 函数在非常早期的 MATLAB 版本中就引入了,但在后来的版本中,它被效率更高、通用性更好的char 函数取代了。strvcat 函数被认为是过时的(deprecated),因此MATLAB建议用户不要再使用这个函数,并且在未来的版本中可能会移除它。

下面我们来看一个例子:将十进制数1至100转换为二进制数,判断转换后的二进制数中有哪些是回文数?要求输出一个字符矩阵,矩阵每一行的字符向量的格式为:'十进制数:转换后的二进制数',可以在每一行字符向量的末尾加上空格保证长度相等。(提示:转换后的二进制数为字符向量类型,将这个字符向量反转顺序,如果和原来的一样就是回文数。例如'101'、'1001'都是二进制回文数)。

第5章:5.2 字符数组(MATLAB入门课程),MATLAB教程新手入门篇(数学建模清风主讲),数学建模,matlab

上面两段代码都能实现题目的要求(代码的关键差异已使用高亮标出)。在每次循环中,如果找到回文数,我们会将构造好的字符向量 tmp 添加到 res 中,左侧代码使用的是已经过时的strvcat函数,右侧代码使用的是char函数。由于拼接过程中,char函数不会忽略空字符向量'',因此右侧的代码中我们额外加入了一行代码:res(1,:) = []; 这行代码能够删除字符矩阵res中的第一行,它的第一行实际上都是空格(由空字符向量''自动添加空格形成),因此删除后不影响最终的结果。尽管使用char函数需要多加一行,但仍然建议大家使用 char 函数,这样能避免将来的兼容性问题。

细心的同学应该发现了,使用disp函数输出res时,MATLAB也会输出每行末尾的空格,尽管我们肉眼看不到它们,但将结果复制到其他位置时可能会引起不必要的麻烦。

下面我们写一段程序,它能依次输出字符矩阵cc的各行,并在输出时会自动删除各行末尾的空格。

第5章:5.2 字符数组(MATLAB入门课程),MATLAB教程新手入门篇(数学建模清风主讲),数学建模,matlab

思路:首先使用size(cc,1)得到字符矩阵cc的行数,然后对cc的每一行进行循环。在循环体中:使用cc(ii,:)获取每一行表示的字符向量,将其保存到变量c_ii中,接下来我们使用了deblank函数,这个函数可以删除c_ii末尾的空白字符,最后我们使用disp函数输出处理后的字符向量,这样输出的每一行都不会有末尾的空格。

拓展一:deblankstrtrim strip 函数

这三个函数用来删除字符向量开头或末尾的空白字符,它们的区别如下:

(1)deblank函数只能删除字符向量末尾的空白字符,不会删除开头的空白字符;strtrim函数会同时删除字符向量开头和末尾的空白字符;strip函数则提供了更多的选项,例如可以指定删除哪一侧的空白字符(左侧 'left'、右侧 'right'、双侧 'both'),甚至还能自己指定要删除的字符,即不一定是空白字符。(如何记住这三个函数?de前缀在英语中表示去除、离开的含义,blank翻译成中文是空白的意思,组合起来deblank就表示去除空白;str来自单词string,意思是字符串,trim中文表示修剪,因此strtrim可以记为修剪字符串;strip在英语中有剥[bāo]去、除去、脱掉等含义,这里你可以记为要剥去前后的指定字符。)

(2)MATLAB中可以识别空白字符有30种,其中最常见的有4种:键盘上空格键打出来的空格 (char(32),这里的32指的是对应的Unicode编码,下同)、键盘上的Tab键打出来的水平制表符char(9)、换行符char(10)以及回车符char(13)。其中,strtrim 和 strip函数能删除这30种空白字符中的25种,deblank函数的能力更强,它能多删除char(0)这个字符,因此能删除其中的26种,余下的4种称为实义空白字符,它们承载着额外的语义或格式要求,要想删除它们可以借助更为强大的正则表达式,在下一章文本处理进阶篇中,我们会介绍相关内容。这30种空白字符的详细列表可参考本章的附录2:MATLAB中的空白字符

下面我们通过几个例子来介绍它们的基础用法:

第5章:5.2 字符数组(MATLAB入门课程),MATLAB教程新手入门篇(数学建模清风主讲),数学建模,matlab

注意:字符向量中间出现的换行符(newline等价于char(10))和空格不会被删除!

事实上,deblank函数和strtrim 函数在MATLAB2006a版本之前就被推出了,而strip函数直到2016b版本才被推出(字符串数据类型也是2016b版本才推出的,本章后面会详细介绍)。因此,从上面的例子可以看出,strip函数使用更加灵活。此外,它还可以指定要删除的单个字符是什么,而不仅限于默认情况下的空白字符。

第5章:5.2 字符数组(MATLAB入门课程),MATLAB教程新手入门篇(数学建模清风主讲),数学建模,matlab

另外,在拓展一上面例题的代码中,我们在循环体中使用了tmp = deblank(c_ii); 这行语句来删除字符矩阵cc每一行最后的空格,然而deblank函数不仅会删除末尾的空格,还会删除其他空白字符。因此,如果你只想删除空格而保留其他空白字符,你可以将这一行代码改为:tmp = strip(c_ii,'right',' '); 这样就只会删除末尾的空格。进一步思考:如果原来字符向量的末尾也有空格,例如cc = char('no ', 'yes', 'good'),此时循环遍历cc的每行并使用strip函数删除末尾空格时,也会删除'no '后面的空格。要想避免这种情况,我们可以借助字符向量元胞数组或字符串数组,它们会将要表示的每段文本视为一个整体,所以和字符矩阵不同,它们不再要求保存的文本长度全都相同。包括deblankstrtrimstrip在内,绝大多数用于字符数组的函数也能用于字符向量元胞数组和字符串数组类型,本章后面会具体讲解这两种数据类型。

易错点:尽管strip函数能够指定在开头或者末尾删除的字符是什么,但只能指定单个字符,不能同时指定多个字符,例如:

第5章:5.2 字符数组(MATLAB入门课程),MATLAB教程新手入门篇(数学建模清风主讲),数学建模,matlab

要想实现这个功能,我们可以使用下一章要介绍的正则表达式,它更加灵活,功能也更为强大。

拓展二:strjust函数

strjust函数用于调整字符数组中文本的对齐方式,它通过调整每一行字符向量前后空格的位置来实现左对齐(left)、右对齐(right, 默认值)和居中对齐(center)三种格式。

第5章:5.2 字符数组(MATLAB入门课程),MATLAB教程新手入门篇(数学建模清风主讲),数学建模,matlab

从上面的例子可以看出,strjust函数能够灵活地调整字符数组的输出格式,因此它在生成格式化的文字报告时非常有用。例如:我们想格式化输出一个乘法口诀表:

第5章:5.2 字符数组(MATLAB入门课程),MATLAB教程新手入门篇(数学建模清风主讲),数学建模,matlab

c = '';  % 初始化一个空的字符数组保存整个结果
for i = 1:9   % 外循环,i表示每行的第二个乘数
    tmp = '';   % 初始化临时字符向量用于构建一整行
    for j = 1:i  % 内循环构建乘法表达式,并添加到临时字符向量中
        tmp = [tmp, num2str(j), '×', num2str(i), ... 
                     '=', num2str(i*j), '  '];  % 同一行的乘法等式之间用空格隔开
    end
    c = char(c,tmp);  % 将构建好的一整行添加到字符矩阵c中
end
c(1,:) = []; % c的第一行全是空格,需要删除掉
cc = strjust(c,'center');  % 居中对齐每行
disp(cc)

上述代码的思路如下:

(1)初始化字符矩阵:首先初始化一个空的字符矩阵c。这个矩阵将用于存储乘法表达式。(2)外层循环:外层循环(for i = 1:9)遍历乘法口诀表中的每一行,其中i表示每行的第二个乘数。(3)构建每行的字符向量内容:对于每一行,初始化一个空字符向量tmp用来临时存储当前行的所有乘法表达式。内层循环(for j = 1:i)遍历第一个乘数。在内循环中,构建形如j × i = i*j的乘法表达式,并将其作为字符向量拼接到tmp中。(4)将完整行添加到字符矩阵:完成内层循环后,tmp字符向量包含了当前行的完整乘法表达式。然后,这个字符向量被添加到字符矩阵c中。通过这种方式,c矩阵逐渐构建成完整的乘法口诀表。(5)处理字符矩阵的第一行:由于c初始化为空,所以第一次添加字符向量后,c的第一行实际上全为空格。因此,代码c(1,:) = []用来移除第一行。(6)对齐字符矩阵中的行:使用strjust函数对字符矩阵c中的每一行进行居中对齐。这样,每一行的乘法表达式在视觉上更加整齐和美观。(7)输出格式化的乘法口诀表:最后,使用disp函数输出居中对齐后的字符矩阵cc。


  点击下方的CSDN专栏阅读下一篇文章:

MATLAB入门课程专栏文章来源地址https://www.toymoban.com/news/detail-791831.html

到了这里,关于第5章:5.2 字符数组(MATLAB入门课程)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 第5章:5.3.2 字符向量元胞数组(MATLAB入门课程)

    ​讲解视频:可以在bilibili搜索《MATLAB教程新手入门篇——数学建模清风主讲》。​ MATLAB教程新手入门篇(数学建模清风主讲,适合零基础同学观看)_哔哩哔哩_bilibili 在上一节中,我们详细介绍了一般的元胞数组的使用方法。 本节将重点学习字符向量元胞数组,这是一种特

    2024年02月03日
    浏览(36)
  • 第5章:5.4.1 字符串数组的创建方法(MATLAB入门课程)

    讲解视频:可以在bilibili搜索《MATLAB教程新手入门篇——数学建模清风主讲》。​ MATLAB教程新手入门篇(数学建模清风主讲,适合零基础同学观看)_哔哩哔哩_bilibili 在本章5.2和5.3两个小节中,我们详细介绍了字符数组和元胞数组在文本数据处理中的应用。本节我们将重点学

    2024年02月01日
    浏览(48)
  • 第5章:5.4.4 字符串数组的配套函数 (MATLAB入门课程)

    ​讲解视频:可以在bilibili搜索《MATLAB教程新手入门篇——数学建模清风主讲》。​ MATLAB教程新手入门篇(数学建模清风主讲,适合零基础同学观看)_哔哩哔哩_bilibili MATLAB自2016b版本正式引入字符串类型起,其文本处理能力就得到了进一步提升。为了增强字符串数组的操控性

    2024年02月02日
    浏览(43)
  • 第5章:5.4.5 字符串数组的综合练习(MATLAB入门课程)

    ​讲解视频:可以在bilibili搜索《MATLAB教程新手入门篇——数学建模清风主讲》。​ MATLAB教程新手入门篇(数学建模清风主讲,适合零基础同学观看)_哔哩哔哩_bilibili 案例 1 : 下表左侧给出了四名同学在三次测试中的成绩数据,请对所有同学的测试成绩进行排名,并生成一

    2024年01月24日
    浏览(49)
  • 第5章:5.4.2 字符串数组的基本操作(MATLAB入门课程)

    ​讲解视频:可以在bilibili搜索《MATLAB教程新手入门篇——数学建模清风主讲》。​ MATLAB教程新手入门篇(数学建模清风主讲,适合零基础同学观看)_哔哩哔哩_bilibili 在文本数据预处理阶段,我们通常需要对字符串数组进行基本的操作。我们将从字符串数组的引用开始,逐

    2024年01月16日
    浏览(44)
  • HLS新手入门教程

    HLS是一种高级综合技术,它允许开发人员使用高级语言(如C、C++和SystemC)来描述数字电路的行为和功能,然后将其转换为硬件电路实现。这种转换过程是自动完成的,因此开发人员无需手动编写硬件描述语言(HDL)。 HLS的主要目的是简化FPGA设计流程,提高设计效率和设计质

    2024年02月02日
    浏览(57)
  • 【Matlab数理统计知识点合集】新手入门第十三天

    掌握随机数的产生 了解概率密度函数等函数的使用 掌握统计图表的绘制方法 随机数是专门的随机试验的结果。在统计学的不同技术中需要使用随机数,比如在从统计总体中抽取有代表性的样本的时候,或者在将实验动物分配到不同的试验组的过程中,或者在进行蒙特卡罗模

    2023年04月11日
    浏览(46)
  • 新手入门Jenkins自动化部署入门详细教程

    在实际开发中,我们经常要一边开发一边测试,当然这里说的测试并不是程序员对自己代码的单元测试,而是同组程序员将代码提交后,由测试人员测试; 或者前后端分离后,经常会修改接口,然后重新部署; 这些情况都会涉及到频繁的打包部署; 手动打包常规步骤: 1.提

    2024年02月13日
    浏览(53)
  • StarkNet新手入门教程:教你用bitget 钱包入门

    理想的Starknet (web3.bitget.com/zh/assets/starknet-wallet) 钱包取决于个人喜好,同时考虑安全性、用户友好性、帐户恢复选项和多通证支持等因素。尽管如此,无论您使用 Starknet (STRK) 的目的是持有还是交易,Bitget Wallet 都是您管理 STRK 以及其他以太坊和 Optimism 加密资产的理想钱包选择

    2024年03月12日
    浏览(52)
  • 【Jmeter】压力测试新手入门教程

    压力测试是每一个Web应用程序上线之前都需要做的一个测试,他可以帮助我们发现系统中的瓶颈问题,减少发布到生产环境后出问题的几率;预估系统的承载能力,使我们能根据其做出一些应对措施。所以压力测试是一个非常重要的步骤,下面我带大家来使用一款压力测试工

    2024年04月15日
    浏览(52)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包