PHP의 str_shuffle 함수는 종종 문자열의 시퀀스를 무작위로 방해하고 다양한 랜덤 순열을 생성하는 데 사용됩니다. 다음과 같이 사용하기가 매우 간단합니다.
<?php
$original = "abcdef";
$shuffled = str_shuffle($original);
echo $shuffled;
?>
이 코드가 실행될 때마다 원래 문자열의 임의 순열 조합을 반환합니다. 그러나 일부 응용 프로그램 시나리오에서는 검증 코드 생성, 임의 암호, 복권 시퀀스 등과 같은 생성 된 임의의 조합을 반복하지 않기를 원합니다.
그러나 str_shuffle 의 무작위 특성으로 인해 호출 할 때마다, 특히 샘플 크기가 작거나 통화 수가 많을 때, 복제 가능성이 크게 증가 할 수 있습니다. 그렇다면 중복 문자 조합을 생성하지 않는 방법은 무엇입니까? 다음은 몇 가지 실용적인 전략입니다.
가장 직관적 인 방법은 새로운 임의의 문자열을 생성하여 배열 또는 컬렉션에 저장하는 것입니다. 새 문자열을 생성 할 때 이미 존재하는지 확인하고 존재하는 경우 재생하십시오.
<?php
$original = "abcdef";
$generated = [];
function generateUniqueShuffle($str, &$history) {
do {
$shuffled = str_shuffle($str);
} while (in_array($shuffled, $history));
$history[] = $shuffled;
return $shuffled;
}
// 예:생성하다10독특한 무작위 조합
for ($i = 0; $i < 10; $i++) {
echo generateUniqueShuffle($original, $generated) . "\n";
}
?>
이 방법은 간단하지만 세대 수가 증가함에 따라 복제 점검이 느려지고 결국 원하는 수보다 적은 수 (제한된 조합)가 생성 될 수 있습니다.
줄의 모든 순열은 제한적입니다 (길이 n의 줄은 n! 순열을 갖는다). 먼저 재귀 알고리즘을 사용하여 모든 순열을 생성하고 저장 한 다음 무작위로 추출하여 제거 할 수 있습니다.
예제는 완전히 구성된 핵심 코드를 생성합니다.
<?php
function permute($str, $prefix = '') {
$result = [];
$len = strlen($str);
if ($len == 0) {
$result[] = $prefix;
} else {
for ($i = 0; $i < $len; $i++) {
$rem = substr($str, 0, $i) . substr($str, $i + 1);
$result = array_merge($result, permute($rem, $prefix . $str[$i]));
}
}
return $result;
}
$original = "abc";
$allPermutations = permute($original);
shuffle($allPermutations); // 무작위 혼란 순서
foreach ($allPermutations as $perm) {
echo $perm . "\n";
}
?>
이 방법은 짧은 문자열 길이 (일반적으로 8 미만)에 적합합니다. 전체 순열의 수가 폭발하여 (8! = 40320) 많은 메모리와 시간을 소비합니다.
요청 또는 오랫동안 복제를 피해야하는 경우 데이터베이스 또는 캐시 (예 : Redis)에 생성 된 조합을 녹화 한 다음 각 생성 후에 복제 된 지 확인한 다음 반환 여부를 결정할 수 있습니다.
이 방법은 다중 사용자 환경에서 또는 많은 메모리 사용을 피하고 독창성을 보장하는 대량 배치의 임의 조합을 생성 할 때 매우 실용적입니다.
Pseudocode 아이디어 예 :
<?php
// 데이터베이스에 연결하십시오,현재 조합이 이미 존재하는 경우 쿼리
// 있다면,则重新생성하다,直到생성하다唯一组合
// 새 조합을 데이터베이스에 삽입하여 저장하십시오
?>
특정 구현은 데이터베이스 시스템 및 사용하는 비즈니스 요구에 따라 다릅니다.
간단한 반복을 피하면 str_shuff 와 임의의 문자 교체를 결합하여 임의의 공간을 증가시킬 수도 있습니다. 예를 들어, 혼란 후에는 다른 문자 세트의 여러 문자를 무작위로 교체하십시오.
이것은 반복 확률을 줄이지 만 절대적으로 고유 한 것은 아닙니다.
소규모 및 간단한 시나리오 : 생성 된 결과를 배열로 저장하고 루프 감지는 복제를 피합니다.
중간 크기 및 짧은 문자열 : 사전 생성 된 전체 순열, 무작위로 그려진;
대규모 및 지속적인 고유성 : 데이터베이스 또는 캐시를 사용하여 응급 처치;
향상된 무작위성 : 다른 랜덤 변환 방법과 결합하여 반복 가능성을 줄입니다.
전략을 선택할 때는 스트링 길이, 세대 수, 성능 및 메모리 사용량을 측정하고 합리적인 솔루션을 설계해야합니다.