【问题标题】:Replacing an index with two values in Matlab在 Matlab 中用两个值替换索引
【发布时间】:2015-05-12 01:07:07
【问题描述】:

我正在尝试在 Matlab 中解决以下问题:

函数replace_me 定义如下:function w = replace_me(v,a,b,c)。第一个输入参数v 是一个向量,而abc 都是标量。该函数将v 中等于a 的每个元素替换为bc

例如命令

x = replace_me([1 2 3],2,4,5);

使x 等于[1 4 5 3]。如果省略了c,它将用b 的两个副本替换出现的a。如果b 也被省略,它会将每个a 替换为两个零。”

这是我目前所拥有的:

function [result] = replace_me(v,a,b,c)
    result = v;
    for ii = 1:length(v)
        if result(ii) == a
            result(ii) = b;
            result(ii +1) = c;
        end
    end
end

该函数将v 中与a 相同的值替换为b,但我无法将a 替换为bc。任何帮助将非常感激。

编辑:

我已经更新了我的代码:

function [v] = replace_me(v,a,b,c)
for ii = 1:length(v)
  if v(ii) == a
    v = horzcat(v(1:ii-1), [b c], v(ii+1:end));
    fprintf('%d',v);
  elseif v(ii) == a && length(varargin) == 3
    v = horzcat(v(1:ii-1), [b b], v(ii+1:end));
    fprintf('%d',v);
  elseif v(ii) == a && length(varargin) == 2
    v = horzcat(v(1:ii-1), [0 0], v(ii+1:end));
    fprintf('%d',v);
  else

      fprintf('%d',v);
  end

end
end

我在尝试 replace_me([1 2 3 4 5 6 7 8 9 10], 2, 2) 时收到以下错误:

replace_me([1 2 3 4 5 6 7 8 9 10],2,2) 12345678910 使用 replace_me 时出错(第 4 行) 输入参数不足。

【问题讨论】:

  • 你的算法错了,请试试我的,你没有考虑到向量在遍历它时会增加他的大小。除此之外,如果你想使用可变数量的参数,你应该使用varargin,看看documentation。如果你喜欢我的回答,请采纳。

标签: matlab for-loop indexing


【解决方案1】:

这是另一种选择:(最初由@A. Donda 提供answered

这样做的好处是替换多次出现

function [result] = replace_me(v,a,b,c)
    if nargin == 3
        c = b;
    end
    if nargin == 2
        c = 0;
        b = 0;
    end
    result = v;
    equ = result == a;
    result = num2cell(result);
    result(equ) = {[b c]};
    result = [result{:}];
end

结果:

>> x = replace_me([1 2 3],2,4,5)

x =

 1     4     5     3

>> x = replace_me([1 2 3],2)

x =

 1     0     0     3

>> x = replace_me([1 2 3],2,4)

x =

 1     4     4     3

>> x = replace_me([1 2 3 2], 2, 4, 5)

x =

 1     4     5     3     4     5

【讨论】:

  • 只是好奇我将如何处理被省略的输入值。我仍然需要处理这部分问题:“如果省略 c,则将出现的 a 替换为 b 的两个副本。如果也省略 b,则将每个 a 替换为两个零。”有没有办法使用 nargin 关键字来处理输入中 b 的缺失值和/或 c 的缺失值?
【解决方案2】:

通过计算av 中出现的次数,您可以计算得到的向量length(v) + sum(v == a) 的大小,然后您可以遍历向量并在每次找到匹配项时插入[b c]。您应该在每次插入新元素时将计数器 ii 增加 2,否则如果 a=b 您将使用 a 填充向量的剩余部分。这不是一个有效的算法,但它类似于你的实现

result = v;
rep = sum(result == a);

if rep == 0
  return
end

for ii = 1:(length(result) + rep)
  if result(ii) == a
    result = [result(1:ii-1), [b c], result(ii+1:end)];
    ii = ii + 2;
  end
end

一种有效的替代方法(无需调整矢量大小)可能是:

rep = sum(v == a);

if rep == 0
    result = v;
    return;
end

result = zeros(1, length(v) + rep);

idx = 1;
for ii = 1:length(v)
    if v(ii) == a
       result(idx) = b;
       result(idx+1) = c;
       idx = idx + 2;
    else 
       result(idx) = a;
       idx = idx + 1;
    end
end

【讨论】:

  • 您能否为您对 OP 的回答添加一些解释?
  • 我收到一条警告消息:idx 可能被不兼容地使用或重新定义。
  • 我使用了+=运算符,在matlab中无效,答案已编辑
【解决方案3】:

可以是这样的:

function result = replace_me(v, a, b, c)
  result = [];
  for ii = 1:length(v)
    if v(ii) == a
      result = [result, b, c];
    else
      result = [result, v(ii)];
    end
  end
end

关于错误“Error using replace_me (line 4) Not enough input arguments.”,这仅仅是因为你用4个输入参数编写了函数,而你只用3个输入参数调用。

【讨论】:

  • 你的代码错了,用v = [3 4 1 2 3 1]a = 1b = 2c = 2测试,你没有考虑到每次找到一个向量都会增加他的大小新匹配
  • 我想在每次找到匹配项时增加向量大小。由于 a 被 b 和 c 替换,因此向量大小将增加 1,例如 a 等于 v 的索引值。
  • 抱歉,我以为您只需要检查 1 个索引。我也编辑了代码。
  • 如何在不知道第一手结果长度的情况下预分配结果?
猜你喜欢
  • 2015-07-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-26
  • 1970-01-01
  • 2021-05-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多