การสลับสับเปลี่ยน

Aug 24 2020

โพสต์นี้เป็นส่วนขยายของโพสต์ก่อนหน้าของฉัน: การเรียงลำดับขององค์ประกอบขนาดเล็กและขนาดใหญ่

ฉันพยายามทำงานกับการเรียงสับเปลี่ยนแบบสลับและนี่คือตรรกะของฉัน:

function Factorial(n) { 
    
    var res=1; 
          
    for (var i = 2; i <= n; i++) 
        res = res * i; 
    return res; 
} 
    
    
let n = 4;
let A = [];
let C = [];
let a = Factorial(n);
for(let i=0; i<=n;i++) {
    A[i] = 0;
}
A[1] = 1;
for(let k=0; k<n; k++) {
    let b = Factorial(k)*Factorial(n-k);
        
    A[k] = a/b * A[k]*A[n-k]/2;
}
console.log(A);

prints [0, 0, 0, 0]

ฉันคาดหวังว่า A [n + 1] = 5 สำหรับอินพุต n = 4 ตามโพสต์ก่อนหน้าของฉัน แต่ฉันได้เลขศูนย์ทั้งหมด วิธีแก้ไขปัญหานี้

คำตอบ

trincot Aug 24 2020 at 20:00

คุณไม่ได้ใช้ผลรวม (∑) ในสูตรของAndréที่คุณอ้างถึง

ฉันจะหลีกเลี่ยงการคำนวณแฟกทอเรียลเนื่องจากคุณจะพบกับข้อ จำกัด ของความแม่นยำของจุดลอยในไม่ช้า คุณสามารถใช้สามเหลี่ยมของ Pascalแทนได้

นี่คือการใช้งานเครื่องกำเนิดไฟฟ้าที่ไม่มีที่สิ้นสุดของลำดับ A การสาธิตพิมพ์ค่าของ A [0] ได้ถึง A [20]:

function * andre() { // generator
    let pascal = [1];
    let a = [1, 1];
    yield a[0];
    
    let n = 1;
    while (true) {
        yield a[n];
        // Build the next row in Pascal's Triangle
        pascal[n] = 1;
        for (let i = n - 1; i > 0; i--) {
            pascal[i] += pascal[i-1];
        }
        // Apply André's formula
        let sum = 0;
        for (let k = 0; k <= n; k++) {
            sum += pascal[k] * a[k] * a[n-k]
        }
        a[++n] = sum / 2;
    }
}

// demo: display A[0] up to A[20]
let i = 0;
for (let a of andre()) {
    console.log(`A[${i++}] = ${a}`);
    if (i > 20) break;
}

เมื่อลำดับนี้เพิ่มขึ้นอย่างรวดเร็วคุณจะต้องมีความแม่นยำสูงขึ้นในไม่ช้า หากคุณต้องการA [i]สำหรับค่าi ที่สูงขึ้นให้ใช้BigIntประเภทข้อมูลของ JavaScript