Рассматривается работа с контейнерными классами в abc.net
Содержание:
Стек / Stack
Push(x: T);
Pop: T;
Peek: T;
-
Clear;
property Count: integer;
Очередь / Queue
Enqueue(x: T);
Dequeue: T;
Peek: T;
Clear;
property Count: integer;
Список / List
Contains(x: T): boolean;
IndexOf(x: T): integer;
LastIndexOf(x: T): integer;
Find(pred: T -> boolean): T;
FindIndex(pred: T -> boolean): integer;
FindAll(pred: T -> boolean): List
; ForEach(act: T -> ());
TrueForAll(pred: T -> boolean): boolean;
Reverse;
Reverse(from,count: integer);
Sort;
Clear;
Add(x: T);
AddRange(seq: sequence of T);
Remove(x: T): boolean;
RemoveAll(pred: T -> boolean): integer;
RemoveAt(ind: integer);
RemoveRange(ind,count: integer);
Insert(ind: integer; x: T);
InsertRange(ind: integer; seq: sequence of T);
property Count: integer;
property Capacity: integer;
Словари / Dictionary
Dictionary
Add(k: Key; v: Value);
Remove(k: Key): boolean;
ContainsKey(k: Key): boolean;
ContainsValue(v: Value): boolean;
TryGetValue(k: Key; var v: Value): boolean;
Clear;
property Count: integer;
Пример 1:
begin var graph := Dict(('Rostov',Dict(KV('Moscow',1000),KV('Bataisk',10))), ('Moscow',Dict(KV('Rostov',1000))), ('Bataisk',Dict(KV('Rostov',10))) ); graph.Println(NewLine); graph['Rostov']['Moscow'] := 1100; graph['Moscow']['Rostov'] := 1100; Println; graph.Println(NewLine); end. |
Пример 2:
begin var q := ReadLines('a1.pas').Select(s->s.Matches('\w+')).SelectMany(x->x) .Select(x->x.Value); var d := new Dictionary<string,integer>; foreach var x in q do if d.ContainsKey(x) then d[x] := d[x] + 1 else d[x] := 1; d.OrderByDescending(x->x.Value).Take(10).Print(NewLine); end. |
Данный пример может быть решен более коротким способом, используя d.Get
, которая возвращает либо значение, соответствующее ключу, либо 0 если ключа нет:
begin var q := ReadLines('FreqFile.pas').Select(s->s.Matches('\w+')).SelectMany(x->x) .Select(x->x.Value); var d := new Dictionary<string,integer>; foreach var x in q do d[x] := d.Get(x) + 1; d.OrderByDescending(x->x.Value).Take(10).Print(NewLine); end. |
Результат:
(x,9)
(d,4)
(var,3)
(q,2)
(Select,2)
(s,2)
(Value,2)
(begin,1)
(ReadLines,1)
(FreqFile,1)
(d,4)
(var,3)
(q,2)
(Select,2)
(s,2)
(Value,2)
(begin,1)
(ReadLines,1)
(FreqFile,1)
Источником строк может быть файл, находящийся в интернете:
begin var w := new System.Net.WebClient(); var ss := w.DownloadString('http://vojnaimir.ru/files/book1.txt'); var q := ss.MatchValues('\w+'); var d := new Dictionary<string,integer>; foreach var x in q do d[x] := d.Get(x) + 1; d.OrderByDescending(x->x.Value).Take(20).Print(NewLine); end. |
Результат:
(и,10137)
(в,4863)
(не,4221)
(что,3652)
(на,3200)
(с,3025)
(он,3017)
(как,1913)
(его,1876)
(к,1778)
(то,1606)
(я,1354)
(она,1195)
(сказал,1145)
(было,1137)
(это,1030)
(за,961)
(так,952)
(но,949)
(ее,897)
(в,4863)
(не,4221)
(что,3652)
(на,3200)
(с,3025)
(он,3017)
(как,1913)
(его,1876)
(к,1778)
(то,1606)
(я,1354)
(она,1195)
(сказал,1145)
(было,1137)
(это,1030)
(за,961)
(так,952)
(но,949)
(ее,897)
Если необходимо взять только собственные имена, то следует использовать фильтр: слово с большой буквы и длины не менее 4:
var q := ss.MatchValues('\w+').Where(s->s[1].IsUpper and (s.Length>3)); |
HashSet, SortedSet
Add(x: T): boolean;
Remove(x: T): boolean;
Contains(x: T): boolean;
LinkedListNode
property Next: LinkedListNode
read; property Prev: LinkedListNode
read; property Value: T read write;
LinkedList
Contains(x: T): boolean;
Find(x: T): LinkedListNode
; FindLast(x: T): LinkedListNode
; -
AddFirst(x: T);
AddLast(x: T);
AddAfter(n: LinkedListNode
; x: T); AddBefore(n: LinkedListNode
; x: T); Clear;
Remove(LinkedListNode
); RemoveFirst;
RemoveLast;
property Count: integer;
property First: LinkedListNode
; property Last: LinkedListNode
;
Решение задач
Пример: Задана строка с арифметическим выражением. Определить правильность расстановки скобок ( может встречаться
()
, []
, {}
).Решение:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | begin var ss: string; {ss := '{vbsdf[fsdfdff]aa';} ss := '{df{ff{df}aa'; var st := new stack<char>; var res := true; for var i := 1 to ss.Length do begin case ss[i] of '(': st.Push(ss[i]); ')': if (st.Count = 0) or (st.Pop <> '(') then begin res := false; break; end; '[': st.Push(ss[i]); ']': if (st.Count = 0) or (st.Pop <> '[') then begin res := false; break; end; '{': st.Push(ss[i]); '}': if (st.Count = 0) or (st.Pop <> '{') then begin res := false; break; end; end; end; if st.Count <> 0 then res:=false; if res = true then println('ok') else println('NOT RIGHT'); end. |
Пример: Дана корректная запись арифметического выражения в форме обратной польской записи. Вычислить выражение, используя стек. (ОПН — форма записи математических и логических выражений, в которой операнды расположены перед знаками операций)
7 2 3 * -
эквивалентно 7-2*3
1 2 + 4 × 3 +
эквивалентно (1 + 2) х 4 + 3
Выполнение:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | begin var st:=new stack <integer>; var ss:='2 3 + 5 7 + /'; var s:=ss.ToWords; foreach var x in s do begin case x[1] of '0'..'9':st.push(x.ToInteger); '+': st.push(st.pop+st.pop); '*':st.push(st.pop*st.pop); '-':st.push(st.pop-st.pop); '/':st.push(st.pop div st.pop); end; end; println(st.pop); assert(st.count=0); end. |