Оглавление
Я разделю свое объяснение псевдокода Тарьяна на следующие разделы:
- Блоки Тарьяна If-else ( операторы
->
& |
)
- Тесты по назначению и равенству (
:=
и =
)
- Есть
else if
, но нет else
конструкции
- Оператор условного присвоения Тарьяна
:= if
Дополнительные примеры Тарьяна if
и:= if
5.5.
Тарьяновые массивы (или списки)
Резюме операторов
- Оператор двухконечной стрелки Тарьяна (
⟷
)
- Do-циклы Тарьяна похожи на циклы while C / Java
- Оператор условного присваивания Тарьяна со всеми ложными условиями
(1) Блоки Тарьяна, если бы еще
(операторы →
а |
)
if-else
Конструкция является , пожалуй, наиболее фундаментальной структурой управления на языке Tarján в. В дополнение к C-подобным if-блокам, поведение if-else очень близко встроено в назначения Тарьяна и циклы while. Оператор стрелки Тарьяна ->
(или →) является разделителем между условием оператора if и блоком выполнения оператора if.
Например, на языке Тарьяна мы можем иметь:
# Example One
if a = 4 → x := 9 fi
Если мы частично переведем приведенную выше строку кода Тарьяна в C или Java, мы получим следующее:
if (a = 4)
x := 9
fi
Вместо правильных фигурных скобок (как в C и Java) Тарьян оканчивает if
-блок с помощью слов на английском языке в стиле АЛГОЛ:fi
Если мы продолжим перевод нашего примера выше, мы получим:
if (a = 4) {
x := 9
}
(2) Тесты на присвоение и равенство ( :=
и =
)
Тарьян берет эти операторы из ALGOL (позже это также можно увидеть в Pascal).
Тарьян использует =
для тестов на равенство, а не для заданий (поэтому он работает как Java ==
).
Для назначения Тарьян использует :=
, который работает как Java =
.
Таким образом, если мы продолжим перевод нашего примера, мы получим:
if (a == 4) {
x = 9
}
Вертикальная черта (или «труба» или |
) на языке Тарьяна эквивалентна else if
ключевому слову в Си или 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
-слов без описания нюансов. Однако мы не будем обсуждать мелкие детали. Последнее предложение в if-else
блоке Tarjan-ian всегда должно содержать оператор arrow ( →
). Таким образом, нет только else
на языке Тарьяна else if
. Самым близким к else
-блоку в языке Тарьяна является создание самого правильного условия теста 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 выглядит следующим образом:
if condition
→ stuff to do
| condition
→ stuff to do
[...]
| condition
→ stuff to do
fi
Персонаж |
какif else
Символ →
отделяет тестовое условие от материала для дел.
(4) Оператор условного присвоения Тарьяна := if
Тарьяна if
можно использовать двумя совершенно разными способами. До сих пор мы описали только одно из применений тарджанцев if
. Несколько запутанно, но Тарьян все еще использует нотацию / синтаксис if
для второго типа if
-construct. То if
, что используется, основано на контексте. Анализ контекста на самом деле очень прост, поскольку второй тип таржана if
всегда предопределен оператором присваивания.
Например, у нас может быть следующий код Тарьяна:
# Example Three
x := if a = 4 → 9 fi
Начните отступление
Поработав некоторое время с кодом Тарьяна, вы привыкаете к порядку операций. Если мы заключим условие проверки в скобки в приведенном выше примере, мы получим:
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
}
Рассмотрим следующий пример «условного присваивания» в коде Тарьяна:
# Тарьян Пример пятого примера x: = a = 4 → 9 | a> 4 → 11 | правда → 99 фи
В 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 еще-если
if ... fi
..... блок if-else
:= if... fi
..... Условное присвоение на основе блока if-else
(5.5) Тарьянские списки / массивы:
Язык Тарьяна имеет встроенные контейнеры, похожие на массивы. Синтаксис для массивов Тарьяна намного более интуитивен, чем запись для if else
операторов Тарьяна .
list1 := ['lion', 'witch', 'wardrobe'];
list2a := [1, 2, 3, 4, 5];
list2b := [1, 2];
list3 := ["a", "b", "c", "d"];
list4 := [ ]; # an empty array
Доступ к элементам массива Тарьяна осуществляется с помощью круглых скобок ()
, а не квадратных скобок[]
Индексирование начинается с 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)
Тарьян может проверить, является ли массив пустым, - сравнить его с пустым массивом.
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) Дополнительные примеры Тарьяна if
и:= if
Ниже приведены другие примеры условного присваивания Тарьяна ( := if
):
# Tarjan Example Six
a := (false --> a | true --> b | false --> c1 + c2 | (2 + 3 < 99) --> d)
(true --> b)
самый левый (cond --> action)
пункт, имеющий истинное условие. Таким образом, исходный пример шестого присваивания имеет то же поведение присваивания, что иa := b
Ниже приведен наш самый сложный пример кода Тарьяна:
# 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;
Ниже приведен перевод кода Тарьяна для объединения двух отсортированных списков. Следующее не совсем 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 и перевода в нечто похожее на 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) Оператор двухконечной стрелы Тарьяна (<-->
)
Ниже приведен пример кода Тарьяна:
x <--> y
Что делает оператор Double Arrow ( ⟷
) на языке Тарьяна?
Ну, почти все переменные в языке Тарьяна являются указателями.
<-->
это операция обмена Следующие принты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
Ниже приведен перевод кода Тарьяна выше в альтернативный псевдокод:
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;
}
Ниже приведен пример одной из функций Тарьяна с использованием ⟷
оператора:
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
в псевдокод, который не является C, но больше похож на C (условно говоря). Цель этого - показать, как работает ⟷
оператор Тарьян .
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-циклы Тарьяна похожи на циклы while C / Java
Язык if
и for
конструкции Тарьяна знакомы программистам C / Java. Однако ключевое слово Tarjan для цикла while - это do
. Все do
-loops заканчиваются ключевым словом od
, которое является обратным написанием do
. Ниже приведен пример:
sum := 0
do sum < 50 → sum := sum + 1
В псевдокоде в стиле C мы имеем:
sum = 0;
while(sum < 50) {
sum = sum + 1;
}
Вышесказанное на самом деле не совсем верно. Do-цикл Tarjan - это действительно C / Java while(true)
с вложенным в него блоком if-else. Более буквальный перевод кода Тарьяна выглядит следующим образом:
sum = 0;
while(true) {
if (sum < 50) {
sum = sum + 1;
continue;
// This `continue` statement is questionable
}
break;
}
Ниже у нас есть более сложный Tarjan- do
цикл:
sum := 0
do sum < 50 → sum := sum + 1 | sum < 99 → sum := sum + 5
Псевдокод в стиле C / Java для сложного do
цикла Tarjan выглядит следующим образом:
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
в левом аргументе присваивания.