สารบัญ
ฉันจะแบ่งคำอธิบายของpseudocode ของTarjanเป็นส่วนต่อไปนี้:
- บล็อก If-else ของ Tarjan (
->
& |
ตัวดำเนินการ)
- การทดสอบการมอบหมายและความเท่าเทียมกัน (
:=
และ=
)
- มี
else if
แต่ไม่มีelse
โครงสร้าง
- ผู้ดำเนินการมอบหมายตามเงื่อนไขของ Tarjan
:= if
ตัวอย่างเพิ่มเติมของ Tarjan's if
และ:= if
5.5
Tarjan Arrays (หรือรายการ)
สรุปผู้ประกอบการ
- ตัวดำเนินการศรสองหัวศรของ Tarjan (
⟷
)
- Do-loops ของ Tarjan เหมือนกับ C / Java while-loops
- ผู้ประกอบการกำหนดเงื่อนไขของ Tarjan พร้อมเงื่อนไขที่ผิดพลาดทั้งหมด
(1) บล็อก If-else ของ Tarjan
(ผู้ประกอบการ→
และ|
)
if-else
สร้างอาจจะเป็นโครงสร้างการควบคุมพื้นฐานที่สุดในภาษา Tarjan ของ นอกจากบล็อก if-like แบบ C แล้วพฤติกรรม if-else นั้นมีอยู่แล้วภายในการมอบหมายของ Tarjan และ Tarjan's ในขณะที่ลูป ตัวดำเนินการลูกศรของ Tarjan ->
(หรือ→) เป็นตัวคั่นระหว่างเงื่อนไขของคำสั่ง if-if และบล็อกการดำเนินการของคำสั่ง if
ตัวอย่างเช่นในภาษา Tarjan เราอาจมี:
# Example One
if a = 4 → x := 9 fi
หากเราแปลบรรทัดโค้ด Tarjan บางส่วนเป็น C หรือ Java เราจะได้รับสิ่งต่อไปนี้
if (a = 4)
x := 9
fi
แทนการจัดฟันด้านขวา (ใน C และ Java) Tarjan จบif
-block ด้วย ALGOL ที่เหมือนการสะกดคำย้อนหลังของคีย์คำ:fi
หากเราแปลตัวอย่างข้างต้นต่อไปเราจะได้รับ:
if (a = 4) {
x := 9
}
(2) การทดสอบการมอบหมายและความเท่าเทียมกัน ( :=
และ=
)
Tarjan ใช้ตัวดำเนินการเหล่านี้จาก ALGOL (ภายหลังจะเห็นใน Pascal)
Tarjan ใช้=
สำหรับการทดสอบความเท่าเทียมกันไม่ใช่การมอบหมาย (เพื่อให้ทำงานได้เหมือน Java ==
)
สำหรับการกำหนด, การใช้ Tarjan :=
ซึ่งทำงานเช่น =
Java
ดังนั้นหากเราแปลตัวอย่างของเราต่อไปเรามี:
if (a == 4) {
x = 9
}
แถบแนวตั้ง (หรือ " |
ไพพ์" หรือ) ในภาษาของ Tarjan เทียบเท่ากับelse if
คำสำคัญใน C หรือ Java
ตัวอย่างเช่นในภาษา Tarjan เราอาจมี:
# Example Two
if a = 4 → x := 9 | a > 4 → y := 11 fi
รหัส Tarjan ด้านบนแปลเป็น:
if (a == 4) {
x = 9
}
else if (a > 4) {
y = 11
}
(3) else if
เท่านั้นและไม่มีelse
โครงสร้าง
ก่อนหน้านี้ฉันพูดถึงพื้นฐานของif
-statements โดยไม่อธิบายความแตกต่าง อย่างไรก็ตามเราจะไม่พูดคุยรายละเอียดเล็กน้อย ประโยคสุดท้ายในif-else
บล็อกTarjan-ian ต้องมีตัวดำเนินการลูกศร ( →
) เสมอ เป็นเช่นนี้ไม่มีelse
ในภาษา Tarjan else if
เพียง สิ่งที่ใกล้เคียงที่สุดกับelse
-block ในภาษาของ Tarjan คือการทำให้เงื่อนไขการทดสอบที่ถูกtrue
ต้องที่สุด
if a = 4 → x := 9 | a > 4 → y := 11 | true → z := 99 fi
ใน C / Java เราจะมี:
if (a == 4) {
x = 9
}
else if (a > 4) {
y = 11
}
else { // else if (true)
z = 99
}
ตัวอย่างเข้าใจง่ายกว่าคำอธิบายทั่วไป อย่างไรก็ตามตอนนี้เรามีตัวอย่างบางส่วนภายใต้เข็มขัดของเรารู้ว่ารูปแบบทั่วไปของโครงสร้าง if-else ของ Tarjan มีดังนี้:
if condition
→ stuff to do
| condition
→ stuff to do
[...]
| condition
→ stuff to do
fi
ตัวละคร |
เป็นเช่นif else
ตัวละครจะ→
แยกสภาพการทดสอบออกจากสิ่งที่ต้องทำ
(4) ผู้ดำเนินการมอบหมายตามเงื่อนไขของ Tarjan := if
Tarjan if
สามารถใช้สองวิธีที่แตกต่างกันมาก จนถึงขณะนี้เราได้อธิบายเพียงหนึ่งในการใช้ประโยชน์จาก if
Tarjanian ค่อนข้างสับสน Tarjan ยังคงใช้สัญกรณ์ / ไวยากรณ์if
สำหรับประเภทที่สองของif
โครงสร้าง ซึ่งif
ถูกนำมาใช้จะขึ้นอยู่กับบริบท การวิเคราะห์บริบทนั้นทำได้ง่ายมากเนื่องจากประเภทที่สองของ Tarjan- if
ได้รับการแก้ไขล่วงหน้าโดยผู้ดำเนินการที่ได้รับมอบหมาย
ตัวอย่างเช่นเราอาจมีรหัส Tarjan ต่อไปนี้:
# Example Three
x := if a = 4 → 9 fi
เริ่มพูดนอกเรื่อง
หลังจากทำงานกับรหัส Tarjan สักครู่คุณจะคุ้นเคยกับลำดับของการดำเนินการ หากเราวงเล็บเงื่อนไขการทดสอบในตัวอย่างข้างต้นเราได้รับ:
x := if (a = 4) → 9 fi
a = 4
ไม่ใช่การดำเนินการที่ได้รับมอบหมาย a = 4
เป็นเช่นa == 4
- มันกลับจริงหรือเท็จ
สิ้นสุดการแยกย่อย
มันสามารถช่วยให้คิดว่า:= if
เป็นไวยากรณ์สำหรับผู้ประกอบการเดียวที่แตกต่างจาก:=
และif
ในความเป็นจริงเราจะอ้างถึง:= if
ผู้ประกอบการเป็นผู้ประกอบการ "การกำหนดเงื่อนไข"
สำหรับรายการเราif
(condition → action)
สำหรับ:= if
รายการเรา(condition → value)
อยู่ที่ไหนvalue
ค่าด้านขวามือเราอาจกำหนดให้ทางด้านซ้ายlhs
# Tarjan Example Four
lhs := if (a = 4) → rhs fi
ใน C หรือ Java อาจมีลักษณะดังนี้:
# Example Four
if (a == 4) {
lhs = rhs
}
ลองพิจารณาตัวอย่างของ "การกำหนดเงื่อนไข" ในรหัส Tarjanian:
# Tarjan การสร้างอินสแตนซ์ของตัวอย่างห้า x: = a = 4 → 9 | a> 4 → 11 | true → 99 fi
ใน C / Java เราจะมี:
// C/Java Instantiation of Example Five
if (a == 4) {
x = 9
}
else if (a > 4) {
x = 11
}
else if (true) { // else
x = 99
}
(5) สรุปผู้ประกอบการ:
จนถึงตอนนี้เรามี:
:=
...... โอเปอเรเตอร์ที่ได้รับมอบหมาย (C / Java =
)
=
...... การทดสอบความเท่าเทียมกัน (C / Java ==
)
→
...... ตัวคั่นระหว่างเงื่อนไขการทดสอบของ if-block และเนื้อหาของ if-block
|
..... C / Java อื่น - ถ้า
if ... fi
..... ถ้าบล็อกอื่น
:= if... fi
..... การมอบหมายแบบมีเงื่อนไขขึ้นอยู่กับบล็อก if-else
(5.5) รายการ / อาร์เรย์ Tarjan:
ภาษาของ Tarjan มีคอนเทนเนอร์แบบอาเรย์ในตัว ไวยากรณ์สำหรับ Tarjan arrays นั้นใช้งานง่ายกว่าสัญกรณ์สำหรับif else
คำสั่งTarjan
list1 := ['lion', 'witch', 'wardrobe'];
list2a := [1, 2, 3, 4, 5];
list2b := [1, 2];
list3 := ["a", "b", "c", "d"];
list4 := [ ]; # an empty array
องค์ประกอบอาเรย์ Tarjan เข้าถึงได้ด้วยวงเล็บ()
ไม่ใช่วงเล็บเหลี่ยม[]
1
การจัดทำดัชนีเริ่มต้นที่ ดังนั้น,
list3 := ["a", "b", "c", "d"]
# list3(1) == "a" returns true
# list3(2) == "b" return true
ด้านล่างแสดงวิธีสร้างอาร์เรย์ใหม่ที่มีองค์ประกอบที่ 1 และ 5 ของ [1, 2, 3, 4, 5, 6, 7]
nums := [1, 2, 3, 4, 5, 6, 7]
new_arr := [nums(1), nums(5)]
ตัวดำเนินการความเสมอภาคถูกกำหนดไว้สำหรับอาร์เรย์ พิมพ์รหัสต่อไปนี้true
x := false
if [1, 2] = [1, 2, 3, 4, 5] --> x := true
print(x)
วิธีของ Tarjan ในการทดสอบว่าอาเรย์นั้นว่างหรือไม่คือการเปรียบเทียบกับอาเรย์ที่ว่างเปล่า
arr := [1, 2]
print(arr = [ ])
# `=` is equality test, not assignment
หนึ่งสามารถสร้างมุมมอง (ไม่คัดลอก) ของอาร์เรย์ย่อยโดยการให้ดัชนีหลายตัวให้กับผู้ประกอบการ()
รวมกับ..
list3 := ["a", "b", "c", "d"]
beg := list3(.. 2)
# beg == ["a", "b"]
# beg(1) == "a"
end := list3(3..)
# end == ["c", "d"]
# end(1) == "c"
mid := list3(2..3)
# mid == ["b", "c"]
# mid(2) == "c"
# `list3(4)` is valid, but `mid(4)` is not
(6) ตัวอย่างเพิ่มเติมของ Tarjan if
และ:= if
ต่อไปนี้เป็นอีกตัวอย่างของการกำหนดเงื่อนไข Tarjan ( := if
):
# Tarjan Example Six
a := (false --> a | true --> b | false --> c1 + c2 | (2 + 3 < 99) --> d)
(true --> b)
เป็น(cond --> action)
ประโยคซ้ายสุดที่มีเงื่อนไขจริง ดังนั้นการมอบหมายต้นฉบับตัวอย่างที่หกจึงมีพฤติกรรมการมอบหมายเช่นเดียวกับa := b
ด้านล่างเป็นตัวอย่างที่ซับซ้อนที่สุดของโค้ด Tarjan ของเรา:
# Tarjan Example -- merge two sorted lists
list function merge (list s, t);
return if s =[] --> t
| t = [ ] --> s
| s != [ ] and t != [] and s(l) <= t(1) -->
[s(1)]& merge(s[2..], t)
| s != [ ]and t != [ ] and s(1) > r(l) -->
[t(1)] & merge (s,t(2..))
fi
end merge;
ต่อไปนี้เป็นคำแปลของรหัสของ Tarjan สำหรับการรวมสองรายการที่เรียงลำดับ ต่อไปนี้ไม่ใช่ C หรือ Java แต่มันใกล้กว่า C / Java มากกว่ารุ่น Tarjan
list merge (list s, list t) {
if (s is empty) {
return t;
}
else if (t is empty){
return s;
}
else if (s[1] <= t[1]) {
return CONCATENATE([s[1]], merge(s[2...], t));
else { // else if (s[1] > t[1])
return CONCATENATE ([t[1]], merge(s,t[2..]);
}
}
ด้านล่างนี้เป็นอีกตัวอย่างของ Tarjan-code และการแปลในภาษาที่คล้ายกับ C หรือ Java:
heap function meld (heap h1, h2);
return if h1 = null --> h2
| h2 = null --> h1
| h1 not null and h2 not null --> mesh (h1, h2)
fi
end meld;
ด้านล่างคือการแปล C / Java:
HeapNode meld (HeapNode h1, HeapNode h2) {
if (h1 == null) {
return h2;
}
else if (h2 == null) {
return h1;
} else {
mesh(h1, h2)
}
} // end function
(7) โอเปอเรเตอร์ลูกศรชี้สองตาร์จัน ( <-->
)
ด้านล่างเป็นตัวอย่างของรหัส Tarjan:
x <--> y
ตัวดำเนินการ Double Arrow ( ⟷
) ทำในภาษาของ Tarjan อย่างไร
ตัวแปรเกือบทั้งหมดในภาษา Tarjan เป็นตัวชี้
<-->
เป็นการดำเนินการสลับ พิมพ์ดังต่อไปนี้true
x_old := x
y_old := y
x <--> y
print(x == y_old) # prints true
print(y == x_old) # prints true
หลังจากดำเนินการx <--> y
แล้วให้x
ชี้ไปที่วัตถุซึ่งy
เคยชี้ไปที่และy
ชี้ไปยังวัตถุที่x
เคยชี้ไป
ด้านล่างนี้เป็นคำสั่ง Tarjan โดยใช้<-->
โอเปอเรเตอร์:
x := [1, 2, 3]
y := [4, 5, 6]
x <--> y
ด้านล่างเป็นการแปลจากรหัส Tarjan ด้านบนเป็น pseudocode ทางเลือก:
Pointer X = address of array [1, 2, 3];
Pointer Y = address of array [4, 5, 6];
Pointer X_OLD = address of whatever X points to;
X = address of whatever Y points to;
Y = address of whatever X_OLD points to;
อีกทางหนึ่งเราอาจมี:
void operator_double_arrow(Array** lhs, Array** rhs) {
// swap lhs and rhs
int** old_lhs = 0;
old_lhs = lhs;
*lhs = *rhs;
*rhs = *old_lhs;
return;
}
int main() {
Array* lhs = new Array<int>(1, 2, 3);
Array* rhs = new Array<int>(4, 5, 6);
operator_double_arrow(&lhs, &rhs);
delete lhs;
delete rhs;
return 0;
}
ด้านล่างนี้เป็นตัวอย่างหนึ่งของฟังก์ชัน Tarjan โดยใช้⟷
โอเปอเรเตอร์:
heap function mesh (heap nodes h1, h2);
if key(h1) > key(h2) → h1 ⟷ h2 fi;
right (h1) := if right(h1) = null → h2
|right(h1) ≠ null → mesh (right(h1), h2)
fi;
if rank (left (h1)) < rank (right (h1))
→ left(h1) ⟷ right(h1)
fi;
rank (h1) := rank(right(h1)) + 1;
return h1;
end mesh;
ด้านล่างเป็นการแปลmesh
ฟังก์ชั่นของ Tarjan เป็นรหัสหลอกซึ่งไม่ใช่ C แต่ดูเหมือน C (พูดค่อนข้างมาก) จุดประสงค์ของสิ่งนี้คือเพื่อแสดงให้เห็นว่า⟷
ผู้ปฏิบัติงานของ Tarjan ทำงานอย่างไร
node pointer function mesh(node pointers h1, h2) {
if (h1.key) > h2.key) {
// swap h1 and h2
node pointer temp;
temp = h1;
h1 = h2;
h2 = temp;
}
// Now, h2.key <= h1.key
if (h1.right == null) {
h1.right = h2;
} else // h1.key != null {
h1.right = mesh(h1.right, h2);
}
if (h1.left.rank < h1.right.rank ) {
// swap h1.left and h1.right
node pointer temp;
temp = h1;
h1 = h2;
h2 = temp;
}
h1.rank = h1.right.rank + 1;
return h1;
}
(8) do-loops ของ Tarjan เหมือนกับ C / Java ในขณะที่-loops
ภาษาif
และfor
โครงสร้างของ Tarjan คุ้นเคยกับโปรแกรมเมอร์ C / Java อย่างไรก็ตามคำหลัก Tarjan do
ในขณะที่ห่วงคือ ทั้งหมดdo
-loops ท้ายด้วยคำหลักซึ่งเป็นสะกดถอยหลังของod
do
ด้านล่างเป็นตัวอย่าง:
sum := 0
do sum < 50 → sum := sum + 1
ใน pseudocode แบบ C เรามี:
sum = 0;
while(sum < 50) {
sum = sum + 1;
}
จริง ๆ แล้วข้างต้นไม่ถูกต้องนัก Tarjan do-loop นั้นจริงๆแล้วเป็น C / Java ที่while(true)
มี if-else block อยู่ภายใน การแปลที่แท้จริงของรหัส Tarjan มีดังนี้:
sum = 0;
while(true) {
if (sum < 50) {
sum = sum + 1;
continue;
// This `continue` statement is questionable
}
break;
}
ด้านล่างเรามี Tarjan do
-loop ที่ซับซ้อนมากขึ้น:
sum := 0
do sum < 50 → sum := sum + 1 | sum < 99 → sum := sum + 5
pseudocode สไตล์ C / Java สำหรับ Tarjan do
-loop ที่ซับซ้อนมีดังนี้:
sum = 0;
while(true) {
if (sum < 50) {
sum = sum + 1;
continue;
}
else if (sum < 99) {
sum = sum + 5;
continue;
}
break;
}
(9) ผู้ปฏิบัติงานที่ได้รับมอบหมายจาก Tarjan พร้อมเงื่อนไขที่ผิดพลาดทั้งหมด
แม้ว่าคำอธิบายที่ยาวเกินไปข้างต้นครอบคลุมเรื่องส่วนใหญ่ แต่บางเรื่องก็ยังไม่ได้รับการแก้ไข ฉันหวังว่าสักวันคนอื่นจะเขียนคำตอบที่ได้รับการปรับปรุงใหม่โดยอิงจากของฉันซึ่งตอบคำถามเหล่านี้
โดยเฉพาะอย่างยิ่งเมื่อใช้ตัวดำเนินการกำหนดเงื่อนไข:= if
และไม่มีเงื่อนไขใดเป็นจริงฉันไม่ใช่ค่าที่กำหนดให้กับตัวแปร
x := if (False --> 1| False --> 2 | (99 < 2) --> 3) fi
ฉันไม่แน่ใจ แต่เป็นไปได้ที่จะไม่มีการมอบหมายx
:
x = 0;
if (false) {
x = 1;
}
else if (false) {
x = 2;
}
else if (99 < 2) {
x = 3;
}
// At this point (x == 0)
คุณอาจต้องการให้ประกาศตัวแปรด้านซ้ายที่เห็นใน:= if
คำสั่งก่อนหน้านี้ ในกรณีนั้นแม้ว่าเงื่อนไขทั้งหมดจะเป็นเท็จตัวแปรจะยังคงมีค่าอยู่
อีกทางเลือกหนึ่งอาจเป็นเงื่อนไขที่ผิดพลาดทั้งหมดแสดงถึงข้อผิดพลาดรันไทม์ อีกทางเลือกหนึ่งคือการส่งคืนnull
ค่าพิเศษและเก็บไว้null
ในอาร์กิวเมนต์ซ้ายมือของการกำหนด