This recursive function takes two input arguments, The first (A) is a number and the second (n) is a digit, checks the occurrence of n in A. (A is updated by removing its last digit in each recursion). it seems like the recursion is infinite and the base case (A == 0) is not valid but why.
function counts = countn(A,n)
if (A == 0)
counts= 0;
end
if (n == mod(A,10))
disp(A);
disp(floor(A/10));
disp(mod(A,10));
B = floor(A/10);
counts = countn(B,n) + 1;
else
B = floor(A/10);
countn(B,n);
end
end
It does not stop because it first evaluates the first if statement if( A == 0) and afterward the if (n == mod(A,10)) where it jumps in the else branch and recursively calls the function again. So it does not stop in the first if statement as you likely expected it to do.
something like this should work:
function counts = countn(A,n)
if (A == 0)
counts = 0;
elseif (n == mod(A,10))
disp(A);
disp(floor(A/10));
disp(mod(A,10));
B = floor(A/10);
counts = countn(B,n) + 1;
else
B = floor(A/10);
counts = countn(B,n);
end
end
You also have to update count counts variable in the else branch to avoid the uninitialized use of variables.
Have a look at how to use a debugger manual. Simply click on the line number inside your function and run your code. Use the F10 and F11 keys to evaluate your code line by line. This helps you understand what your program does.
Related
Is it possible to go from within a case in switch to another case based on a condition?
Here is an example:
flag_1 = 'a'
flag_2 = 1;
x = 0;
switch flag_1
case 'a'
if flag_2 == 1
% go to otherwise
else
x = 1;
otherwise
x = 2;
end
If flag_2 == 1 I want to go from case 'a' to otherwise. Is it possible?
No, this is not possible. There’s no “goto” statement in MATLAB.
One solution is to put the code for the “otherwise” branch into a function, then call that function if your condition is met:
flag_1 = 'a'
flag_2 = 1;
x = 0;
switch flag_1
case 'a'
if flag_2 == 1
x = otherwise_case;
else
x = 1;
otherwise
x = otherwise_case;
end
function x=otherwise_case
% assuming this is more complex of course
x = 2;
end
Similar to Cris' answer, you could set a flag, and have a simpler conditional based on that flag after the switch:
flag_1 = 'a'
flag_2 = 1;
x = 0;
otherwise_case = false;
switch flag_1
case 'a'
if flag_2 == 1
otherwise_case = true;
else
x = 1;
otherwise
otherwise_case = true;
end
if otherwise_case
% assuming this is more complex of course
x = 2;
end
This is simpler if, for instance, the otherwise_case function would have lots of required inputs which are already available in the current scope when using the flag approach instead.
For completeness, I'm going to mention the "early bailout" approach. Basically, you put your switch inside a try/catch:
try
switch flag_1
case 'a'
if flag_2 == 1
throw(...)
else
x = 1;
otherwise
throw(...)
end
catch ME
% otherwise case, if exception is as expected
end
I should note that the other answers are likely more suitable for the present problem. This approach is useful when you have multiple loops or internal functions within the case, and you want to quickly exit all of them and reach the "otherwise". Note that when doing this you should check within the catch clause that the exception is as you expect (example), to avoid legitimate issues that might arise in the cases' logic.
I'm quite new in MATLAB. I have to write a function that counts the number of a certain character in a text file. 2 input arguments are requested: fname (char vector of the filename) and character (the char it counts in the file).
Output argument: the number of characters found. If the file is not found or character is not a valid char, the function return -1.
I wrote a function which passed correctly two of the 4 tests. The two wrong ones are:
==> 1) Test with all visible characters
Explanation: Variable charnum has an incorrect value. When testing with '#' your solution returned -1 which is incorrect. (0)
==> 2) Non existent file
For number 2), no explanation provided.
This is my code:
function charnum = char_counter(fname, character)
A = fileread(fname);
char_1 = strfind(A, character);
charnum = numel(char_1);
if isfile(fname) == 0 %doesn't work...
charnum = -1;
elseif exist(fname) == 0
charnum = -1;
elseif charnum == 0
charnum = -1;
elseif ischar(character) == 0
charnum = -1;
fclose(fid);
end
Thank you all for your suggestions and advice.
I understand, for the 1) that I probably should add an instruction to take into account all the characters but I can't find a satisfying way that works. Because when I test for the character '#', it works correctly on my MATLAB:
When I test the function with the visible character '#' the answer is correct.
For 2) I don't understand why my 4th line doesn't work correctly.
I already check various options found on the Internet but so far it did not fix the problem.
To answer your questions:
1) A = fileread(fname) will throw an error before you can get to the if statements, so you will have to restructure your code to take that into account.
However, you can use the isequal function to compare two things for an if statement. isfile returns a 0 if the file is not found, so you can compare that to 0.
if isequal(isfile(fname),0)
charnum = -1;
2) The function ischar returns 0 if the input is not a character array. This will return 0 for string arrays, so make 100% sure your input is a character array. Use char to do this:
elseif isequal(ischar(char(character)),0)
charnum = -1;
Here is what your function could look like:
function charnum = char_counter(fname, character)
if isequal(isfile(fname),0)
charnum = -1;
else
A = fileread(fname);
char_1 = strfind(A, character);
charnum = numel(char_1);
if isequal(exist(fname),0)
charnum = -1;
elseif isequal(charnum,0)
charnum = -1;
elseif isequal(ischar(char(character)),0)
charnum = -1;
end
fclose(fid);
end
end
I have created a matrix with row 1 full of strings and 4 other rows with numbers. They are created in a handle class with the object "Projekter".
So in the object "Projekter" row 1, the first value is blank, but the second value is 'Ole'. So I know that 'Ole' is in (1,2). x is the name/string I want to search for, which in this case is 'Ole'.
As you see below it should search row 1 from column 2 untill the last name/string and if i = 'Ole', it should bring me the value 2 because " i " should be equal 2.
A is just a controller if the function works, but at this point it doesn't.
The error it gives is "Undefined function 'eq' for input arguments of type 'cell'."
How do I fix this so it return the " i " value when the statement is correct?
Thank you in advance!
function number(obj,x)
A = [];
for i = 2:size(obj.Projekter,2)
if obj.Projekter(1,i)==x
A = A + 1;
end
end
disp(A)
end
Maybe you have to index the cell content:
your_cell = {'a_string'};
your_string = your_cell{1};
function [returnValue] = number(obj,x)
for i = 2:size(obj.Projekter,2)
if obj.Projekter{1,i}==x
returnValue = i;
return;
end
end
end
Note the change from obj.Projekter(1,i)==x to obj.Projekter{1,i}==x (use curly braces instead of parens). I have then specified that returnValue will hold the value that should be returned by doing function [returnValue] = number(obj,x). We then set returnValue equal to i and return from the function when the condition of the if statement is true.
As suggested in the comments, it is probably better to do:
function [returnValue] = number(obj, x)
returnValue = find(strcmp(x, obj.Projekter) == 1);
strcmp(x, obj.Projektor) will give you an array the length of obj.Projekter with 1's wherever the strings match, and 0's where they don't, you can then find the indices that are set to 1. This has the added benefit of
not using a loop so it's faster
Giving you every occurrence of a match, not just the first one.
I have written a function which takes in an integer (int8) as one of the inputs (called iscool). The function runs a while loop and I insert an if-check inside it to break out of the loop. The if-check checks the value of the iscool variable as well and sets the value of imarch to 0 to get out of loop. So basically, the code is something like this.
% Code_snippet
while (imarch == 1)
<some procedures not modifying iscool>
if ((iscool == 0) && (<other condition 1>) && (<other condition 2>))
imarch = 0;
elseif ((iscool == 1) && (<other condition 3>) && (<other condition 4>))
imarch = 0;
end
disp (strcat('Cooling index is: ',num2str(iscool)));
end
The output of the disp command in the first while-loop execution is 0 (which is the input), but it changes to 1 in the subsequent iteration and stays so after that. I have tried removing the if-elseif-end check and the value of iscool stays intact in that case, but I need to have the check in order to be able to get out of the loop. Any sort of help, particularly an insight into why the value might be changing would be great help. Thanks.
Here's my code:
N = 1:999;
for i = N
if rem(i,3) == 0 || rem(i,5) == 0
v(i,1) = i
end
end
Te problem is that I get an Array with some zeros in, but I just want an an arraywith the values comforming to my conditions.
How can I fix it?
Thank you!
I think the OP is looking for a result like:
v= N( (rem(N,3)==0) | (rem(N,5)==0) );
though without looping... :-)
I'm assuming that you're using a loop for a reason, and am not removing it from my solution. However, loops should be avoided where possible.
If I understand your question, you're trying to store only those values of i which correspond to a true conditional evaluation. You're problem is that you're using i as your index value inside the assignment statement. Use the end index keyword. Like so:
N = 1:999;
v = [];
for i = N
if rem(i,3) == 0 || rem(i,5) == 0
v(end+1) = i
end
end