I have two variables (always 4 letter strings), Start and End. I need to generate other variables based on their values. *'s are wildcards (any capitalised letter).
The Start or End is classed as "Inner" if it is:
  • YF**
  • YG**
  • GRA*
  • EHEH
  • EHAM
The Start or End is classed as "Outer" if it is:
  • Y*** (except any inner values)
  • G*** (except any innter values)
  • BI**
  • BKPR
The Start or End is classed as "Far" if it is:
  • EGYP
  • Any other value
What's the most efficient way of doing this?

댓글 수: 5

Cedric
Cedric 2015년 8월 25일
What is the purpose? Can you provide an example of raw input and explain what you need to achieve?
Example...
Data.Car.Start = 'YLPR'
Data.Car.End = 'EGYP'
Thus, what should be produced is something like...
Data.Car.Start_Category = 'Outer'
Data.Car.End_Category = 'Far'
From these two variables names, I then need to be able to make an estimate for the amount of fuel required. E.g. in this case, 'Outer' and 'Far' would be a 'Heavy' amount of fuel. But if the categories came out as 'Inner' and 'Inner', then the fuel would be 'Light'.
Does this make sense?
Cedric
Cedric 2015년 8월 25일
편집: Cedric 2015년 8월 25일
Makes sense. I'm traveling; I'll answer later tonight if nobody answers.
Walter Roberson
Walter Roberson 2015년 8월 25일
편집: Walter Roberson 2015년 8월 25일
If Far is EGYP or "any other value", then why specialize EGYP, why not just say "any other value", or more concisely "any value" ? Perhaps the "any other value" refers to "any value not classified as Inner or Outer" ? Still no need to say EGYP specially.
J
J 2015년 8월 27일
Good point, whoops! Yeah, EGYP was supposed to be YFYP, hence I modified your code slightly.

댓글을 달려면 로그인하십시오.

 채택된 답변

Walter Roberson
Walter Roberson 2015년 8월 25일
편집: Walter Roberson 2015년 8월 26일

0 개 추천

var_is_Inner = ~cellfun(@isempty, regexp(Varlist, '^Y[FG]|^GRA|EHEH|EHAM'));
var_is_Outer = ~cellfun(@isempty, regexp(Varlist, '^Y[^FG]|^G[^R]|^GR[^A]|^BI|BKPR'));
var_is_Far = ~(var_is_Inner | var_is_Outer);
var_category = cell(length(Varlist), 1);
var_category(var_is_Inner) = {'Inner'};
var_category(var_is_Outer) = {'Outer'};
var_category(var_is_Far) = {'Far'};
Varlist should be a cell array of strings for this code, even if there is only one. Or if there is only one then replace length(Varlist) with 1 and Varlist could then be a single string.

댓글 수: 2

Repaired. I should not have been asking for 'match'
J
J 2015년 8월 27일
Perfect! Only modified it slightly for an additional variable I had forgotten.

댓글을 달려면 로그인하십시오.

추가 답변 (1개)

Cedric
Cedric 2015년 8월 26일
편집: Cedric 2015년 8월 27일

1 개 추천

Here is the beginning of an answer while I am waiting for my plane.
"Most efficient" can have multiple meanings here. Does it mean that you want the code to be fast, or that you want the code to be concise, or that you want the code to scale well to larger similar problems?
Let's say that if you want the code to be fast, you need to find a way to reformulate your problem so it can be vectorized (we can talk about this a little later). If you want it to be fast but you are still planning on looping over cases, and you can afford writing a very specific solution, you can solve the problem with a few nested IF statements, e.g.
function category = getCategory( bnd )
if bnd(1) == 'Y'
if bnd(2) == 'F' || bnd(2) == 'G'
category = 1 ;
else
category = 2 ;
end
elseif bnd(1) == 'G'
if all( bnd(2:3) == 'RA' )
category = 1 ;
else
category = 2 ;
end % EDITED
elseif all( bnd(1:2) == 'BI' ) || strcmp( bnd, 'BKPR' )
category = 2 ;
elseif any( strcmp( bnd, {'EHEH','EHAM'} ))
category = 1 ;
else
category = 3 ;
end
end
Using this, we get a category ID for both boundaries as follows
catId_start = getCategory( Data.Car.Start ) ;
catId_end = getCategory( Data.Car.End ) ;
which is easier and faster to test than strings like 'far' for example.
If you want it to be more versatile and/or more scalable, you can use pattern matching with REGEXP for example.
PS: I don't have a MATLAB for testing at the moment, but it shows the concept.

댓글 수: 4

J
J 2015년 8월 27일
This is a great answer, I wish I could choose two accepted answers! I think I want to stay away from as many for loops as possible, my code is going to be very long (this is only part of it) and needs to run efficiently!
Cedric
Cedric 2015년 8월 27일
편집: Cedric 2015년 8월 27일
The REGEXP based version will be slower, but more versatile. This version is more specific and more efficient in term of speed precisely because it avoids pattern matching and performs only a few character comparisons.
J
J 2015년 8월 27일
Hmmmm, that's a good point. Okay, I guess if the destination categories were changing frequently it might be a good idea to use the REGEXP version. I'll reimplement your solution and compare them. Thanks again!!
Cedric
Cedric 2015년 8월 27일
편집: Cedric 2015년 8월 27일
Now I would recommend to think well about what you really need to optimize, especially if the code is large and if other people will have to understand and update it later.
To illustrate my point, I would say that in most of my developments efficiency in terms of speed is only the 3rd or 4th priority. The top priorities are to make the code clear, stable, well documented, easily maintainable, etc. Only at a few strategic places, do I really favor speed. At these places, I compensate for the lack of clarity or for the complexity of the code with an extensive help, illustrative examples, etc.

댓글을 달려면 로그인하십시오.

카테고리

도움말 센터File Exchange에서 Loops and Conditional Statements에 대해 자세히 알아보기

질문:

J
J
2015년 8월 25일

편집:

2015년 8월 27일

Community Treasure Hunt

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

Start Hunting!

Translated by