집합에서 가장 높은 (또는 가장 낮은) 값을 추출 할 수있는 방법이 있습니까? I는 "이 바이트의 집합"다음 경우 예를 들어, :델파이 세트에서 가장 높은 값을 얻는 방법?
[0, 1, 2, 4, 5, 28, 199]
내가 그 실행하고 다시 199 결과를 얻을 수있는 기능이있다?
EDIT : for..in 루프와 관련된 명백한 강력한 해결책이 있습니다. 가능하다면 그보다 나은 방법을 찾고 싶습니다.
집합에서 가장 높은 (또는 가장 낮은) 값을 추출 할 수있는 방법이 있습니까? I는 "이 바이트의 집합"다음 경우 예를 들어, :델파이 세트에서 가장 높은 값을 얻는 방법?
[0, 1, 2, 4, 5, 28, 199]
내가 그 실행하고 다시 199 결과를 얻을 수있는 기능이있다?
EDIT : for..in 루프와 관련된 명백한 강력한 해결책이 있습니다. 가능하다면 그보다 나은 방법을 찾고 싶습니다.
루프는 형식적으로 올바른 방법입니다.
type
TSetType = set of TEnumType;
function HighestMember(const s: TSetType): TEnumType;
begin
for Result := High(Result) downto Low(Result) do
if Result in s then
exit;
raise Exception.Create('empty sets have no highest member');
end;
당신이 유형의 안전을 잃고 강제 둘 유형 캐스팅 또는 어셈블러, 필요 솔루션의 다른 종류 - 그들이가는 "언어 외부를,"말하자면.
집합에 32 개 이하의 요소가 있다고 보증 할 수있는 경우 집합에 일반 정수를 겹칠 수 있으며 질문은 32 비트에서 가장 높은 비트 집합의 위치를 묻는 것과 같습니다 정수. 당신이 세트의 형태에서 32 요소 제한이없는 경우
는, 당신은 델파이의 256 요소 한계가 있고, 어떤 비트 : 그건 꽤 많이, 이곳에 질문 됐어요 -twiddling 솔루션은 32- 바이트 입력을 처리해야합니다.
세트의 순서는 정해져 있지 않으므로 루프보다 훨씬 좋을 것입니다. 한 세트의 최소/최대 값을 지속적으로 찾으려면 heap data structure을 사용하십시오.이 값은 최소값/최대 값을 얻기 위해 O (1) 검색을 제공하고 다른 값에는 O (log n) 검색을 제공합니다.
다음은 바이트 세트의 내부 구조에 대한 지식을 사용하는 조금 더 빠른 버전입니다.
type
TByteSet = set of Byte;
function HighestElement(const ByteSet: TByteSet): Byte;
type
TSetBytes = array[0..SizeOf(TByteSet) - 1] of Byte;
var
I, J: Integer;
B: Byte;
SetBytes: TSetBytes;
begin
if ByteSet <> [] then
begin
SetBytes := TSetBytes(ByteSet);
// Start at the top and work down, one byte at a time
for I := SizeOf(TByteSet) - 1 downto 0 do
begin
// Any bits set here
B := SetBytes[I];
if B <> 0 then
begin
Result := I * 8;
for J := 0 to 7 do
if (B shr J) and 1 <> 0 then
begin
Result := Result + J;
Exit;
end;
end;
end;
end else
// No elements set
end;
세트 유형 TByteSet을 거의 모든 설정 유형으로 변경할 수 있으며이 기능은 여전히 작동해야합니다. 함수의 decland와 body 안에있는 TByteSet을 설정의 타입으로 대체하면됩니다. 또한 AnsiChar 집합이나 일부 열거 형 집합을 사용하는 경우 실제 요소 형식을 반환하도록 수정할 수 있습니다. 가장 낮은 값을 얻으려면 "I"for 루프를 "0 to SizeOf (TByteSet) - 1"로 변경하고 "J"루프의 if 테스트를 "if (B shl J) 및 $ 80 <> 0"으로 변경하십시오.
흠 "platform"과 "deprecated"외에도 "endianunsafe"지시어가 필요합니다 :-) –
있지만 짧을 :
type
TByteSet = set of Byte;
function MaxSet(S: TByteSet): Byte;
var
CardArr: Array [0..7] of Cardinal absolute S;
i: Byte;
begin
i := 7;
while (i > 0) AND (CardArr[i] = 0) do
Dec(i);
Result := i + Floor(Log2(CardArr[i]));
end;
최저 수학 기기를 사용하지 :
type
TCharSet = set of Char;
function MaxOfSet(aSet: TCharSet):Char;
var
Data:array[0..SizeOf(TCharSet)-1] of Byte absolute aSet;
i,r:Byte;
begin
if aSet<>[] then begin
i:=SizeOf(TCharSet)-1;
while (i>0) and (Data[i]=0) do
Dec(i);
r:=i*8;
i:=Data[i];
while (i and $80)=0 do begin
i:=i shl 1;
Dec(r)
end;
Result:=Chr(r+7)
end
else
raise Exception.Create('Unable to extract max value from an empty set');
end;
function MinOfSet(aSet: TCharSet):Char;
var
Data:array[0..SizeOf(TCharSet)-1] of Byte absolute aSet;
i,r:Byte;
begin
if aSet<>[] then begin
i:=0;
while (i<SizeOf(TCharSet)-1) and (Data[i]=0) do
Inc(i);
r:=i*8;
i:=Data[i];
while (i and 1)=0 do begin
i:=i shr 1;
Inc(r)
end;
Result:=Chr(r)
end
else
raise Exception.Create('Unable to extract min value from an empty set');
end;
답변에 대한 설명을 추가하십시오. 그것은 단지 코드 조각보다 도움이 될 것입니다. – Billa
256 맥스 카운트 루프 최상위 비트 세트 무력 아니다 찾을. 국방부에 대한 공격이나 RSA 암호 해독 시도는 무차별 적 공격입니다. 이것이 최상의 솔루션입니다. 가독성 우선 코드를 작성하십시오 (실제 병목 현상이 발생한 경우에만). – paxdiablo
그런 종류의 비트 집합으로 내부 구현에 의존하지 않는가? 그렇지 않으면 모든 가능한 값을 반복하는 대신 집합의 요소를 반복하는 것이 좋습니다. – jpfollenius
더 매끄럽고 모든 가능한 값을 확인하는 것 외에는 집합의 내용을 열거 할 방법이 없습니다. 내부적으로 "for-in"루프가 작동하는 방식입니다. 코드로 시연 한 메서드는 내부 표현에 의존하지 않고 집합 만 유한합니다.비트 열렬한 해결책은 내부 표현에 의존하지만 이는 매우 안전한 가정입니다. 델리는 결코 변하지 않았습니다. 그들은 터보 파스칼에서 돌아온 것과 같습니다. –