Arrays 如何使用冒号运算符将半整数序列压缩为字符串表达式?(如何将列表转换为字符串)
Matlab中是否有内置函数,可将半整数序列压缩为带有冒号运算符的表达式 例如,Arrays 如何使用冒号运算符将半整数序列压缩为字符串表达式?(如何将列表转换为字符串),arrays,matlab,Arrays,Matlab,Matlab中是否有内置函数,可将半整数序列压缩为带有冒号运算符的表达式 例如,[1:4,5:5:7]给出 1, 2, 3, 4, 5, 5.5, 6, 6.5, 7 给定一个双数组,如[1,2,3,4,5,5.5,6,6.5,7],是否有一种方便的方法将其转换回[1:4,5:5:7]-或同样有效的[1:5,5.5:.5:7]-作为字符串?这里有一个简单的循环答案,假设x是你的向量,我选择1e-10作为浮点精度的差异阈值 x=[1, 2, 3, 4, 5, 5.5, 6, 6.5, 7]; d
[1:4,5:5:7]
给出
1, 2, 3, 4, 5, 5.5, 6, 6.5, 7
给定一个双数组,如
[1,2,3,4,5,5.5,6,6.5,7]
,是否有一种方便的方法将其转换回[1:4,5:5:7]
-或同样有效的[1:5,5.5:.5:7]
-作为字符串?这里有一个简单的循环答案,假设x
是你的向量,我选择1e-10
作为浮点精度的差异阈值
x=[1, 2, 3, 4, 5, 5.5, 6, 6.5, 7];
dx=diff(x);
a=num2str(x(1)); % first step, start the range
for n=2:numel(dx)
if abs(dx(n)-dx(n-1))>1e-10
if dx(n-1)~=1
a=[a ':' num2str(dx(n-1)) ':' num2str(x(n)), ' ', num2str(x(n+1)) ];
else
a=[a ':' num2str(x(n)), ' ', num2str(x(n+1)) ];
end
end
end
a=[a ':' num2str(dx(end)) ':' num2str(x(end))]; % last step, close the range
> a =
'1:5 5.5:0.5:7'
这里有一个解决方案
- 适当处理不构成范围的数字。例如,
将作为[1 3 5 9]
输出。类似地,'[1:2:5 9]'
将给出[1 3 5 9 11]
'[1:2:5 9 11]
- 省略指定步骤
。例如,1
将给出[9 3 4 5]
[9 3:5]
- 省略不必要的括号。例如,
将给出[8 6 4 2]
,'8:-2:2'
将给出5
'5'
- 允许空输入。所以
会给出[]
'[]'
x=[2 4.5 7 9.5 9 8 7 6 5 15 7.5 7 6.5 6 9 11];%示例输入
九月=“”;%定义分隔符;也可以是逗号
str='';%初始化输出
k=1;%第一个数字尚未处理
如果不为空且至少找到2个:范围(至少3个数字),则为k2%
ini=x(k);
ste=x(k+1)-x(k);
鳍=x(k+m-1);
如果ste~=1
str=[str num2str(ini)''num2str(ste)''num2str(fin)];
其他的
str=[str num2str(ini)''num2str(fin)];
结束
k=k+m;%m个数字已经处理
else%无范围:仅包括一个数字
str=[str num2str(x(k))];
k=k+1;%1号已处理
结束
str=[str sep];%添加分隔符
结束
str=条带(str,sep);%这将删除尾随空格/逗号(如果存在)。对于2016b之前的版本,请使用'strtrim'`
如果有(str==sep)| | isempty(str)
str=['['str']'];%括号是必需的
结束
示例/测试:
给出了[2 4.5 7 9.5 9 8 7 6 5 15 7.5 7 6.5 6 9 11]
'[2:2.5:9.5 9:-1:5 15 7.5:-0.5:6 9 11]
给出了[1.516-0.5-7-9-11]
'[1.516-0.5-7:-2-11]
给出了[4 2 0-2 5 12 19]
'[4:-2:-2 5:7:19]'
给出了[-20 2.5 5.5]
'[-20 2.5 5.5]'
给出了[2 3 4 10 7 8]
'[2:4 10 7 8]
给出了[6 4.5 3]
'6:-1.5:3'
给出了[3 4 5 6]
'3:6'
给出42
'42'
给出了[]
'[]'
m=find(diff([diff(x(k:end))inf]),1)+1;%可能为空
这将尝试从当前位置k
开始查找构成范围的数字的最大长度m
diff(x(k:end))
计算连续的差异,外部的diff
检测这些差异的变化。使用find(…,1)
计算的第一个此类更改指示不属于该范围的第一个数字。共有五种情况,第二种情况解释了为什么需要inf
:
- 3个或更多数字的正确范围,后跟至少一个不在该范围内的数字。例如,如果
是x(k:end)
我们有[3 5 7 15]
等于diff(x(k:end))
,[2 2 8]
等于diff([diff(x(k:end))inf])
,[0 6 inf]
给出查找(…,1)
,而2
是m
3
- 3个或更多数字的适当范围,以结束数组。例如,如果
是x(k:end)
我们有[3 5 7]
等于diff(x(k:end))
,[2]
等于diff([diff(x(k:end))inf])
,[0 inf]
给出查找(…,1)
,而2
是m
。这就是为什么需要3
;如果没有它,结果将是inf
,这将被m=[]
分支错误地解释为“无范围”if
- 没有合适的范围;还有两个以上的数字。例如,如果
是x(k:end)
我们有[3 6 7]
等于diff(x(k:end))
,[3 1]
等于diff([diff(x(k:end))inf])
,[-2 inf]
给出查找(…,1)
,而1
是m
。这意味着有两个数字的范围;但是它不是一个合适的范围,因此2
分支将忽略它,执行将继续执行if
部分else
- 没有合适的范围;只剩下两个号码了。例如,如果
是x(k:end)
我们有[36]
等于diff(x(k:end))
,3
等于diff([diff(x(k:end))inf])
,[inf]
给出查找(…,1)
,而1
是m
。同样,有两个数字的范围,但这不是一个合适的范围。请注意,如果没有包含的2
,我们将使用inf
而不是“正确的”m=[]
,但这也将有效地触发2
部分(其中未使用else
的实际值)m
- 没有合适的范围;只剩下1个数字,即当前数字结束数组。例如,如果x(k:end)只是
x = [2 4.5 7 9.5 9 8 7 6 5 15 7.5 7 6.5 6 9 11]; % example input sep = ' '; % define separator; it could also be comma str = ''; % initiallize output k = 1; % first number not processed yet while k<=numel(x) m = find(diff([diff(x(k:end)) inf]), 1) + 1; % may be empty if m>2 % if non-empty and at least 2: range found (at least 3 numbers) ini = x(k); ste = x(k+1)-x(k); fin = x(k+m-1); if ste~=1 str = [str num2str(ini) ':' num2str(ste) ':' num2str(fin)]; else str = [str num2str(ini) ':' num2str(fin)]; end k = k+m; % m numbers have been processed else % no range: include just one number str = [str num2str(x(k))]; k = k+1; % 1 number has been processed end str = [str sep]; % add separator end str = strip(str,sep); % this removes trailing space/comma, if it exists. For pre-2016b, use `strtrim` if any(str==sep) || isempty(str) str = ['[' str ']']; % brackets are required end