Takið upphaflega RPN forritið sem var sýnt í fyrirlestri og breytið því á eftirfarandi hátt.
Aðgerðir eiga að vera strengir ("+", "*", "p") en ekki bókstafir ('+', '*', 'p'). Það á að vera hægt að bæta inn aðgerð sem inniheldur fleiri en einn bókstaf, t.d. "drop". Gerið tilheyrandi breytingar á struct operation, operations og eval_op.
Bætið við nýrri skipun "drop" sem fleygir burt efsta stakinu af hlaðanum.
Bætið við nýrri skipun "dup" sem tekur efsta stakið á hlaðanum og setur það tvisvar á hlaðann (duplicate top value).
Bætið við nýrri skipun "swap" sem víxlar tveimur efstu stökunum á hlaðanum.
#include <stdio.h> #include <stdlib.h> #include <string.h> #include "stack.h" const char delim[] = " \n"; static int is_number(char *s) { return strspn(s, "1234567890") == strlen(s); } static void eval_plus(struct stack *s) { int a, b; a = stack_pop(s); b = stack_pop(s); stack_push(s, a + b); } static void eval_multiply(struct stack *s) { int a, b; a = stack_pop(s); b = stack_pop(s); stack_push(s, a * b); } static void eval_drop(struct stack *s) { stack_pop(s); } static void eval_dup(struct stack *s) { int v = stack_pop(s); stack_push(s, v); stack_push(s, v); } static void eval_swap(struct stack *s) { int a, b; a = stack_pop(s); b = stack_pop(s); stack_push(s, a); stack_push(s, b); } struct operation { char *op; int minargs; void (*eval)(struct stack *s); }; static struct operation operations[] = { { "+", 2, eval_plus }, { "*", 2, eval_multiply }, { "p", 0, stack_print }, { "drop", 1, eval_drop }, { "dup", 1, eval_dup }, { "swap", 2, eval_swap }, { 0, 0, NULL } }; static void eval_op(struct stack *s, char *token) { struct operation *op; for (op = operations; op->eval; op++) { if (!strcmp(op->op, token)) break; } if (op->eval == NULL) { printf("Unknown operation: %s\n", token); return; } if (stack_count(s) < op->minargs) { printf("Not enough arguments on stack\n"); return; } op->eval(s); } void eval(struct stack *s, char *line) { char *state = line; char *token; token = strtok_r(line, delim, &state); while (token != NULL) { printf("token: %s\n", token); if (is_number(token)) stack_push(s, atoi(token)); else eval_op(s, token); token = strtok_r(NULL, delim, &state); } } int main(void) { char line[1024]; struct stack s; stack_init(&s); while (1) { if (feof(stdin) || ferror(stdin)) break; if (fgets(line, sizeof(line), stdin) == NULL) break; eval(&s, line); } return 0; }
#include <stdio.h> #include <stdlib.h> #include <string.h> #include "stack.h" void stack_init(struct stack *s) { s->top = NULL; s->n = 0; } void stack_push(struct stack *s, int value) { struct item *p = malloc(sizeof(struct item)); p->value = value; p->next = s->top; s->top = p; s->n++; } int stack_pop(struct stack *s) { struct item *p = s->top; int value = p->value; s->top = s->top->next; s->n--; free(p); return value; } int stack_empty(struct stack *s) { return s->top == NULL; } int stack_count(struct stack *s) { return s->n; } void stack_print(struct stack *s) { struct item *p = s->top; printf("Stack (from top to bottom):\n"); while (p != NULL) { printf(" [%d]\n", p->value); p = p->next; } } int stack_top(struct stack *s) { return s->top->value; }
#ifndef _STACK_H #define _STACK_H struct item { int value; struct item *next; }; struct stack { struct item *top; int n; }; extern void stack_init(struct stack *s); extern void stack_push(struct stack *s, int value); extern int stack_empty(struct stack *s); extern int stack_count(struct stack *s); extern void stack_print(struct stack *s); extern int stack_pop(struct stack *s); extern int stack_top(struct stack *s); #endif
Leysið dæmi 1.3.4 í bókinni í Java. Notið Stack klasann úr fyrirlestri.
Write a stack client Parentheses in Java that reads in a text stream from standard input and uses a stack to determine whether its parentheses are properly balanced. For example, your program should print true for [()]{}{[()()]()} and false for [(]).
[()]{}{[()()]()} [(])
true false
import java.util.Scanner; public class Parentheses { private static char flip(char c) { switch (c) { case ')': return '('; case '}': return '{'; case ']': return '['; } return '?'; } public static boolean balanced(String line) { Stack<Character> s = new Stack<Character>(); for (int i = 0; i < line.length(); i++) { char c = line.charAt(i); if (c == '(' || c == '{' || c == '[') { s.push(c); continue; } if (s.empty()) return false; char top = s.pop(); if (top != flip(c)) return false; } return true; } public static void main(String[] args) { Scanner s = new Scanner(System.in); while (s.hasNext()) { String line = s.nextLine(); if (balanced(line)) System.out.println("true"); else System.out.println("false"); } } }
Takið upphaflega RPN forritið (rpn.zip) sem var sýnt í fyrirlestri og forritið hliðstæða útgáfu í Java. Forritið á að hegða sér nákvæmlega eins og C forritið. Notandi forritsins ætti ekki að geta sagt til um hvort forritið hann er að keyra.
2 token: 2 3 token: 3 4 token: 4 5 token: 5 p token: p Stack (from top to bottom): [5] [4] [3] [2] + token: + * token: * + token: + p token: p Stack (from top to bottom): [29]
import java.util.Scanner; public class RPN { private static boolean isNumeric(String w) { try { Integer.parseInt(w); } catch (NumberFormatException e) { return false; } return true; } public static void main(String[] args) { Stack<Integer> s = new Stack<Integer>(); Scanner scan = new Scanner(System.in); while (scan.hasNext()) { String w = scan.next(); System.out.printf("token: %s\n", w); if (isNumeric(w)) { s.push(Integer.parseInt(w)); continue; } if (w.equals("+")) { if (s.count() < 2) { System.out.println("Not enough arguments on stack"); continue; } s.push(s.pop() + s.pop()); } else if (w.equals("*")) { if (s.count() < 2) { System.out.println("Not enough arguments on stack"); continue; } s.push(s.pop() * s.pop()); } else if (w.equals("p")) { System.out.println("Stack (from top to bottom)"); s.print(); } else { System.out.printf("Unknown operation: %s\n", w); } } } }
public class Stack<T> { class Node { T value; Node next; }; private Node top; private int n; Stack() { top = null; n = 0; } public void push(T value) { Node x = new Node(); x.value = value; x.next = top; top = x; n++; } public T pop() { T x = top.value; top = top.next; n--; return x; } public T peek() { return top.value; } public boolean empty() { return top == null; } public void print() { Node p = top; while (p != null) { System.out.printf(" [%s]\n", p.value); p = p.next; } } public int count() { return n; } public static void main(String[] args) { Stack<String> s = new Stack<String>(); s.push("A"); s.push("B"); s.push("C"); while (!s.empty()) System.out.println(s.pop()); } }
Klárið útfærslu af walktree fallinu í beinagrindinni. Fallið tekur inn skrá/möppu (File object) og FileVisitor hlut. Fallið gengur yfir allar skrár og möppur sem liggja undir slóðinni og fyrir hverja skrá/möppu þá er kallað á visit í FileVisitor.
Forritið á að nota hlaða, sem fylgir með beinagrindinni. Forritið tekur næstu skrá af hlaðanum, kallar á FileVisitor og síðan kallar það á listFiles á viðkomandi skrá, sem sækir allar undirskrár/undirmöppur, og setur allar undirskrár/undirmöppur á hlaðann.
import java.io.File; interface FileVisitor { void visit(File file); } public class Walker { static class PrintFile implements FileVisitor { public void visit(File file) { if (file.isDirectory()) System.out.printf("D %s\n", file.getAbsolutePath()); else System.out.printf("F %s (%d bytes)\n", file.getAbsolutePath(), file.length()); } } public static void walktree(File root, FileVisitor visitor) { Stack<File> s = new Stack<File>(); s.push(root); while (!s.empty()) { File f = s.pop(); visitor.visit(f); File[] files = f.listFiles(); if (files == null) continue; for (File cf : files) s.push(cf); } } public static void main(String[] args) { if (args.length < 1) { System.err.println("usage: java Walker <path>"); return; } File root = new File(args[0]); walktree(root, new PrintFile()); } }
public class Stack<T> { class Node { T value; Node next; }; private Node top; private int n; Stack() { top = null; n = 0; } public void push(T value) { Node x = new Node(); x.value = value; x.next = top; top = x; n++; } public T pop() { T x = top.value; top = top.next; n--; return x; } public T peek() { return top.value; } public boolean empty() { return top == null; } public int count() { return n; } public static void main(String[] args) { Stack<String> s = new Stack<String>(); s.push("A"); s.push("B"); s.push("C"); while (!s.empty()) System.out.println(s.pop()); } }