statsguyz
statsguyz

Reputation: 459

Replacing an index with two values in Matlab

I'm attempting to solve the following problem in Matlab:

The function replace_me is defined like this: function w = replace_me(v,a,b,c). The first input argument v is a vector, while a,b, and c are all scalars. The function replaces every element of v that is equal to a with b and c.

For example, the command

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

makes x equal to [1 4 5 3]. If c is omitted, it replaces occurrences of a with two copies of b. If b is also omitted, it replaces each a with two zeros."

Here is what I have so far:

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

The function replaces the values in v that are the same as a with b, but I'm not able to replace a with both b and c. Any help would be much appreciated.

Edit:

I have updated my code:

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

I receive the following error when I try 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 Error using replace_me (line 4) Not enough input arguments.

Upvotes: 0

Views: 1090

Answers (3)

dlavila
dlavila

Reputation: 1212

By counting the number of times that a appears in v you can calculate the size of your resulting vector length(v) + sum(v == a), then you can iterate over the vector and insert [b c] each time you find a match. You should increment the counter ii by two each time you insert new elements, otherwise if a=b you'll fill the remaining part of the vector with a's. It's not an efficient algorithm but it similar to your implementation

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

an efficient alternative (without vector resizing) could be:

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

Upvotes: 2

scmg
scmg

Reputation: 1894

Can be like this:

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

About the error "Error using replace_me (line 4) Not enough input arguments.", it is simply because you wrote the function with 4 input arguments while you called with only 3.

Upvotes: 1

Santhan Salai
Santhan Salai

Reputation: 3898

Here is an alternative: (Originally answered by @A. Donda)

This has the advantage of replacing multiple occurrences

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

Results:

>> 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

Upvotes: 2

Related Questions