Mục lục
Tôi sẽ chia lời giải thích về mã giả của Tarjan thành các phần sau:
- Các khối If-other của Tarjan (các toán tử
->
& |
toán tử)
- Bài kiểm tra chuyển nhượng và bình đẳng (
:=
và =
)
- Có
else if
, nhưng không có else
cấu trúc
- Toán tử chuyển nhượng có điều kiện của Tarjan
:= if
Ví dụ bổ sung của Tarjan if
và:= if
5.5.
Mảng Tarjan (hoặc Danh sách)
Tóm tắt về các nhà khai thác
- Toán tử mũi tên nhọn của Tarjan (
⟷
)
- Các vòng lặp do Tarjan giống như các vòng lặp C / Java
- Toán tử gán điều kiện của Tarjan với tất cả các điều kiện sai
(1) Khối nếu khác của Tarjan
(các nhà khai thác →
và |
)
Cấu if-else
trúc có lẽ là cấu trúc điều khiển cơ bản nhất trong ngôn ngữ của Tarjan. Ngoài các khối if giống như C, hành vi if-if gần như được tích hợp trong các bài tập của Tarjan và các vòng lặp của Tarjan. Toán tử mũi tên của Tarjan ->
(hoặc →) là một dấu phân cách giữa điều kiện của câu lệnh if và khối thực thi của câu lệnh if.
Ví dụ: trong ngôn ngữ của Tarjan, chúng ta có thể có:
# Example One
if a = 4 → x := 9 fi
Nếu chúng tôi dịch một phần dòng mã Tarjan ở trên sang C hoặc Java, chúng tôi sẽ nhận được như sau:
if (a = 4)
x := 9
fi
Thay vì một dấu ngoặc nhọn bên phải (như trong C và Java), Tarjan kết thúc một if
-block bằng một cách viết ngược giống như ALGOL của từ khóa:fi
Nếu chúng tôi tiếp tục dịch ví dụ trên, chúng tôi nhận được:
if (a = 4) {
x := 9
}
(2) Bài kiểm tra chuyển nhượng và bình đẳng ( :=
và =
)
Tarjan lấy các toán tử này từ ALGOL (sau này cũng thấy trong Pascal).
Tarjan sử dụng =
cho các bài kiểm tra đẳng thức, không phải bài tập (vì vậy nó hoạt động như Java ==
).
Để gán, Tarjan sử dụng :=
, hoạt động như Java =
.
Vì vậy, nếu chúng tôi tiếp tục dịch ví dụ của mình, chúng tôi có:
if (a == 4) {
x = 9
}
Một thanh dọc (hoặc "ống" hoặc |
) trong ngôn ngữ của Tarjan tương đương với else if
từ khóa trong C hoặc Java.
Ví dụ: trong ngôn ngữ của Tarjan, chúng ta có thể có:
# Example Two
if a = 4 → x := 9 | a > 4 → y := 11 fi
Mã Tarjan ở trên có nghĩa là:
if (a == 4) {
x = 9
}
else if (a > 4) {
y = 11
}
(3) else if
chỉ và không có else
cấu trúc
Trước đó, tôi đã trình bày những điều cơ bản của if
-statements mà không mô tả các sắc thái. Tuy nhiên, chúng tôi sẽ không thảo luận về một chi tiết nhỏ. Mệnh đề cuối cùng trong khối Tarjan-ian if-else
phải luôn chứa →
toán tử mũi tên ( ). Như vậy, không có else
ngôn ngữ của Tarjan, chỉ else if
. Điều gần nhất với một else
-block trong ngôn ngữ của Tarjan là tạo điều kiện kiểm tra đúng nhất true
.
if a = 4 → x := 9 | a > 4 → y := 11 | true → z := 99 fi
Trong C / Java, chúng ta sẽ có:
if (a == 4) {
x = 9
}
else if (a > 4) {
y = 11
}
else { // else if (true)
z = 99
}
Các ví dụ dễ hiểu hơn các mô tả chung. Tuy nhiên, bây giờ chúng tôi có một số ví dụ trong vành đai của mình, hãy biết rằng hình thức chung của cấu trúc if-other của Tarjan như sau:
if condition
→ stuff to do
| condition
→ stuff to do
[...]
| condition
→ stuff to do
fi
Nhân vật |
giống nhưif else
Nhân vật →
tách điều kiện kiểm tra ra khỏi công cụ cần làm.
(4) Toán tử chuyển nhượng có điều kiện của Tarjan := if
Tarjan if
có thể được sử dụng theo hai cách rất khác nhau. Cho đến nay, chúng tôi chỉ mô tả một trong những cách sử dụng Tarjanian if
. Hơi khó hiểu, Tarjan vẫn sử dụng ký hiệu / cú pháp if
cho loại if
-construct thứ hai . Mà if
đang được sử dụng là dựa trên bối cảnh. Phân tích bối cảnh thực sự rất dễ thực hiện vì loại Tarjan thứ hai - if
luôn được cố định trước bởi một toán tử gán.
Ví dụ: chúng tôi có thể có mã Tarjan sau:
# Example Three
x := if a = 4 → 9 fi
Bắt đầu tiêu hóa
Sau khi làm việc với mã Tarjan một lúc, bạn sẽ quen với thứ tự các thao tác. Nếu chúng ta ngoặc đơn điều kiện kiểm tra trong ví dụ trên, chúng ta có được:
x := if (a = 4) → 9 fi
a = 4
không phải là một hoạt động chuyển nhượng. a = 4
giống như a == 4
- nó trả về đúng hay sai.
Kết thúc tiêu hóa
Nó có thể giúp nghĩ về := if
cú pháp cho một toán tử đơn lẻ, khác với :=
và trên if
thực tế, chúng ta sẽ gọi := if
toán tử là toán tử "gán điều kiện".
Đối với if
chúng tôi liệt kê (condition → action)
. Đối với := if
chúng tôi liệt kê (condition → value)
đâu value
là giá trị phía bên phải, chúng tôi có thể gán cho phía bên tráilhs
# Tarjan Example Four
lhs := if (a = 4) → rhs fi
trong C hoặc Java có thể trông giống như:
# Example Four
if (a == 4) {
lhs = rhs
}
Hãy xem xét ví dụ sau về "gán điều kiện" trong mã Tarjanian:
# Khởi tạo Tarjan của ví dụ Năm x: = a = 4 → 9 | a> 4 → 11 | đúng → 99 fi
Trong C / Java, chúng ta sẽ có:
// C/Java Instantiation of Example Five
if (a == 4) {
x = 9
}
else if (a > 4) {
x = 11
}
else if (true) { // else
x = 99
}
(5) Tóm tắt về các nhà khai thác:
Cho đến nay, chúng ta có:
:=
...... Toán tử gán (C / Java =
)
=
...... Kiểm tra tính bằng (C / Java ==
)
→
...... Phân cách giữa điều kiện kiểm tra của khối if và thân khối if
|
..... C / Java khác-nếu
if ... fi
..... khối if-other
:= if... fi
..... Phân công có điều kiện dựa trên khối if-other
(5.5) Danh sách / Mảng Tarjan:
Ngôn ngữ của Tarjan có các thùng chứa giống như mảng. Cú pháp cho mảng Tarjan trực quan hơn nhiều so với ký hiệu cho các if else
câu lệnh Tarjan .
list1 := ['lion', 'witch', 'wardrobe'];
list2a := [1, 2, 3, 4, 5];
list2b := [1, 2];
list3 := ["a", "b", "c", "d"];
list4 := [ ]; # an empty array
Phần tử mảng Tarjan được truy cập bằng dấu ngoặc đơn ()
, không phải dấu ngoặc vuông[]
Lập chỉ mục bắt đầu lúc 1
. Như vậy
list3 := ["a", "b", "c", "d"]
# list3(1) == "a" returns true
# list3(2) == "b" return true
Dưới đây cho thấy cách tạo một mảng mới chứa các phần tử thứ 1 và thứ 5 của [1, 2, 3, 4, 5, 6, 7]
nums := [1, 2, 3, 4, 5, 6, 7]
new_arr := [nums(1), nums(5)]
Toán tử đẳng thức được định nghĩa cho mảng. Các đoạn mã sau intrue
x := false
if [1, 2] = [1, 2, 3, 4, 5] --> x := true
print(x)
Cách của Tarjan để kiểm tra xem một mảng có trống hay không là so sánh nó với một mảng trống
arr := [1, 2]
print(arr = [ ])
# `=` is equality test, not assignment
Người ta có thể tạo một khung nhìn (không sao chép) của một mảng con, bằng cách cung cấp nhiều chỉ mục cho toán tử ()
kết hợp với..
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) Ví dụ bổ sung về Tarjan's if
và:= if
Sau đây là một ví dụ khác về phép gán điều kiện Tarjan ( := if
):
# Tarjan Example Six
a := (false --> a | true --> b | false --> c1 + c2 | (2 + 3 < 99) --> d)
(true --> b)
là (cond --> action)
mệnh đề ngoài cùng bên trái có một điều kiện đúng. Do đó, phép gán ban đầu Ví dụ Six có hành vi gán giống nhưa := b
Dưới đây là ví dụ phức tạp nhất của chúng tôi về mã Tarjan cho đến nay:
# 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;
Sau đây là bản dịch mã của Tarjan để hợp nhất hai danh sách được sắp xếp. Dưới đây không chính xác là C hoặc Java, nhưng nó gần với C / Java hơn nhiều so với phiên bản 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..]);
}
}
Dưới đây là một ví dụ khác về mã Tarjan và bản dịch trong một cái gì đó tương tự như C hoặ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;
Dưới đây là bản dịch 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) Toán tử mũi tên nhọn của Tarjan ( <-->
)
Dưới đây là một ví dụ về mã Tarjan:
x <--> y
⟷
Toán tử mũi tên kép ( ) làm gì trong ngôn ngữ của Tarjan?
Chà, hầu như tất cả các biến trong Ngôn ngữ của Tarjan đều là con trỏ.
<-->
là một hoạt động trao đổi. Các bản in sautrue
x_old := x
y_old := y
x <--> y
print(x == y_old) # prints true
print(y == x_old) # prints true
Sau khi thực hiện x <--> y
, x
trỏ đến đối tượng y
được sử dụng để trỏ đến và y
trỏ đến đối tượng x
được sử dụng để trỏ đến.
Dưới đây là một tuyên bố Tarjan bằng cách sử dụng <-->
toán tử:
x := [1, 2, 3]
y := [4, 5, 6]
x <--> y
Dưới đây là bản dịch từ mã Tarjan ở trên sang mã giả thay thế:
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;
Ngoài ra, chúng ta có thể có:
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;
}
Dưới đây là một ví dụ về một trong các chức năng của Tarjan khi sử dụng ⟷
toán tử:
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;
Dưới đây là bản dịch mesh
chức năng của Tarjan sang mã giả không phải là C, nhưng trông giống C hơn (nói tương đối). Mục đích của việc này là để minh họa cách thức ⟷
hoạt động của nhà điều hành 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) Các vòng lặp của Tarjan giống như các vòng lặp C / Java
Ngôn ngữ if
và for
cấu trúc của Tarjan quen thuộc với các lập trình viên C / Java. Tuy nhiên, từ khóa Tarjan cho một vòng lặp while là do
. Tất cả các do
từ kết thúc bằng từ khóa od
, đó là cách viết ngược do
. Dưới đây là một ví dụ:
sum := 0
do sum < 50 → sum := sum + 1
Trong mã giả kiểu C, chúng ta có:
sum = 0;
while(sum < 50) {
sum = sum + 1;
}
Trên đây thực sự không hoàn toàn đúng. Một vòng lặp do Tarjan thực sự là một C / Java while(true)
với một khối if-if được lồng bên trong. Một bản dịch chính xác hơn của mã Tarjan như sau:
sum = 0;
while(true) {
if (sum < 50) {
sum = sum + 1;
continue;
// This `continue` statement is questionable
}
break;
}
Dưới đây, chúng ta có một Tarjan -loop phức tạp hơn do
:
sum := 0
do sum < 50 → sum := sum + 1 | sum < 99 → sum := sum + 5
Mã giả kiểu C / Java cho Tarjan -loop phức tạp do
như sau:
sum = 0;
while(true) {
if (sum < 50) {
sum = sum + 1;
continue;
}
else if (sum < 99) {
sum = sum + 5;
continue;
}
break;
}
(9) Toán tử gán điều kiện của Tarjan với tất cả các điều kiện sai
Mặc dù lời giải thích dài dòng ở trên bao gồm hầu hết mọi thứ, một vài vấn đề vẫn chưa được giải quyết. Tôi hy vọng rằng một ngày nào đó người khác sẽ viết một câu trả lời được cải tiến mới dựa trên câu trả lời của tôi.
Đáng chú ý, khi toán tử gán điều kiện := if
được sử dụng và không có điều kiện nào đúng, tôi không phải là giá trị nào được gán cho biến.
x := if (False --> 1| False --> 2 | (99 < 2) --> 3) fi
Tôi không chắc chắn, nhưng có thể là không có nhiệm vụ nào được thực hiện để x
:
x = 0;
if (false) {
x = 1;
}
else if (false) {
x = 2;
}
else if (99 < 2) {
x = 3;
}
// At this point (x == 0)
Bạn có thể yêu cầu biến bên trái nhìn thấy trong := if
câu lệnh phải được khai báo trước đó. Trong trường hợp đó, ngay cả khi tất cả các điều kiện là sai, biến vẫn sẽ có giá trị.
Ngoài ra, có lẽ tất cả các điều kiện sai thể hiện lỗi thời gian chạy. Một cách khác là trả về một null
giá trị đặc biệt và lưu trữ null
trong đối số bên trái của bài tập.