Java Visitor Pattern

Sort by

recency

|

195 Discussions

|

  • + 0 comments

    I don't get it are this clases provided? or do we have to implement them? abstract class Tree class TreeNode extends Tree class TreeLeaf extends Tree abstract class TreeVis

    because the compiler is not able to find the but the text says: "A Tree class implementing a rooted tree is provided in the editor"

  • + 0 comments
    
    

    import java.io.; import java.util.;

    enum Color { RED, GREEN }

    abstract class Tree { private int value; private Color color; private int depth;

    public Tree(int value, Color color, int depth) {
        this.value = value;
        this.color = color;
        this.depth = depth;
    }
    
    public int getValue() {
        return value;
    }
    
    public Color getColor() {
        return color;
    }
    
    public int getDepth() {
        return depth;
    }
    
    public abstract void accept(TreeVis visitor);
    

    }

    class TreeNode extends Tree { private final List children = new ArrayList<>();

    public TreeNode(int value, Color color, int depth) {
        super(value, color, depth);
    }
    
    public void accept(TreeVis visitor) {
        visitor.visitNode(this);
        for (Tree child : children) {
            child.accept(visitor);
        }
    }
    
    public void addChild(Tree child) {
        children.add(child);
    }
    

    }

    class TreeLeaf extends Tree { public TreeLeaf(int value, Color color, int depth) { super(value, color, depth); }

    public void accept(TreeVis visitor) {
        visitor.visitLeaf(this);
    }
    

    }

    abstract class TreeVis { public abstract int getResult(); public abstract void visitNode(TreeNode node); public abstract void visitLeaf(TreeLeaf leaf); }

    // Visitor 1: Sum of all leaf values class SumInLeavesVisitor extends TreeVis { private int sum = 0;

    public int getResult() {
        return sum;
    }
    
    public void visitNode(TreeNode node) {}
    
    public void visitLeaf(TreeLeaf leaf) {
        sum += leaf.getValue();
    }
    

    }

    // Visitor 2: Product of red node values class ProductOfRedNodesVisitor extends TreeVis { private long product = 1; private final int MOD = 1_000_000_007;

    public int getResult() {
        return (int) product;
    }
    
    public void visitNode(TreeNode node) {
        if (node.getColor() == Color.RED) {
            product = (product * node.getValue()) % MOD;
        }
    }
    
    public void visitLeaf(TreeLeaf leaf) {
        if (leaf.getColor() == Color.RED) {
            product = (product * leaf.getValue()) % MOD;
        }
    }
    

    }

    // Visitor 3: Difference between even depth node sum and green leaf sum class FancyVisitor extends TreeVis { private int sumEvenDepthNonLeaf = 0; private int sumGreenLeaf = 0;

    public int getResult() {
        return Math.abs(sumEvenDepthNonLeaf - sumGreenLeaf);
    }
    
    public void visitNode(TreeNode node) {
        if (node.getDepth() % 2 == 0) {
            sumEvenDepthNonLeaf += node.getValue();
        }
    }
    
    public void visitLeaf(TreeLeaf leaf) {
        if (leaf.getColor() == Color.GREEN) {
            sumGreenLeaf += leaf.getValue();
        }
    }
    

    }

    public class Solution {

    private static int[] values;
    private static Color[] colors;
    private static Map<Integer, List<Integer>> treeMap = new HashMap<>();
    
    public static void main(String[] args) {
        Tree root = solve();
    
        TreeVis vis1 = new SumInLeavesVisitor();
        TreeVis vis2 = new ProductOfRedNodesVisitor();
        TreeVis vis3 = new FancyVisitor();
    
        root.accept(vis1);
        root.accept(vis2);
        root.accept(vis3);
    
        System.out.println(vis1.getResult());
        System.out.println(vis2.getResult());
        System.out.println(vis3.getResult());
    }
    
    public static Tree solve() {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
    
        values = new int[n];
        for (int i = 0; i < n; i++) {
            values[i] = sc.nextInt();
        }
    
        colors = new Color[n];
        for (int i = 0; i < n; i++) {
            colors[i] = sc.nextInt() == 0 ? Color.RED : Color.GREEN;
        }
    
        for (int i = 0; i < n - 1; i++) {
            int u = sc.nextInt() - 1;
            int v = sc.nextInt() - 1;
    
            treeMap.computeIfAbsent(u, x -> new ArrayList<>()).add(v);
            treeMap.computeIfAbsent(v, x -> new ArrayList<>()).add(u);
        }
    
        return buildTree(0, 0, -1);
    }
    
    private static Tree buildTree(int node, int depth, int parent) {
        List<Integer> children = treeMap.getOrDefault(node, new ArrayList<>());
        children.remove((Integer) parent);
    
        if (children.isEmpty()) {
            return new TreeLeaf(values[node], colors[node], depth);
        } else {
            TreeNode treeNode = new TreeNode(values[node], colors[node], depth);
            for (int child : children) {
                treeNode.addChild(buildTree(child, depth + 1, node));
            }
            return treeNode;
        }
    }
    

    }

    
    
  • + 0 comments

    java8 working f9- import java.util.*;

    enum Color { RED, GREEN }

    abstract class Tree { private int value; private Color color; private int depth;

    public Tree(int value, Color color, int depth) {
        this.value = value;
        this.color = color;
        this.depth = depth;
    }
    
    public int getValue() {
        return value;
    }
    
    public Color getColor() {
        return color;
    }
    
    public int getDepth() {
        return depth;
    }
    
    public abstract void accept(TreeVis visitor);
    

    }

    class TreeNode extends Tree { private List children = new ArrayList<>();

    public TreeNode(int value, Color color, int depth) {
        super(value, color, depth);
    }
    
    public void accept(TreeVis visitor) {
        visitor.visitNode(this);
        for (Tree child : children) {
            child.accept(visitor);
        }
    }
    
    public void addChild(Tree child) {
        children.add(child);
    }
    

    }

    class TreeLeaf extends Tree { public TreeLeaf(int value, Color color, int depth) { super(value, color, depth); }

    public void accept(TreeVis visitor) {
        visitor.visitLeaf(this);
    }
    

    }

    abstract class TreeVis { public abstract int getResult(); public abstract void visitNode(TreeNode node); public abstract void visitLeaf(TreeLeaf leaf); }

    class SumInLeavesVisitor extends TreeVis { private int sum = 0;

    public int getResult() {
        return sum;
    }
    
    public void visitNode(TreeNode node) {
        // Do nothing
    }
    
    public void visitLeaf(TreeLeaf leaf) {
        sum += leaf.getValue();
    }
    

    }

    class ProductRedNodesVisitor extends TreeVis { private long product = 1; private final int MOD = 1000000007;

    public int getResult() {
        return (int) product;
    }
    
    public void visitNode(TreeNode node) {
        if (node.getColor() == Color.RED) {
            product = (product * node.getValue()) % MOD;
        }
    }
    
    public void visitLeaf(TreeLeaf leaf) {
        if (leaf.getColor() == Color.RED) {
            product = (product * leaf.getValue()) % MOD;
        }
    }
    

    }

    class FancyVisitor extends TreeVis { private int evenDepthNonLeafSum = 0; private int greenLeafSum = 0;

    public int getResult() {
        return Math.abs(evenDepthNonLeafSum - greenLeafSum);
    }
    
    public void visitNode(TreeNode node) {
        if (node.getDepth() % 2 == 0) {
            evenDepthNonLeafSum += node.getValue();
        }
    }
    
    public void visitLeaf(TreeLeaf leaf) {
        if (leaf.getColor() == Color.GREEN) {
            greenLeafSum += leaf.getValue();
        }
    }
    

    }

    public class Solution { public static Tree solve() { Scanner scan = new Scanner(System.in); int n = scan.nextInt(); int[] values = new int[n]; byte[] colors = new byte[n];

        for (int i = 0; i < n; i++) {
            values[i] = scan.nextInt();
        }
    
        for (int i = 0; i < n; i++) {
            colors[i] = scan.nextByte();
        }
    
        Map<Integer, List<Integer>> adj = new HashMap<>();
        for (int i = 0; i < n; i++) {
            adj.put(i, new ArrayList<>());
        }
    
        for (int i = 0; i < n - 1; i++) {
            int u = scan.nextInt() - 1;
            int v = scan.nextInt() - 1;
            adj.get(u).add(v);
            adj.get(v).add(u);
        }
    
        scan.close();
        boolean[] visited = new boolean[n];
        return buildTree(0, 0, values, colors, adj, visited);
    }
    
    public static Tree buildTree(int index, int depth, int[] values, byte[] colors, Map<Integer, List<Integer>> adj, boolean[] visited) {
        visited[index] = true;
        Color color = colors[index] == 0 ? Color.RED : Color.GREEN;
        List<Integer> children = adj.get(index);
        boolean isLeaf = true;
    
        List<Tree> childTrees = new ArrayList<>();
        for (int child : children) {
            if (!visited[child]) {
                isLeaf = false;
                childTrees.add(buildTree(child, depth + 1, values, colors, adj, visited));
            }
        }
    
        if (isLeaf) {
            return new TreeLeaf(values[index], color, depth);
        } else {
            TreeNode node = new TreeNode(values[index], color, depth);
            for (Tree child : childTrees) {
                node.addChild(child);
            }
            return node;
        }
    }
    
    public static void main(String[] args) {
        Tree root = solve();
    
        SumInLeavesVisitor vis1 = new SumInLeavesVisitor();
        ProductRedNodesVisitor vis2 = new ProductRedNodesVisitor();
        FancyVisitor vis3 = new FancyVisitor();
    
        root.accept(vis1);
        root.accept(vis2);
        root.accept(vis3);
    
        System.out.println(vis1.getResult());
        System.out.println(vis2.getResult());
        System.out.println(vis3.getResult());
    }
    

    }

  • + 0 comments
    class SumInLeavesVisitor extends TreeVis {
        private int sum = 0;
    
        public int getResult() {
            return sum;
        }
    
        public void visitNode(TreeNode node) {
            // No action needed for internal nodes in this visitor
        }
    
        public void visitLeaf(TreeLeaf leaf) {
            sum += leaf.getValue();
        }
    }
    
    class ProductOfRedNodesVisitor extends TreeVis {
        private double product = 1;
    
        public int getResult() {
            return (int) product;
        }
    
        public void visitNode(TreeNode node) {
            increaseProduct(node);
        }
    
        public void visitLeaf(TreeLeaf leaf) {
            increaseProduct(leaf);
        }
    
        private void increaseProduct(Tree tree) {
            if (tree.getColor() == Color.RED) {
                product = (product * tree.getValue()) % (Math.pow(10, 9) + 7);
            }
        }
    }
    
    class FancyVisitor extends TreeVis {
        private int nonLeafNodeSum = 0;
        private int greenLeafSum = 0;
    
        public int getResult() {
            return Math.abs(nonLeafNodeSum - greenLeafSum);
        }
    
        public void visitNode(TreeNode node) {
            if (node.getDepth() % 2 == 0) {
                nonLeafNodeSum += node.getValue();
            }
        }
    
        public void visitLeaf(TreeLeaf leaf) {
            if (leaf.getColor() == Color.GREEN) {
                greenLeafSum += leaf.getValue();
            }
        }
    }
    
    public class Solution {
      
        public static Tree solve() {
            Scanner scan = new Scanner(System.in);
            int n = Integer.parseInt(scan.nextLine());
            String valuesLine = scan.nextLine();
            String colorsLine = scan.nextLine();
    
            String[] valuesStr = valuesLine.split(" ");
            int[] values = new int[n];
    
            for (int i = 0; i < n; i++) {
                values[i] = Integer.parseInt(valuesStr[i]);
            }
    
            String[] colorsStr = colorsLine.split(" ");
            byte[] colors = new byte[n];
            
            for (int i = 0; i < n; i++) {
                colors[i] = (byte) Integer.parseInt(colorsStr[i]);
            }
    
            Map<Integer, List<Integer>> adj = new HashMap<>();
            boolean[] visited = new boolean[n];
    
            for (int i = 0; i < n; i++) {
                adj.put(i, new ArrayList<Integer>());
            }
    
            while (scan.hasNextInt()) {
                int u = scan.nextInt() - 1;
                int v = scan.nextInt() - 1;
                adj.get(u).add(v);
                adj.get(v).add(u);
            }
    
            scan.close();
            
            return buildTree(0, 0, values, colors, adj, visited);
        }
    
        public static Tree buildTree(
            int index, int depth, int[] values, byte[] colors, Map<Integer, List<Integer>> adj, boolean[] visited
        ) {
            boolean isLeaf = true;
            visited[index] = true;
    
            Color color = colors[index] == 0 ? Color.RED : Color.GREEN;
            List<Integer> children = adj.get(index);
            TreeNode treeNode = new TreeNode(values[index], color, depth);
    
            for (int child : children) {
                if (!visited[child]) {
                    isLeaf = false;
                    Tree childNode = buildTree(child, depth + 1, values, colors, adj, visited);
                    treeNode.addChild(childNode);
                }
            }
    
            if (isLeaf) {
                return new TreeLeaf(values[index], color, depth);
            } else {
                return treeNode;
            }
        }
    
  • + 0 comments

    This problem leads one to believe that the input data is a tree. But in fact, it is an undirected graph. The lack of this information made me waste a lot of time solving the problem.