การสร้างการแสดงออกทางคณิตศาสตร์แบบสุ่ม


16

ฉันมีความคิดนี้ในหัวของฉันเพื่อสร้างและประเมินนิพจน์ทางคณิตศาสตร์แบบสุ่ม ดังนั้นฉันจึงตัดสินใจที่จะถ่ายภาพและทำอัลกอริธึมก่อนที่จะเขียนโค้ดเพื่อทดสอบ

ตัวอย่าง:

นี่คือตัวอย่างของนิพจน์ที่ฉันต้องการสร้างแบบสุ่ม:

4 + 2                           [easy]
3 * 6 - 7 + 2                   [medium]
6 * 2 + (5 - 3) * 3 - 8         [hard]
(3 + 4) + 7 * 2 - 1 - 9         [hard]
5 - 2 + 4 * (8 - (5 + 1)) + 9   [harder]
(8 - 1 + 3) * 6 - ((3 + 7) * 2) [harder]

คนที่ง่ายและปานกลางค่อนข้างตรงไปตรงมา Randoms intคั่นด้วยตัวดำเนินการสุ่มไม่มีอะไรที่นี่บ้า แต่ฉันมีปัญหาในการเริ่มต้นกับสิ่งที่สามารถสร้างหนึ่งในที่ยากและหนักขึ้นตัวอย่าง ฉันไม่แน่ใจด้วยซ้ำว่าอัลกอริทึมเดียวสามารถให้สองอันสุดท้ายกับฉันได้

สิ่งที่ฉันกำลังพิจารณา:

ฉันไม่สามารถพูดได้ว่าฉันลองใช้ความคิดเหล่านั้นเพราะฉันไม่ต้องการเสียเวลาไปในทิศทางที่ไม่มีโอกาสทำงานตั้งแต่แรก แต่ถึงกระนั้นฉันคิดว่าการแก้ปัญหาสองสาม:

  • ใช้ต้นไม้
  • ใช้การแสดงออกปกติ
  • ใช้วง "for-type" ที่บ้าคลั่ง (แน่นอนที่สุด)

สิ่งที่ฉันกำลังมองหา:

ฉันต้องการทราบวิธีที่คุณเชื่อว่าเป็นวิธีที่ดีที่สุดระหว่างวิธีการแก้ปัญหาที่ฉันพิจารณาและความคิดของคุณ

หากคุณเห็นวิธีที่ดีในการเริ่มต้นฉันขอขอบคุณผู้นำในทิศทางที่ถูกต้องเช่นเมื่อเริ่มต้นอัลกอริทึมหรือโครงสร้างทั่วไปของมัน

โปรดทราบด้วยว่าฉันจะต้องประเมินการแสดงออกเหล่านั้น สิ่งนี้สามารถทำได้หลังจากสร้างนิพจน์หรือในระหว่างการสร้าง หากคุณคำนึงถึงคำตอบของคุณก็ถือว่ายอดเยี่ยม

ฉันไม่ได้มองหาสิ่งใดที่เกี่ยวข้องกับภาษา แต่สำหรับบันทึกฉันกำลังคิดที่จะนำไปใช้ใน Objective-C เนื่องจากเป็นภาษาที่ฉันใช้งานเมื่อไม่นานมานี้

ตัวอย่างเหล่านั้นไม่ได้รวม:โอเปอเรเตอร์เนื่องจากฉันต้องการจัดการints เท่านั้นและโอเปอเรเตอร์นี้จะเพิ่มการยืนยันจำนวนมาก หากคำตอบของคุณให้วิธีแก้ปัญหาในการจัดการกับปัญหานี้มันยอดเยี่ยมมาก

หากคำถามของฉันต้องการคำชี้แจงใด ๆ โปรดถามในความคิดเห็น ขอบคุณสำหรับความช่วยเหลือของคุณ.


2
อืมมเพิ่มฟังก์ชั่นการออกกำลังกายและมันดูเหมือนว่าคุณกำลังมุ่งหน้าไปยังโปรแกรมทางพันธุกรรม
ฟิลิป

คำตอบ:


19

นี่คือการตีความเชิงทฤษฎีของปัญหาของคุณ

คุณกำลังหาคำที่สร้างแบบสุ่ม(การแสดงออกเชิงพีชคณิต) จากภาษาที่กำหนด นี่คือคำอธิบายอย่างเป็นทางการของไวยากรณ์พีชคณิตแบบง่ายที่สนับสนุนการเพิ่มและการคูณเท่านั้น:

E -> I 
E -> (E '+' E)
E -> (E '*' E)

นี่Eคือนิพจน์ (เช่นคำศัพท์ในภาษาของคุณ) และIเป็นสัญลักษณ์เทอร์มินัล (กล่าวคือไม่มีการขยายเพิ่มเติมใด ๆ ) แทนจำนวนเต็ม ความหมายข้างต้นสำหรับการEมีสามกฎการผลิต ตามคำจำกัดความนี้เราสามารถสร้างเลขคณิตที่ถูกต้องแบบสุ่มได้ดังนี้:

  1. เริ่มต้นด้วยEสัญลักษณ์เดียวของคำที่ส่งออก
  2. เลือกสุ่มสัญลักษณ์ที่ไม่ใช่เทอร์มินัลอย่างสม่ำเสมอ
  3. เลือกกฎการผลิตแบบสุ่มที่เหมือนกันสำหรับสัญลักษณ์นั้นและนำไปใช้
  4. ทำซ้ำขั้นตอนที่ 2 - 4 จนกระทั่งเหลือเพียงสัญลักษณ์เทอร์มินัล
  5. แทนที่สัญลักษณ์เทอร์มินัลทั้งหมดIด้วยจำนวนเต็มแบบสุ่ม

นี่คือตัวอย่างการใช้งานของอัลกอริทึมนี้:

E
(E + E)
(E + (E * E))
(E + (I * E))
((E + E) + (I * E))
((I + E) + (I * E))
((I + E) + (I * I))
((I + (E * E)) + (I * I))
((I + (E * I)) + (I * I))
((I + (I * I)) + (I * I))
((2 + (5 * 1)) + (7 * 4))

ผมถือว่าคุณจะเลือกที่จะเป็นตัวแทนของการแสดงออกที่มีอินเตอร์เฟซExpressionที่จะดำเนินการโดยการเรียนIntExpression, และAddExpression MultiplyExpressionหลังสองจากนั้นก็จะมีและleftExpression rightExpressionทั้งหมดExpressionsubclasses จะต้องดำเนินการevaluateวิธีการที่ทำงานซ้ำบนโครงสร้างที่กำหนดโดยวัตถุเหล่านี้ได้อย่างมีประสิทธิภาพและดำเนินการรูปแบบคอมโพสิต

ทราบว่าไวยากรณ์ข้างต้นและขั้นตอนวิธีการน่าจะเป็นของการขยายการแสดงออกEเป็นสัญลักษณ์ขั้วIเป็นเพียงในขณะที่ความเป็นไปได้ที่จะขยายการแสดงออกเป็นสองต่อไปคือการแสดงออกp = 1/3 1-p = 2/3ดังนั้นจำนวนที่คาดหวังของจำนวนเต็มในสูตรที่ผลิตโดยอัลกอริทึมดังกล่าวจึงไม่มีที่สิ้นสุด ความยาวที่คาดหวังของการแสดงออกขึ้นอยู่กับความสัมพันธ์ที่เกิดซ้ำ

l(0) = 1
l(n) = p * l(n-1) + (1-p) * (l(n-1) + 1)
     = l(n-1) + (1-p)

โดยที่l(n)หมายถึงความยาวที่คาดหวังของการแสดงออกทางคณิตศาสตร์หลังจากการnใช้กฎการผลิต ฉันจึงแนะนำให้คุณกำหนดความน่าจะเป็นที่ค่อนข้างสูงpให้กับกฎE -> Iดังกล่าวซึ่งคุณจะได้รับนิพจน์ที่ค่อนข้างเล็กและมีความน่าจะเป็นสูง

แก้ไข : หากคุณกังวลว่าไวยากรณ์ข้างต้นสร้างวงเล็บมากเกินไปให้ดูที่คำตอบของ Sebastian Negraszusซึ่งไวยากรณ์หลีกเลี่ยงปัญหานี้อย่างสง่างาม


โอ้โห .. เยี่ยมมากฉันชอบมากขอบคุณมาก! ฉันยังต้องดูข้อมูลเพิ่มเติมเกี่ยวกับโซลูชันทั้งหมดที่แนะนำเพื่อเลือกสิ่งที่ถูกต้อง ขอบคุณอีกครั้งคำตอบที่ดี
rdurand

ขอบคุณสำหรับการแก้ไขของคุณนั่นคือสิ่งที่ฉันไม่ได้คิด คุณคิดว่าการ จำกัด จำนวนครั้งที่คุณทำตามขั้นตอนที่ 2-4 สามารถใช้งานได้หรือไม่ บอกว่าหลังจากทำซ้ำ 4 (หรืออะไรก็ตาม) ของขั้นตอน 2-4 ให้อนุญาตกฏE-> Iเท่านั้น
rdurand

1
@rdurand: ใช่แน่นอน พูดหลังจากmทำซ้ำ 2-4 คุณจะไม่สนใจกฎการผลิตซ้ำ l(m)นี้จะนำไปสู่การแสดงออกของขนาดคาด อย่างไรก็ตามโปรดทราบว่านี่ไม่จำเป็น (ในทางทฤษฎี) เนื่องจากความน่าจะเป็นในการสร้างนิพจน์ที่ไม่มีที่สิ้นสุดนั้นมีค่าเป็นศูนย์แม้ว่าขนาดที่คาดหวังนั้นจะไม่มีที่สิ้นสุด แต่วิธีการของคุณเป็นอย่างดีตั้งแต่ในทางปฏิบัติหน่วยความจำที่ไม่ได้เป็นเพียง จำกัด แต่ยังเล็ก ๆ :)
blubb

ด้วยวิธีการแก้ปัญหาของคุณฉันไม่เห็นวิธีที่ฉันสามารถแก้ไขการแสดงออกในขณะที่สร้างมัน มีผู้ใด ? ฉันยังคงสามารถแก้ไขได้ในภายหลัง แต่ฉันก็ไม่อยาก
rdurand

หากคุณต้องการสิ่งนั้นทำไมไม่เริ่มต้นด้วยตัวเลขสุ่มเป็นนิพจน์พื้นฐานและแยกย่อยมัน (เขียนใหม่) ลงในการดำเนินการในลักษณะที่อธิบายบลับ? จากนั้นไม่เพียง แต่คุณจะมีวิธีแก้ปัญหาสำหรับการแสดงออกทั้งหมด แต่คุณจะได้รับการ subsolutions สำหรับแต่ละสาขาของต้นไม้การแสดงออก
mikołak

7

ก่อนอื่นฉันต้องการสร้างนิพจน์ในรูปแบบpostfixคุณสามารถแปลงเป็น infix หรือประเมินผลหลังจากสร้างนิพจน์แบบสุ่มของคุณ แต่การทำใน postfix หมายความว่าคุณไม่ต้องกังวลเกี่ยวกับวงเล็บหรือลำดับความสำคัญ

ฉันจะให้จำนวนคำทั้งหมดที่มีอยู่สำหรับโอเปอเรเตอร์ถัดไปในนิพจน์ของคุณ (สมมติว่าคุณต้องการหลีกเลี่ยงการสร้างนิพจน์ที่ผิดรูป) เช่นอะไร:

string postfixExpression =""
int termsCount = 0;
while(weWantMoreTerms)
{
    if (termsCount>= 2)
    {
         var next = RandomNumberOrOperator();
         postfixExpression.Append(next);
         if(IsNumber(next)) { termsCount++;}
         else { termsCount--;}
    }
    else
    {
       postfixExpression.Append(RandomNumber);
       termsCount++;
     }
}

เห็นได้ชัดว่านี่คือรหัสหลอกดังนั้นจึงไม่ได้ทดสอบ / อาจมีข้อผิดพลาดและคุณอาจจะไม่ใช้สตริง แต่สแต็กของสมาพันธ์ที่เลือกปฏิบัติบางอย่างเช่นประเภท


ขณะนี้ถือว่าผู้ประกอบการทั้งหมดเป็นไบนารี แต่ค่อนข้างง่ายที่จะขยายการกับผู้ประกอบการของ arity ที่แตกต่างกัน
JK

ขอบคุณมาก. ฉันไม่คิดว่า RPN เป็นความคิดที่ดี ฉันจะตรวจสอบคำตอบทั้งหมดก่อนที่จะยอมรับ แต่ฉันคิดว่าฉันสามารถทำงานนี้ได้
rdurand

+1 สำหรับการแก้ไขภายหลัง คุณสามารถกำจัดความต้องการที่จะใช้อะไรมากกว่ากองซึ่งฉันคิดว่าง่ายกว่าการสร้างต้นไม้
Neil

2
@rdurand ส่วนหนึ่งของข้อได้เปรียบของ post-fix หมายความว่าคุณไม่ต้องกังวลเกี่ยวกับการมาก่อน (ซึ่งถูกนำมาพิจารณาก่อนที่จะเพิ่มลงใน post-fix stack) หลังจากนั้นคุณก็จะปรากฏตัวถูกดำเนินการทั้งหมดที่คุณพบจนกระทั่งคุณปรากฏตัวดำเนินการแรกที่คุณพบบนสแต็กจากนั้นกดลงบนสแต็กผลลัพธ์และคุณดำเนินการต่อในลักษณะนี้จนกว่าคุณจะปรากฏค่าสุดท้ายออกจากสแต็ก
Neil

1
@rdurand นิพจน์2+4*6-3+7ได้รับการแปลงเป็นสแต็กหลังการแก้ไข+ 7 - 3 + 2 * 4 6(ด้านบนของสแต็กถูกที่สุด) คุณกด 4 และ 6 แล้วใช้โอเปอเรเตอร์*จากนั้นกด 24 อีกครั้ง จากนั้นคุณป๊อป 24 และ 2 และใช้โอเปอเรเตอร์ + จากนั้นกด 26 อีกครั้ง คุณดำเนินการต่อในลักษณะนี้และคุณจะพบว่าคุณจะได้รับคำตอบที่ถูกต้อง ขอให้สังเกตว่า* 4 6เป็นคำแรกในกองซ้อน นั่นหมายความว่าจะดำเนินการก่อนเพราะคุณได้กำหนดลำดับความสำคัญมาแล้วโดยไม่ต้องใช้วงเล็บ
Neil

4

คำตอบของ blubb เป็นการเริ่มต้นที่ดี แต่ไวยากรณ์ที่เป็นทางการของเขาสร้างคำจำกัดความมากเกินไป

นี่คือสิ่งที่ฉันจะทำ:

E -> I
E -> M '*' M
E -> E '+' E
M -> I
M -> M '*' M
M -> '(' E '+' E ')'

Eคือนิพจน์Iเลขจำนวนเต็มและMเป็นนิพจน์ที่เป็นอาร์กิวเมนต์สำหรับการดำเนินการคูณ


1
ส่วนขยายที่ดีอันนี้ดูไม่รกอย่างแน่นอน!
blubb

เมื่อฉันแสดงความคิดเห็นต่อคำตอบของ blubb ฉันจะเก็บวงเล็บที่ไม่ต้องการไว้ อาจทำให้การสุ่ม "less random";) ขอบคุณสำหรับแอดออน!
rdurand

3

วงเล็บในนิพจน์ "ยาก" แสดงถึงลำดับของการประเมินผล แทนที่จะพยายามสร้างฟอร์มที่แสดงโดยตรงเพียงแค่สร้างรายการผู้ประกอบการตามลำดับแบบสุ่มและสืบทอดรูปแบบการแสดงผลของนิพจน์จากนั้น

เบอร์: 1 3 3 9 7 2

ผู้ประกอบการ: + * / + *

ผลลัพธ์: ((1 + 3) * 3 / 9 + 7) * 2

การรับฟอร์มแสดงผลเป็นอัลกอริทึมแบบเรียกซ้ำได้ง่าย

อัปเดต:นี่คืออัลกอริทึมใน Perl เพื่อสร้างแบบฟอร์มการแสดงผล เพราะ+และ*กระจายแล้วมันสุ่มลำดับของเงื่อนไขสำหรับตัวดำเนินการเหล่านั้น ที่ช่วยป้องกันไม่ให้วงเล็บทั้งหมดอยู่ติดกับด้านใดด้านหนึ่ง

use warnings;
use strict;

sub build_expression
{
    my ($num,$op) = @_;

    #Start with the final term.
    my $last_num = pop @$num; 
    my $last_op = pop @$op;

    #Base case: return the number if there is just a number 
    return $last_num unless defined $last_op;

    #Recursively call for the expression minus the final term.
    my $rest = build_expression($num,$op); 

    #Add parentheses if there is a bare + or - and this term is * or /
    $rest = "($rest)" if ($rest =~ /[+-][^)]+$|^[^)]+[+-]/ and $last_op !~ /[+-]/);

    #Return the two components in a random order for + or *.
    return $last_op =~ m|[-/]| || rand(2) >= 1 ? 
        "$rest $last_op $last_num" : "$last_num $last_op $rest";        
}

my @numbers   = qw/1 3 4 3 9 7 2 1 10/;
my @operators = qw|+ + * / + * * +|;

print build_expression([@numbers],[@operators]) , "\n";

อัลกอริทึมนี้ดูเหมือนว่าจะสร้างต้นไม้ที่ไม่สมดุลอยู่เสมอ: กิ่งด้านซ้ายนั้นลึกในขณะที่อันที่ถูกต้องเป็นเพียงตัวเลขเดียว จะมีการเปิด parans มากเกินไปในการเริ่มต้นของแต่ละนิพจน์และลำดับของการดำเนินการจะถูกปล่อยจากซ้ายไปขวาเสมอ
scriptin

ขอบคุณสำหรับคำตอบและมันช่วยได้ แต่ @scriptin ฉันไม่เข้าใจสิ่งที่คุณไม่ชอบในคำตอบนี้ คุณช่วยอธิบายหน่อยได้ไหม?
rdurand

@scriptin ที่สามารถแก้ไขได้ด้วยการสุ่มลำดับการแสดงผลอย่างง่าย ดูการปรับปรุง

@rdurand @ dan1111 ฉันลองใช้สคริปต์แล้ว ปัญหาของทรีย่อยขนาดใหญ่ด้านซ้ายได้รับการแก้ไข แต่ต้นไม้ที่สร้างยังคงไม่สมดุลมาก ภาพนี้แสดงสิ่งที่ฉันหมายถึง นี้อาจไม่ได้รับการพิจารณาปัญหา แต่จะนำไปสู่สถานการณ์ที่ subexpressions ชอบ(A + B) * (C + D)จะไม่เคยนำเสนอในการแสดงออกที่สร้างขึ้นและยังมีจำนวนมากของ parens ซ้อนกัน
scriptin

3
@scriptin หลังจากคิดเกี่ยวกับเรื่องนี้ฉันยอมรับว่านี่เป็นปัญหา

2

เพื่อขยายบนวิธีทรีสมมติว่าแต่ละโหนดเป็นใบไม้หรือนิพจน์ไบนารี:

Node := Leaf | Node Operator Node

โปรดทราบว่าใบไม้เป็นเพียงจำนวนเต็มที่สร้างแบบสุ่มที่นี่

ตอนนี้เราสามารถสร้างแผนภูมิแบบสุ่ม การตัดสินใจว่าความน่าจะเป็นของแต่ละโหนดเป็นใบไม้ทำให้เราสามารถควบคุมความลึกที่คาดไว้แม้ว่าคุณอาจต้องการความลึกสูงสุดแน่นอนเช่นกัน:

Node random_tree(leaf_prob, max_depth)
    if (max_depth == 0 || random() > leaf_prob)
        return random_leaf()

    LHS = random_tree(leaf_prob, max_depth-1)
    RHS = random_tree(leaf_prob, max_depth-1)
    return Node(LHS, RHS, random_operator())

จากนั้นกฎที่ง่ายที่สุดสำหรับการพิมพ์ต้นไม้คือ()ล้อมรอบนิพจน์ที่ไม่ใช่แบบลีฟและหลีกเลี่ยงการกังวลเกี่ยวกับลำดับความสำคัญของโอเปอเรเตอร์


ตัวอย่างเช่นถ้าฉันวงเล็บการแสดงออกตัวอย่างสุดท้ายของคุณ:

(8 - 1 + 3) * 6 - ((3 + 7) * 2)
((((8 - 1) + 3) * 6) - ((3 + 7) * 2))

คุณสามารถอ่านต้นไม้ที่จะสร้าง:

                    SUB
                  /      \
               MUL        MUL
             /     6     /   2
          ADD          ADD
         /   3        3   7
       SUB
      8   1

1

ฉันจะใช้ต้นไม้ พวกเขาสามารถให้การควบคุมที่ดีแก่คุณในการสร้างนิพจน์ เช่นคุณสามารถ จำกัด ความลึกต่อสาขาและความกว้างของแต่ละระดับแยกจากกัน การสร้างแบบอิงทรียังให้คำตอบแล้วในระหว่างการสร้างซึ่งมีประโยชน์ถ้าคุณต้องการให้แน่ใจว่าผลลัพธ์ (และผลย่อย) นั้นยากพอและ / หรือไม่ยากเกินไปที่จะแก้ไข โดยเฉพาะอย่างยิ่งถ้าคุณเพิ่มตัวดำเนินการหารในบางจุดคุณสามารถสร้างนิพจน์ที่ประเมินเป็นจำนวนเต็ม


ขอบคุณสำหรับคำตอบ. ฉันมีความคิดเดียวกันเกี่ยวกับต้นไม้ความสามารถในการประเมิน / ตรวจสอบนิพจน์ย่อย บางทีคุณอาจให้รายละเอียดเพิ่มเติมเล็กน้อยเกี่ยวกับโซลูชันของคุณ คุณจะสร้างต้นไม้แบบนั้นได้อย่างไร (ไม่ใช่จริง ๆ แต่โครงสร้างทั่วไปจะเป็นอย่างไร)
rdurand

1

ต่อไปนี้เป็นคำตอบที่ยอดเยี่ยมของ Blubb:

สิ่งที่คุณกำลังพยายามสร้างที่นี่เป็นหลัก parser ที่ทำงานในสิ่งที่ตรงกันข้าม สิ่งที่ปัญหาและตัวแยกวิเคราะห์ของคุณมีเหมือนกันคือไวยากรณ์ที่ไม่มีบริบทสิ่งนี้ในรูปแบบ Backus-Naur :

digit ::= '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'
number ::= <digit> | <digit> <number>
op ::= '+' | '-' | '*' | '/'
expr ::= <number> <op> <number> | '(' <expr> ')' | '(' <expr> <op> <expr> ')'

โปรแกรมแยกวิเคราะห์เริ่มต้นด้วยสตรีมของเทอร์มินัล (โทเค็นตัวอักษรเช่น5หรือ*) และพยายามรวบรวมพวกมันเป็น nonterminals (สิ่งที่ประกอบไปด้วยเทอร์มินัลและ nonterminals อื่น ๆ เช่นnumberหรือop) ปัญหาของคุณเริ่มต้นด้วย nonterminals และทำงานแบบย้อนกลับเลือกสิ่งใดระหว่างสัญลักษณ์ "หรือ" (ไปป์) โดยการสุ่มเมื่อพบและทำซ้ำกระบวนการซ้ำจนกว่าจะถึงเทอร์มินัล

สองคำตอบอื่น ๆ ได้แนะนำว่านี่เป็นปัญหาของต้นไม้ซึ่งเป็นกรณีของชั้นแคบ ๆ ที่ไม่มีผู้ที่ไม่เกี่ยวข้องที่อ้างอิงตนเองโดยตรงหรือโดยอ้อมผ่าน nonterminal อื่น ตั้งแต่ไวยากรณ์อนุญาตให้ปัญหานี้เป็นจริงเป็นกราฟ (การอ้างอิงทางอ้อมผ่าน nonterminals อื่นจะนับรวมสิ่งนี้ด้วย)

มีโปรแกรมชื่อSpew ที่ ตีพิมพ์ใน Usenet ในช่วงปลายทศวรรษ 1980ซึ่ง แต่เดิมได้รับการออกแบบมาเพื่อสร้างหัวข้อข่าวแท็บลอยด์แบบสุ่มและยังเป็นยานพาหนะที่ยอดเยี่ยมสำหรับการทดลองกับ มันทำงานโดยการอ่านเทมเพลตที่ควบคุมการผลิตกระแสของเทอร์มินัลแบบสุ่ม นอกเหนือจากค่าความสนุก (พาดหัว, เพลงคันทรี่, พูดพล่อยๆภาษาอังกฤษออกเสียง) ฉันได้เขียนเทมเพลตจำนวนมากที่มีประโยชน์สำหรับการสร้างข้อมูลทดสอบที่มีตั้งแต่ข้อความธรรมดาไปจนถึง XML ไปจนถึงการแก้ไขข้อผิดพลาด และเขียนใน K&R C และมีรูปแบบเทมเพลตที่น่าเกลียดมันรวบรวมได้ดีและทำงานตามที่โฆษณาไว้ ฉันสร้างแม่แบบที่ช่วยแก้ปัญหาของคุณและโพสต์ไว้บน pastebin เนื่องจากการเพิ่มข้อความจำนวนมากที่นี่ดูเหมือนไม่เหมาะสม

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.