我必须在Delphi 7中实现决策矩阵。 功能是
CalcNewStatus(actionCode:string; reportType:string; currentStatus:string):string;
在C#中,我会使用字典。我怎么能在Delphi 7中做到这一点?
答案 0 :(得分:10)
将输入字符规范化为基于零的序数值,事情变得更加容易。从几个类型声明开始:
type
TActionCode = (acA, acN);
TReportType = (rtI, rtF);
TStatus = (sP, sI, sF);
然后,您可以使用具有所有可能状态值的类型来定义数组。将sX
替换为每个位置中属于哪个状态值。
const
NextStatus: array[TActionCode, TReportType, TStatus] of TStatus = (
{acA} (// sP, sI, sF
{rtI} ( sX, sX, sX),
{rtF} ( sX, sX, sX)
),
{acN} (
{rtI} ( sX, sX, sX),
{rtF} ( sX, sX, sX)
)
);
然后你的功能就是这个:
function CalcNewStatus(const actionCode, reportType, currentStatus: string): string;
var
ac: TActionCode;
rt: TReportType;
s: TStatus;
const
StateChars: array[TState] of Char = ('P', 'I', 'F');
begin
Assert(actionCode <> ''); Assert(reportType <> ''); Assert(currentStatus <> '');
Assert(actionCode[1] in ['A', 'N']);
Assert(reportType[1] in ['I', 'F']);
Assert(currentStatus[1] in ['P', 'I', 'F']);
if actionCode[1] = 'A' then ac := acA else ac := acN;
if reportType[1] = 'I' then rt := rtI else rt := rtF;
if currentStatus[1] = 'P' then s := sP
else if currentStatus[1] = 'I' then s := sI
else s := sF;
Result := StateChars[NextStatus[ac, rt, s]];
end;
正如您所看到的,此代码的大部分用于在字符串和枚举类型之间进行转换。如果可以,请避免使用字符串。尽可能在程序中尽早切换到枚举类型,并且只在需要时才转换回字符串或字符。字符串可以具有任意长度,您实际上不应该处理它,并且字符串也可以具有超出您定义的范围的值。枚举不能,除非你做一些奇怪的事情。此外,编译器不会让你不小心使用期望TReportType的TState值,这将帮助你混淆你的I和F.
答案 1 :(得分:4)
首先在这种有限的情况下(2个ActionCodes,2个ReportTypes,3个状态)我绝对应该使用枚举类型而不是字符串。
对于决策矩阵......矩阵:
Type
TActionCode = (taA, taN);
TReprotType = (rtI, rtF);
TStatus = (stP, stI, stF);
const
NewStatus: array [TActionCode, TReportType, TStatus] of TStatus =
((((,,)),((,,))),(((,,)),((,,)))) // values of the new statuses here
答案 2 :(得分:0)
有一种解决方案使用一维数组。
unit XnResultStatusOverride;
interface
function XnCalcOverridenResultStatus(
actionCodeStr: string;
reportTypeStr: string;
currentStatusStr: string ): string;
implementation
uses SysUtils;
type
TActionCodes = ( ActionCodeA = 0, ActionCodeN = 1);
TReportTypes = (ReportTypeI = 0, ReportTypeF = 1);
TResultStatus = (ResultStatusP = 0, ResultStatusF = 1, ResultStatusI = 2);
const
DecisionMatrix: array[ 0 .. 15 ] of TResultStatus
=
(
ResultStatusF, // 0 A-I-P
ResultStatusF, // 1 A-I-F
ResultStatusF, // 2 A-I-I
ResultStatusF, // 3 N/A
ResultStatusP, // 4 A-F-P
ResultStatusP, // 5 A-F-F
ResultStatusF, // 6 A-F-I
ResultStatusF, // 7 N/A
ResultStatusF, // 8 N-I-P
ResultStatusF, // 9 N-I-F
ResultStatusP, // 10 N-I-I
ResultStatusF, // 11 N/A
ResultStatusF, // 12 N-F-P
ResultStatusI, // 13 N-F-F
ResultStatusF, // 14 N-F-I
ResultStatusF // 15 N/A
);
function ParseActionCodeString( value: string ): TActionCodes;
begin
if value = 'A' then
begin
result := ActionCodeA;
exit;
end;
if value = 'N' then
begin
result := ActionCodeN;
exit;
end;
raise Exception.Create('Invalid action code string' );
end;
function ParseReportTypeString( value: string ): TReportTypes;
begin
if value = 'I' then
begin
result := ReportTypeI;
exit;
end;
if value = 'F' then
begin
result := ReportTypeF;
exit;
end;
raise Exception.Create('Invalid report type string' );
end;
function ParseResultStatusString( value: string ): TResultStatus;
begin
if value = 'P' then
begin
result := ResultStatusP;
exit;
end;
if value = 'F' then
begin
result := ResultStatusF;
exit;
end;
if value = 'I' then
begin
result := ResultStatusI;
exit;
end;
raise Exception.Create('Invalid result status string' );
end;
function ResultStatusToString( value: TResultStatus ): string;
begin
if value = ResultStatusP then
begin
result := 'P';
exit;
end;
if value = ResultStatusF then
begin
result := 'F';
exit;
end;
if value = ResultStatusI then
begin
result := 'I';
exit;
end;
raise Exception.Create('Unknown TResultStatus enum member' );
end;
function XnCalcOverridenResultStatus(
actionCodeStr: string;
reportTypeStr: string;
currentStatusStr: string ): string;
var
actionCode: TActionCodes;
reportType: TReportTypes;
currentStatus:TResultStatus;
discriminant: integer;
newStatusInt: integer;
newStatus: TResultStatus;
begin
actionCode := ParseActionCodeString( actionCodeStr );
reportType := ParseReportTypeString( reportTypeStr );
currentStatus := ParseResultStatusString( currentStatusStr );
discriminant := integer(actionCode) * 8 + integer(reportType) * 4 + integer(currentStatus);
newStatusInt := DecisionMatrix[ discriminant ];
newStatus := TResultStatus( newStatusInt);
Result := ResultStatusToString( newStatus );
end;
end.