arrays - 如何使用冒号运算符将半整数序列压缩为字符串表达式? (如何将列表转换为字符串)

标签 arrays matlab

Matlab 中是否有内置函数将半整数序列压缩为带有冒号运算符的表达式?

例如,[1:4,5:.5:7]

1, 2, 3, 4, 5, 5.5, 6, 6.5, 7

给定一个 double 数组,例如 [1, 2, 3, 4, 5, 5.5, 6, 6.5, 7] ,是否有一种方便的方法将其转换回 [1:4,5:.5:7] — 或同样有效,[1:5,5.5:.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]; % 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
    

    示例/测试:
  • [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'
  • []'[]'

  • 该代码由一个循环组成,该循环从当前位置开始搜索最大长度范围,然后向前移动。 最棘手的部分 是线

    m = find(diff([diff(x(k:end)) inf]), 1) + 1; % may be empty



    这试图找到最大长度 m形成一个范围的数字,从当前位置开始 k . 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] , find(..., 1)2 , 和 m3 .
  • 3 个或更多数字的适当范围,结束数组。例如,如果 x(k:end)[3 5 7]我们有 diff(x(k:end))等于 [2 2] , diff([diff(x(k:end)) inf])等于 [0 inf] , find(..., 1)2 , 和 m3 .这就是为什么inf需要;没有它,结果将是 m=[] ,这会被 if 错误地解释为“无范围”分支。
  • 没有合适的范围;剩余的号码超过 2 个。例如,如果 x(k:end)[3 6 7]我们有 diff(x(k:end))等于 [3 1] , diff([diff(x(k:end)) inf])等于 [-2 inf] , find(..., 1)1 , 和 m2 .这意味着有两个数字的范围;但它不是一个合适的范围,所以 if分支将忽略它,并继续执行 else部分。
  • 没有合适的范围;只剩下2个号码了。例如,如果 x(k:end)[3 6]我们有 diff(x(k:end))等于 3 , diff([diff(x(k:end)) inf])等于 [inf] , find(..., 1)1 , 和 m2 .同样,有两个数字的范围,但它不是一个合适的范围。请注意,没有包含 inf我们会有 m=[]而不是“正确的”2 ,但这也可以触发 else部分(其中不使用 m 的实际值)。
  • 没有合适的范围;只剩下 1 个数字,即当前数字结束数组。例如,if x(k:end)只是 3我们有 diff(x(k:end))等于 [] , diff([diff(x(k:end)) inf])等于 [] , find(..., 1)[] , 和 m[] .虽然 m “应该”是1 , []与触发 else 一样有效部分。

  • 注意,由于输入包含整数或半整数,所以有没有浮点精度问题 ,因为这些数字精确地表示为 ± 2^52 .

    关于arrays - 如何使用冒号运算符将半整数序列压缩为字符串表达式? (如何将列表转换为字符串),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58226737/

    相关文章:

    python - 如何将向量分离为基向量?

    php - 分解长字符串 - PHP

    Java 将 BufferedOutputStream 存储在数组中

    c - 用 0 填充 C 数组

    arrays - MATLAB:fscanf - 保留柱状结构

    matlab - 如何在 MATLAB 中加速多向量卷积?

    javascript - 使用 charAt 遍历数组以获取 javascript 中每个值的首字母

    matlab - 使用combvec获得完整矩阵(matlab)

    matlab - 为什么 100*0.07 等于 6.9999....?

    matlab - 是否可以通过继承来扩展图形对象的功能?