I think this is a naive query. Yet, let me pose it:
If '(' '2' '*' '3' ')' are elements of a string vector S, then what function f results in the following:
f(S) = (2*3) = 6
str2num for '2' and '3' is not an option, since they can occur anywhere in S, and there is no apriori information as to where they will occur.
For the same reasons, keeping the bracket structure intact is also important, even though it seems that we can do away with the brackets in this example.

 Akzeptierte Antwort

Walter Roberson
Walter Roberson am 26 Nov. 2020

0 Stimmen

S = '(2*3)+Z*14*(3*5)+(7)*(9)-(11)*13'
S = '(2*3)+Z*14*(3*5)+(7)*(9)-(11)*13'
while true
newS = regexprep(S, {'\((\d+)\)\*\((\d+)\)', '\((\d+)\)\*(\d+)', '(\d+)\*\((\d+)\)', '(\d+)\*(\d+)'}, {'${string(times(str2double($1),str2double($2)))}'})
if strcmp(newS, S); break; end
S = newS;
end
newS = '(6)+Z*14*(15)+63-143'
newS = '(6)+Z*210+63-143'
newS = '(6)+Z*210+63-143'
Note that the logic gets more complex if you have operators that are higher priority, such as ^ . For example '2*3^Z' should not have the 2*3 multiplied out.
Also, you could reasonably argue that I did not preserve brackets in some of the cases such as (11)*13 -- it would not be unreasonable to claim that the result of that should be (143) instead of 143 . You could take care of those cases by having four different replacement strings instead of the single replacement I have there.
I did try to unify all of the cases into one case, but stripping off the brackets without using nested regexp or using an auxillary function would have been a bit messy. It would probably be cleanest to use some auxillary functions like
{'${s_times($1,$2)}'}
with s_times responsible for stripping off brackets and converting to numeric and doing the multiplication and converting the result to character. It would probably be a good idea to use something like that, and then the cases could probably be reduced to a single case.

5 Kommentare

v k
v k am 26 Nov. 2020
I have 2 queries :
1). How can I accept both the answers? Given the time and expertise invested by the experts, it will be very rude on my part to selectively tick one, given the fact that both answers work nicely.
2). Suppose there is an 'equal to' sign in between. Then how to output 'LHS=RHS' or 'LHS is not equal to RHS' depending upon the LHS and RHS evals? Again, the '=' sign can occur anywhere. Example,
S1=["(" "2" "*" "3" ")" "=" "4"];
will have the output 'LHS is not equal to RHS'.
And
S2=["(" "2" "=" "2" "^" "1" ")"];
will have the output 'LHS is equal to RHS'.
Thank you and Happy Thanksgiving Thursday.
S2=["(" "2" "=" "2" "^" "1" ")"];
That should generate an error or non-acceptance I would say. The left of the equals sign is open-bracket followed by a number, and the right is an expression followed by close bracket. The two sides cannot be equal because the brackets are unbalanced on each side.
If you want the second to somehow succeed then you have to start treating the = as a comparison operator that can appear in the middle of the expression and evaluates to something, in which case the second string becomes just a bracketed expression, and the final determination of success is according to whether the expression output is compatible with truth. You probably do not want to have to deal with mixed data types so you probably want truth and falsehood to be represented by integers. You could adopt the convention used in several programming languages that true is anything non-zero and then it generally becomes useful to return 0 for false and 1 for true and to accept any non-zero as true. so for example the expression 1+1 would generate the success message but 1-1 would generate the failure message.
Bythe way look in the File Exchange for Shunting Yard
Rik
Rik am 26 Nov. 2020
Regarding your first question: you can't. The polite thing to do is to accept one and give the other a vote.
v k
v k am 26 Nov. 2020
Shunting Yard --- How did you find this??!! Thank you for directing to that algorithm! Come to think of it - there has to have been an algorithm for the strings to function as operators. They won't become operators until such an algorithm is in play.
Also, thanks for the logical true and false - that works.
Walter Roberson
Walter Roberson am 26 Nov. 2020
Shunting Yard got mentioned by other people a couple of times recently... they found it, not me :)

Melden Sie sich an, um zu kommentieren.

Weitere Antworten (1)

Matt J
Matt J am 26 Nov. 2020
Bearbeitet: Matt J am 26 Nov. 2020

2 Stimmen

I can't tell if you really intend S to be a string vector because that dpesn't agree with the example you posted. If I assume it is what you meant, though, then you could do,
S=["(" "2" "*" "3" ")"];
whos S
Name Size Bytes Class Attributes S 1x5 366 string
eval(cell2mat(cellstr(S)))
ans = 6

1 Kommentar

Walter Roberson
Walter Roberson am 26 Nov. 2020
If this is user input then evalc is dangerous as the user could have coded a call to delete files

Melden Sie sich an, um zu kommentieren.

Kategorien

Tags

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by