สอบถามปัญหาการสลับเลข มีแนวทางการแก้ไขปัญหายังไงบ้างครับ
ไม่ใช้ source สลับโดยตรง
$temp = '0123456789';
$src = '112';
$forsort = substr($temp,0,strlen($src));
แล้วเอา $forsort ไปจัดเรียง
เอาตัวจัดเรียงที่ได้ ไปหาตำแหน่ง จาก $temp เพื่อไป แมพกับ $src
Date :
2020-02-23 13:52:55
By :
Chaidhanan
ตรงค่า $ele_amnt จะต้องหาจำนวนไม่ซ้ำกันให้ได้ก่อนครับ
เช่น ถ้าซ้ำกัน 2 ตัวจะเหลือ $ele_amnt เท่าไหร่ ต้องหาตรงนี้ให้ได้
เวลาเอามาวนลูปจะได้ไม่เกินจากที่ต้องการ
while(count($output) < $ele_amnt){
Date :
2020-02-24 10:34:57
By :
{Cyberman}
Code (PHP)
/**
* Multiply step down by one until number is 1.
*
* Example: number is 3 will be 3*2*1 = 6<br>
* number is 4 will be 4*3*2*1 = 24
*
* @param number $number
* @return number
*/
function factorial($number)
{
if ($number == 1) {
return $number;
} else {
return $number * factorial($number - 1);
}
}
factorial.php
Code (PHP)
include_once 'factorial.php';
$testNumber = 113;
$numbersArray = str_split($testNumber);
if (is_array($numbersArray)) {
$totalNumbers = count($numbersArray);
// 2 numbers possibility arrange is 2*1 = 2,
// 3 numbers possibility is 3*2*1 = 6,
// 4 numbers possibility is 4*3*2*1 = 24,
// 5 numbers possibility is 5*4*3*2*1 = 120
$maxPossibilityArrange = factorial($totalNumbers);
$output = [];
$outputKeys = [];
$numberArrayKeys = array_keys($numbersArray);
while (count($outputKeys) < $maxPossibilityArrange) {
shuffle($numberArrayKeys);
if (!in_array($numberArrayKeys, $outputKeys)) {
$outputKeys[] = $numberArrayKeys;
}
}
unset($maxPossibilityArrange, $numberArrayKeys, $totalNumbers);
foreach ($outputKeys as $eachArray) {
$number = '';
foreach ($eachArray as $eachKey) {
if (isset($numbersArray[$eachKey])) {
$number .= $numbersArray[$eachKey];
}
}
$output[] = $number;
}
unset($number, $outputKeys);
sort($output);
echo '<pre>'.print_r($output, true).'</pre>'.PHP_EOL;
} else {
echo 'unable to continue, cannot split numbers into array.';
exit();
}
test.php
เนื่องจากของเดิมมันไปเช็ค in_array กับค่าตัวเลขที่สลับกันแล้ว (shuffle) ดังนั้นแน่นอนว่าถ้าเลขมันซ้ำมันก็เข้าเงื่อนไข in_array นั่นแหละ
ตัวอย่าง 113 จะสลับไปสลับมาได้ทั้งหมด...
Quote: Array
(
[0] => 113
[1] => 113
[2] => 131
[3] => 131
[4] => 311
[5] => 311
)
ดังนั้นในโค้ดของเดิม เมื่อเจอ 113 เข้าไป เจอ 131, 311 เข้าไป ค่าที่สลับได้มันจึงเหลือแค่ 3 ซึ่งน้อยกว่า 6 ตามสูตร 3*2*1
ในโค้ดใหม่จึงใช้วิธีเล่นกับ array key หรือ array index ซึ่งจะไม่มีวันซ้ำแน่ๆ ก็ช่วยแก้ไขได้ แล้วก็ไปจับเอา key ให้ตรง value จากต้นฉบับอีกที.
แต่!!!!
เนื่องจาก shuffle() มันมีโอกาสทำงานซ้ำๆบ่อยมาก ซึ่งทดลอง debug โดยใส่ $total++ เข้าไปใน while พบว่าบางครั้งมันวนถึง 30 รอบเลย!?!!
ดังนั้นเมื่อมีโอกาสซ้ำบ่อย ทำให้วนหลายรอบ เมื่อวนหลายรอบ การใส่ตัวเลขหลายๆหลัก เช่น 12345 หรือมากกว่านั้น จะยิ่งเพิ่มความเสี่ยงในการที่จะ execution timeout ได้อีกเหมือนเดิม!!
วิธีแก้ทำยังไง?
ผมไม่รู้.
คือคิดได้ แต่โค้ดไม่ออก เพราะมันเกี่ยวกับ array หลายมิติและตัวเลข ดูแล้วมึนจัด.
ตัวอย่างนะครับ
Code
// possibility 4
12 [0, 1]
21 [1, 0]
// possibility 6
123 [0, 1, 2]
132 [0, 2, 1]
213 [1, 0, 2]
231 [1, 2, 0]
312 [2, 0, 1]
321 [2, 1, 0]
// possibility 6
123 [0, 1, 2]
213 [1, 0, 2]
132 [0, 2, 1]
312 [2, 0, 1]
321 [2, 1, 0]
231 [1, 2, 0]
// possibility 24
1234 [0, 1, 2, 3]
1243 [0, 1, 3, 2]
1324 [0, 2, 1, 3]
1342 [0, 2, 3, 1]
1423 [0, 3, 1, 2]
1432 [0, 3, 2, 1]
2134
2143
2314
2341
2413
2431
// possibility 120
12345 [0, 1, 2, 3, 4]
12354 [0, 1, 2, 4, 3]
12435 [0, 1, 3, 2, 4]
12453 [0, 1, 3, 4, 2]
12534 [0, 1, 4, 2, 3]
12543 [0, 1, 4, 3, 2]
13245 [0, 2, 1, 3, 4]
13254 [0, 2, 1, 4, 3]
13425 [0, 2, 3, 1, 4]
13452 [0, 2, 3, 4, 1]
13524 [0, 2, 4, 1, 3]
13542 [0, 2, 4, 3, 1]
14235 [0, 3, 1, 2, 4]
14253 [0, 3, 1, 4, 2]
14325 [0, 3, 2, 1, 4]
14352 [0, 3, 2, 4, 1]
14523 [0, 3, 4, 1, 2]
14532 [0, 3, 4, 2, 1]
15234 [0, 4, 1, 2, 3]
15243 [0, 4, 1, 3, 2]
15324 [0, 4, 2, 1, 3]
15342 [0, 4, 2, 3, 1]
15423 [0, 4, 3, 1, 2]
15432 [0, 4, 3, 2, 1]
จากเลขตัวอย่างข้างบน วิธีที่คิดได้คือวนจาก array key 0 ไปยังสุดท้าย ตามจำนวนรอบของ row เช่น เลข 2 หลัก วนหลักละ 1 รอบ
เลข 3 หลัก วนหลักละ 2 รอบ
ทั้งหมดมีการเช็คข้าม row ด้วยว่าซ้ำหรือไม่ ซึ่งเพิ่มความงงเข้าไปอีก.
วิธีนี้ถ้าคิดออก มันจะลดการ shuffle มั่วๆซั่วๆซ้ำๆจน execution timeout ได้มากเลย.
ก็ขอใครคิดได้ลองบอกด้วยครับ.
Date :
2020-02-25 01:27:36
By :
mr.v
www.yourdomain.com/test.php?digit=5
เลข 5 ปรับเอาตามชอบ ถ้าไม่กลัวเมมเต็มก็ใส่ไปเยอะ 55555
Code (PHP)
<?php
function Modi(&$f,&$s, &$ar){
$l=strlen($s);
for($i=0; $i<$l; $i++){
$x=$f.substr($s,$i,1);
//------------------------------------
if($i==0){$y=substr($s,1);}
elseif($i==($l-1)){ $y=substr($s,0,$i);}
else{$y=substr($s,0,$i).substr($s,$i+1);}
if ($f.$s!=$x.$y) $ar[]=$x.$y;
Modi($x, $y, $ar);
}
}
function map($s, &$ar){
foreach($ar as $x){
$z='';
for($i=0; $i<strlen($x); $i++){
$z.=$s[$x[$i]];
}
echo '<br>',$z;
}
}
$st = time();
$digit = isset($_GET['digit'])? $_GET['digit']: 5; // default สำหรับ 5 หลัก
$number = str_repeat('0123456789',$digit);
echo $src = substr(str_shuffle($number),0,$digit),'<br>';
$z=''; $tmp=substr('0123456789',0,$digit);
$ar=[$tmp];
Modi($z, $tmp, $ar);
$en = time();
echo '<br>TimeUse = ', $en - $st, '<br>Loop = ',count($ar);
map($src,$ar);
แก้ไขใหม่
ประวัติการแก้ไข 2020-02-25 16:34:27
Date :
2020-02-25 13:15:28
By :
Chaidhanan
Load balance : Server 01