目录
我将对Tarjan伪代码的解释分为以下几部分:
- Tarjan的If-else块(
->
&|
运算符)
- 分配和平等测试(
:=
和=
)
- 有
else if
,但没有else
构造
- Tarjan的条件赋值运算符
:= if
Tarjan if
和:= if
5.5的其他示例。
Tarjan阵列(或列表)
运营商摘要
- Tarjan的双指向箭头运算符(
⟷
)
- Tarjan的do循环就像C / Java while循环
- Tarjan的条件赋值运算符具有所有错误条件
(1)塔里安的If-else积木
(运营商→
和|
)
该if-else
构造可能是Tarjan语言中最基本的控制结构。除了类似C的if块,Tarjan的赋值和Tarjan的while循环几乎都内置了if-else行为。Tarjan的箭头运算符->
(或→)是if语句的条件与if语句的执行块之间的分隔符。
例如,用塔里安的语言,我们可能有:
# Example One
if a = 4 → x := 9 fi
如果我们将上面的Tarjan代码行部分转换为C或Java,则会得到以下结果:
if (a = 4)
x := 9
fi
Tarjan代替了右花括号(如C和Java中的花括号),以-block结尾if
,其关键字类似于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中的关键字。
例如,用塔里安的语言,我们可能有:
# 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
没有描述细微差别,而是介绍了- 语句的基础。但是,我们不会讨论一个小细节。Tarjan-ian if-else
块中的最后一个子句必须始终包含arrow(→
)运算符。因此else
,只有Tarjan语言没有else if
。else
用Tarjan的语言最接近-block的是使最右边的test-condition 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
}
实例比一般说明更容易理解。但是,现在我们有了一些示例,可以知道,Tarjan的if-else构造的一般形式如下:
if condition
→ stuff to do
| condition
→ stuff to do
[...]
| condition
→ stuff to do
fi
人物 |
就像if else
角色→
将测试条件与待办事项分开。
(4)塔里安的条件赋值运算符 := if
if
可以使用两种非常不同的方式来使用Tarjan 。到目前为止,我们仅描述了Tarjanian的用途之一if
。令人困惑的是,Tarjan仍然if
对第二种类型的if
-construct 使用符号/语法。使用哪个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
-它返回true或false。
终点离题
可以将其:= 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代码中的“条件赋值”示例:
#示例5的Tarjan实例化x:= a = 4→9 | a> 4→11 | 真实→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块的测试条件与if块的主体之间的分隔符
|
..... C / Java else-if
if ... fi
..... if-else块
:= if... fi
.....基于if-else块的条件赋值
(5.5)Tarjan列表/数组:
Tarjan的语言具有内置的数组式容器。Tarjan数组的语法比Tarjan if else
语句的符号直观得多。
list1 := ['lion', 'witch', 'wardrobe'];
list2a := [1, 2, 3, 4, 5];
list2b := [1, 2];
list3 := ["a", "b", "c", "d"];
list4 := [ ]; # an empty array
Tarjan数组elementa用括号()
而不是方括号括起来[]
索引从开始1
。从而,
list3 := ["a", "b", "c", "d"]
# list3(1) == "a" returns true
# list3(2) == "b" return true
下面显示了如何创建一个新数组,其中包含第一个元素和第五个元素 [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,但与Tarjan版本相比,它更接近C / Java。
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代码的另一个示例,以及类似于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
双箭头(⟷
)运算符用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代码到其他伪代码的转换:
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;
下面是将Tarjan mesh
函数转换为伪代码的伪代码,该伪代码不是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)Tarjan的do循环就像C / Java while循环
Tarjan的语言if
和for
构造对于C / Java程序员是熟悉的。但是,while循环的Tarjan关键字是do
。全do
循环以关键字结尾,该关键字od
是的反向拼写do
。下面是一个示例:
sum := 0
do sum < 50 → sum := sum + 1
在C风格的伪代码中,我们有:
sum = 0;
while(sum < 50) {
sum = sum + 1;
}
以上实际上是不正确的。Tarjan do-loop实际上是while(true)
一个内部嵌套有if-else块的C / Java 。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
复杂的Tarjan do
-loop的C / Java风格伪代码如下:
sum = 0;
while(true) {
if (sum < 50) {
sum = sum + 1;
continue;
}
else if (sum < 99) {
sum = sum + 5;
continue;
}
break;
}
(9)具有所有错误条件的塔里安的条件赋值运算符
尽管上面冗长的解释涵盖了大多数问题,但仍有一些问题尚未解决。我希望其他人有一天会根据我的回答写出这些改进后的答案。
值得注意的是,当使用条件赋值运算符:= 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
在赋值的左侧参数中。