Matlab 中是否有内置函数将半整数序列压缩为带有冒号运算符的表达式?
例如,[1:4,5:.5:7]给
1, 2, 3, 4, 5, 5.5, 6, 6.5, 7
Run Code Online (Sandbox Code Playgroud)
给定一个 double 数组,例如[1, 2, 3, 4, 5, 5.5, 6, 6.5, 7],是否有一种方便的方法将其转换回[1:4,5:.5:7](或同样有效)[1:5,5.5:.5:7]作为字符串?
这是一个解决方案
\n\n[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]; % example input\nsep = \' \'; % define separator; it could also be comma\nstr = \'\'; % initiallize output\nk = 1; % first number not processed yet\nwhile k<=numel(x)\n m = find(diff([diff(x(k:end)) inf]), 1) + 1; % may be empty\n if m>2 % if non-empty and at least 2: range found (at least 3 numbers)\n ini = x(k);\n ste = x(k+1)-x(k);\n fin = x(k+m-1);\n if ste~=1\n str = [str num2str(ini) \':\' num2str(ste) \':\' num2str(fin)];\n else\n str = [str num2str(ini) \':\' num2str(fin)];\n end\n k = k+m; % m numbers have been processed\n else % no range: include just one number\n str = [str num2str(x(k))];\n k = k+1; % 1 number has been processed\n end\n str = [str sep]; % add separator\nend\nstr = strip(str,sep); % this removes trailing space/comma, if it exists. For pre-2016b, use `strtrim`\nif any(str==sep) || isempty(str)\n str = [\'[\' str \']\']; % brackets are required\nend\nRun Code Online (Sandbox Code Playgroud)\n\n示例/测试:
\n\n[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.5 16 -0.5 -7 -9 -11]给出\'[1.5 16 -0.5 -7:-2:-11]\'[4 2 0 -2 5 12 19]给出\'[4:-2:-2 5:7:19]\'[-2 0 2.5 5.5]给出\'[-2 0 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\'[]给出\'[]\'该代码由一个循环组成,该循环从当前位置开始搜索最大长度范围,然后向前移动。最棘手的部分是线条
\n\n\n\n\n\n
m = find(diff([diff(x(k:end)) inf]), 1) + 1; % may be empty
m这试图找到从当前位置开始形成一个范围的数字的最大长度k。diff(x(k:end))计算连续的差异,外部diff检测这些差异的变化。第一个此类更改(用 计算)find(..., 1)表示第一个不属于该范围的数字。有五种情况,其中第二种解释了为什么inf需要:
x(k:end)is[3 5 7 15]我们有diff(x(k:end))等于[2 2 8]、diff([diff(x(k:end)) inf])等于[0 6 inf]、find(..., 1)给出2和mis 3。x(k:end)is[3 5 7]我们有diff(x(k:end))等于[2 2]、diff([diff(x(k:end)) inf])等于[0 inf]、find(..., 1)给出2和mis 3。这就是为什么inf需要;如果没有它,结果将为m=[],分支将错误地将其解释为“无范围” if。x(k:end)is[3 6 7]我们有diff(x(k:end))等于[3 1]、diff([diff(x(k:end)) inf])等于[-2 inf]、find(..., 1)给出1和mis 2。这意味着存在两个数字的范围;但这不是一个合适的范围,因此if分支将忽略它,并继续执行该else部分。x(k:end)is[3 6]我们有diff(x(k:end))等于3、diff([diff(x(k:end)) inf])等于[inf]、find(..., 1)给出1和mis 2。同样,两个数字有一个范围,但这不是一个适当的范围。请注意,如果没有包含,inf我们将m=[]代替“正确” 2,但这也可以有效触发该部分(其中未使用 的else实际值)。mif x(k:end)等于、等于、给出、并且是。尽管“应该”是,但对于触发该部分同样有效。3diff(x(k:end))[]diff([diff(x(k:end)) inf])[]find(..., 1)[]m[]m1[]else请注意,由于输入包含整数或半整数,因此不存在浮点精度问题,因为这些数字精确表示到 \xc2\xb1 2^52。