First Java Data Structures Assignment - java

edit - I revised my code and replaced my original work with new code, still having similar issues
This data structures class I'm taking is my first programming course, so I'm a bit out of my element. The first project is really kicking my ass. It is to make a Reverse Polish Notation Calculator. It is more or less complete, just a lot of bugs. I have been spending hours tweaking my code but when I address one problem it unleashes another. I apologize in advance for my horrible programming skills.
public class ReversePolishStack {
class SinglyLinkList {
Node head = null;
public void push(float newData) {
Node cache = this.head;
this.head = new Node(newData, cache);
}
public float pop() {
float out = this.head.data;
head = head.next;
return out;
}
public void add(float num1, float num2) {
num1 = pop();
num2 = pop();
push(num1+num2);
}
public void sub(float num1, float num2) {
num1 = pop();
num2 = pop();
push(num2-num1);
}
public void div(float num1, float num2) {
num1 = pop();
num2 = pop();
push(num2/num1);
}
public void mult(float num1, float num2) {
num1 = pop();
num2 = pop();
push(num1*num2);
}
class Node {
public float data;
public Node next;
public Node(float data, Node next) {
this.data = data;
this.next = next;
}
}
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
ReversePolishStack rps = new ReversePolishStack();
SinglyLinkList sll = rps.new SinglyLinkList();
String entry;
do
{
System.out.print("Enter Expression:\n");
Scanner in = new Scanner(System.in);
entry =in.nextLine();
StringTokenizer st = new StringTokenizer(entry," ");
String s1;
int count = 0;
while (st.hasMoreElements())
{
if (entry.length()<4) {// for an error message not enough input
System.out.print("Not enough input"); break;
}
else if (count>1 && sll.head.next==null) {
System.out.print("Not enough operands"); break;
}
s1 = st.nextToken();
if((s1.equals("+") || s1.equals("-") || s1.equals("*") || s1.equals("/"))) {
if(s1.equals("+"))
sll.add(sll.head.data, sll.head.next.data);
else if(s1.equals("-"))
sll.sub(sll.head.data, sll.head.next.data);
else if(s1.equals("/")) {
if (sll.head.data==0) {
System.out.println("Division by Zero enounterd."); break;
}
sll.div(sll.head.data, sll.head.next.data);
}
else if(s1.equals("*"))
sll.mult(sll.head.data, sll.head.next.data);
else
System.out.print("Unrecognized input");break;
}
else {
sll.push(Float.parseFloat(s1));
}
count++;
}
System.out.println(sll.head.data);
sll.pop();
} while(entry.equals("0")== false); // typeing a single zero terminates
System.out.print("Thanks for using my RPN Calculator!");
}
}
I have been at this for awhile and I'm sure with every attempt at fixing a bug I also added to the convolution that is my code. Any help would be appreciated!

First of all you should take out from the main method the classes you have defined.
After that you'll get an error because an instance of the class singlyLinkList (singlyLinkList sll = new singlyLinkList();) has been created without creating the outer class (ReversePolishStack).
See as reference this link about nested classes.
I also put the Node class into the singlyLinkList class (btw you should rename this class as SinglyLinkList with the first letter capitalized).
I didn't get into the logic of your code but at least after these fixes your code will compile:
public class ReversePolishStack {
class singlyLinkList {
Node head = null;
public void push(float newData) {
Node cache = this.head;
this.head = new Node(newData, cache);
}
public float pop() {
float out = this.head.data;
head = head.next;
return out;
}
class Node {
public float data;
public Node next;
public Node(float data, Node next) {
this.data = data;
this.next = next;
}
}
}
/**
* #param args
* the command line arguments
*/
public static void main(String[] args) {
float number1;
float number2;
ReversePolishStack rps = new ReversePolishStack();
singlyLinkList sll = rps.new singlyLinkList();
System.out.print("Enter Expression:\n");
// from here will be the same as you wrote
}
}
I also suggest you to extract the logic of your program from your main method and create methods in the ReversePolishStack in order to use the oop concepts.
Hope this was useful!
Ciao!

Related

Binary Tree Output

Hi how do I make the program output the sum of the numbers instead of giving them out seperately?
public class Tree {
private Node root;
public int sum;
public class Node{
private Node left;
private Node right;
private int val;
public Node(int data) {
this.val = data;
}
}
public void createTree() {
Node first = new Node(7);
Node second = new Node(2);
Node third = new Node(6);
Node fourth = new Node(4);
root = first;
first.left = second;
first.right = third;
second.left = fourth;
}
public void Sum(Node root) {
if(root == null) {
return;
}
System.out.print(root.val + " ");
Sum(root.left);
Sum(root.right);
}
public static void main(String[] args) {
Tree tree = new Tree();
tree.createTree();
tree.Sum(tree.root);
}
}
Current output is 7 2 6 4 but I want them to be added into a sum in the System outprint if possible. I couldnt get it to work for some reason so maybe someone can help me with it.
You can recursively get the sum by doing the following:
public double sum(Node root) {
double leftSum, rightSum, totalSum;
if (root == null) {
totalSum = 0;
return totalSum;
}else {
leftSum = sum(root.left);
rightSum = sum(root.right);
totalSum = root.val + leftSum + rightSum;
return totalSum;
}
}
You need to return the sum of the left and right nodes and print the return value from main(). Also, there's no need for sum() to be an intance method since you're passing in root:
public static int sum(Node root) {
if(root == null) {
return 0;
}
return sum(root.left) + sum(root.right);
}
public static void main(String[] args) {
Tree tree = new Tree();
tree.createTree();
System.out.println(sum(tree.root));
}

Java Stack peek method displays 0 instead of correct number

I can't seem to understand what the logic error is in this class assignment. I am to make a stack using a linked list. Outer and Inner class should be implemented in UserStack. UserStack implements the MyStack provided by the teacher. StackApp houses the main.
It compiles and runs. It properly asks for an integer to be entered. Will remove if there is something to remove and will try to peek if there is something to show. But it always says it removed or is displaying the number 0.
Do I need to try to do a toString override? I asked my professor and he told me to just go to google like other students.
MyStack.java
public interface MyStack
{
public void push (int item);
public int pop ();
public int peek ();
public boolean isEmpty ();
}
UserStack.java
import java.util.NoSuchElementException;
public class UserStack implements MyStack
{
private class Node
{
public int value;
public Node link;
public Node(int data)
{
data = value;
}
}
private Node head = null;
public void push (int item)
{
Node newHead = new Node(item);
newHead.link = head;
head = newHead;
}
public int pop ()
{
if(isEmpty())
throw new NoSuchElementException();
int tmp = head.value;
head = head.link;
return tmp;
}
public int peek ()
{
if(isEmpty())
throw new NoSuchElementException();
int tmp = head.value;
return tmp;
}
public boolean isEmpty ()
{
return head == null;
}
}
StackApp.java
import java.util.Scanner;
class StackApp
{
UserStack stack = new UserStack();
public void displayMenu()
{
System.out.println ("1) Add an integer to the list\n" +
"2) Remove last integer entered\n" +
"3) Look at last integer entered\n" +
"0) Exit the program");
System.out.print ("Selection: ");
}
public StackApp()
{
int option;
Scanner input = new Scanner(System.in);
do{
displayMenu();
option = input.nextInt();
switch (option)
{
case 1:
int number;
System.out.println("Enter integer to add: ");
number = input.nextInt();
stack.push(number);
break;
case 2:
int number2 = stack.pop();
System.out.println("Interger removed: " + number2);
break;
case 3:
int number3 = stack.peek();
System.out.println("Next Interger: " + number3);
break;
case 0:
System.out.println("Goodbye");
break;
default:
System.err.println("Unrecongized choice");
break;
}
}while(option != 0);
}
public static void main(String[] args)
{
new StackApp();
}
}
You are never setting the value of the new item.
Mate, try switching around your values assignment in your Node constructor:
Original:
public Node(int data)
{
data = value;
}
New:
public Node(int data)
{
this.value = data;
}
Also, the usage of the keyword "this" is important as your are letting the program know that we want to set this class level variable "value" to that of data. As such, you must use the keyword "this". I am quite certain that your assignment was a bit off as you set your "data" equal to that of "value", and, because value never had an initial value explicitly set, it defaults to 0.

Evaluate a Postfix Expression Using a Singly Linked List

I'm writing a program that asks the user for a postfix expression, and then outputs the result to the expression. I am attempting to do this using a Singly Linked List, and using the Adapter Pattern to create a stack.
The code for the SinglyLinkedList class, the LinkedStack class, and the Stack implementation are all straight out of a Data Structures book that I own. So the SinglyLinkedListTest class is the only one that has my own code in it (and has errors).
I've written a program that simply uses a stack to evaluate a postfix expression before, but I'm getting confused this time with the extra classes included.
I'm sure I have a ton of errors, but the most obvious ones to me are in my SinglyLinkedListTest class, every time I push a value onto the stack. I know the issue is that I am attempting to push Objects and characters onto the stack instead of the arguments that match push(E e), but I don't know how to alter my code to make this work.
Any suggestions or input would be greatly appreciated.
Here is my Stack Implementation:
package PostFix;
public interface Stack<E>
{
int size();
boolean isEmpty();
void push(E e);
E pop();
}
Here is my LinkedStack class:
package PostFix;
public class LinkedStack <E> implements Stack<E>
{
private SinglyLinkedList<E> list = new SinglyLinkedList<>();
public LinkedStack()
{
}
public int size()
{
return list.size();
}
public boolean isEmpty()
{
return list.isEmpty();
}
public void push(E e)
{
list.addFirst(e);
}
public E pop()
{
return list.removeFirst();
}
}
Here is my SinglyLinkedList class:
package PostFix;
public class SinglyLinkedList<E>
{
private static class Node<E>
{
private E element;
private Node<E> next;
public Node(E e, Node<E> n)
{
element = e;
next = n;
}
public E getElement()
{
return element;
}
public Node<E> getNext()
{
return next;
}
}
private Node<E> head = null;
private Node<E> tail = null;
private int size = 0;
public SinglyLinkedList()
{
}
public int size()
{
return size;
}
public boolean isEmpty()
{
return size == 0;
}
public void addFirst(E e)
{
head = new Node<>(e, head);
if (size == 0)
{
tail = head;
}
size++;
}
public E removeFirst()
{
if (isEmpty())
{
return null;
}
E answer = head.getElement();
head = head.getNext();
size--;
if (size == 0)
{
tail = null;
}
return answer;
}
}
Here is my final SinglyLinkedListTest class:
package PostFix;
import java.util.Scanner;
public class SinglyLinkedListTest
{
public static void main(String[] args)
{
Double num1, num2, answer;
char c;
Stack<Double> stack = new LinkedStack<>();
Scanner input = new Scanner(System.in);
System.out.println("Enter the expression you would like to evaluate: ");
String someString = input.nextLine();
for (int index = 0; index < someString.length(); index++)
{
c = someString.charAt(index);
if (Character.isDigit(c))
{
stack.push((double)Character.digit(c, 10));
}
else if (c == '+')
{
num2 = stack.pop();
num1 = stack.pop();
answer = num1+num2;
stack.push(answer);
}
else if (c == '-')
{
num2 = stack.pop();
num1 = stack.pop();
answer = num1-num2;
stack.push(answer);
}
else if (c == '*')
{
num2 = stack.pop();
num1 = stack.pop();
answer = num1*num2;
stack.push(answer);
}
else if (c == '/')
{
num2 = stack.pop();
num1 = stack.pop();
answer = num1/num2;
stack.push(answer);
}
}
System.out.println("The result is: " + stack.pop());
}
}
Stack<String> buffer = new LinkedStack<>();
Poor name: call it stack.
You've declared it as Stack<String> but you're pushing chars:
buffer.push(someString.charAt(index));
and Objects:
buffer.push(answer);
and popping ints:
num1 = buffer.pop();
You are never either pushing or popping strings.
Just make up your mind. You should be pushing and popping ints, or longs, or doubles, or BigDecimals, depending on what precision you need.
EDIT
buffer.push((double)c);
is invalid. You're pushing the ASCII value, not the numeric value it corresponds to. You need
buffer.push((double)Character.digit(c, 10));
You also need an else after each if block: if the character is a digit, it won't be a +, and if it's a + it won't be a -, etc.

Creating a Hot Potato game with collections

Hot Potato Game: In this program you are expected to implement a
general simulation of the Hot Potato game. In this game children line
up in a circle and pass an item from neighbor to neighbor as fast as
they can. At a certain point in the game, the action is stopped and
the child who has the item (the potato) is removed from the circle.
Play continues until only one child is left. In your implementation
user should input a list of names and a constant num. Your program
must return the name of the last person remaining after repetitive
counting by num.
I needed to do that but i couldn't find out how to stop that while loop in the enqueuer() method of hotpotato class. If i have some other mistakes can you please tell me?
hotpotato class:
import java.util.*;
public class hotpotato
{
private static Scanner input1 = new Scanner(System.in);
private static NodeQueue<String> potato = new NodeQueue<String>();
private static Scanner input = new Scanner(System.in);
static int num;
public static void main(String[] args)
{
System.out.println("Enter names of the children.");
enqueuer(input1.next());
System.out.println("Enter the num");
num = input.nextInt();
potatothrower();
}
public static void enqueuer(String p)
{
String keyboard = input1.next();
while(!keyboard.equals("stop"))
{
potato.enqueue(p);
}
}
public static void potatothrower()
{
for(int i = 0; i< num; i++)
{
if(!potato.isEmpty()){
String tmp = potato.front();
potato.dequeue();
potato.enqueue(tmp);
}
else{
System.out.println("Queue is empty");
}
}
potato.dequeue();
}
}
Node Class:
public class Node<E> {
// Instance variables:
private E element;
private Node<E> next;
/** Creates a node with null references to its element and next node. */
public Node() {
this(null, null);
}
/** Creates a node with the given element and next node. */
public Node(E e, Node<E> n) {
element = e;
next = n;
}
// Accessor methods:
public E getElement() {
return element;
}
public Node<E> getNext() {
return next;
}
// Modifier methods:
public void setElement(E newElem) {
element = newElem;
}
public void setNext(Node<E> newNext) {
next = newNext;
}
}
NodeQueue Class:
public class NodeQueue<E> implements Queue<E> {
protected Node<E> head;
protected Node<E> tail;
protected int size; // number of elements in the queue
public NodeQueue() { // constructs an empty stack
head = null;
tail = null;
size = 0;
}
public void enqueue(E elem) {
Node<E> node = new Node<E>();
node.setElement(elem);
node.setNext(null); // node will be new tail node
if (size == 0)
head = node; // special case of a previously empty queue
else
tail.setNext(node); // add node at the tail of the list
tail = node; // update the reference to the tail node
size++;
}
public E dequeue() {
if (size == 0)
System.out.println("Queue is empty.");
E tmp = head.getElement();
head = head.getNext();
size--;
if (size == 0)
tail = null; // the queue is now empty
return tmp;
}
public int size() { return size; }
public boolean isEmpty() {
return size == 0;
}
public E front() {
if (isEmpty()) System.out.println("Queue is empty.");
return head.getElement();
}
public String toString() {
Node<E> temp = head;
String s;
s = "[";
for (int i = 1; i <= size(); i++){
if(i==1)
s += temp.getElement();
else
s += ", " + temp.getElement();
temp = temp.getNext();
}
return s + "]";
}
}
Queue interface:
public interface Queue<E> {
/**
* Returns the number of elements in the queue.
* #return number of elements in the queue.
*/
public int size();
/**
* Returns whether the queue is empty.
* #return true if the queue is empty, false otherwise.
*/
public boolean isEmpty();
/**
* Inspects the element at the front of the queue.
* #return element at the front of the queue.
* #exception EmptyQueueException if the queue is empty.
*/
public E front();
/**
* Inserts an element at the rear of the queue.
* #param element new element to be inserted.
*/
public void enqueue (E element);
/**
* Removes the element at the front of the queue.
* #return element removed.
* #exception EmptyQueueException if the queue is empty.
*/
public E dequeue();
}
call:
System.out.println("Enter names of the children.");
enqueuer();
You're doing the read data only once and then enters an infinite WHILE loop because you have no way to write "stop". Therefore the function would be:
public static void enqueuer()
{
String p;
do {
p = input1.next();
if (!p.equals("stop"))
potato.enqueue(p);
} while(!p.equals("stop"));
}
The problem is really easy, just look better at your code:
public static void enqueuer(String p)
{
String keyboard = input1.next();
while(!keyboard.equals("stop"))
{
potato.enqueue(p);
}
}
You get the new input before the while. This means that keyboard will be the first argument, say Alice.
So, while alice != stop, do potato.enqueue.(p).
But since you get no new input inside the while, keyboard will ever be != then stop!
Bonus:
There is a bug i think:
public static void enqueuer(String p)
{
String keyboard = input1.next();
while(!keyboard.equals("stop"))
{
potato.enqueue(p); //you dont insert the keyboard value, but you insert every time p!
}
}

How to balance an existing random binary search tree (BST) using an array (in Java)?

I got the following assignment - I have a certain java code for a binary search tree and I need to add methods to do the following things with it:
Transform the BST into an array that's sorted by BST data keys.
Create a balanced BST from an ordered integer array.
Use 1. and 2. to balance an existing BST (randomly generated and presumably somewhat unbalanced)
Display the BST before and after balancing.
Please guys, help me if you're smarter than me and know how can that be achieved!
Here is the code that I need to work with:
import java.util.*;
class BtreeNode {
int data;
BtreeNode L,R;
static int depth=0;
public BtreeNode(){
data = 0; L = null; R=null;
}
public BtreeNode(int key){
this();data = key;
}
public String toString() {
return "["+data+"]";
}
public static BtreeNode insOrd(BtreeNode roo, int key){
if(roo==null)return new BtreeNode(key);
//Не се допуска повторение на ключове
if(key==roo.data)return roo;
if(key<roo.data)roo.L=insOrd(roo.L,key);
else roo.R=insOrd(roo.R,key);
return roo;
}
public static BtreeNode generate(int length) {
BtreeNode start = null;
Random rn = new Random();
for(int i = 0; i < length; i++){
start = insOrd(start,rn.nextInt(10000));
}
return start;
}
public static void spc(int n){
for(int i=0;i<n;i++)System.out.print(" ");
}
public static void print(BtreeNode roo){
if(roo!=null){
depth++;
print(roo.R);
spc(depth);System.out.println(roo);
print(roo.L);
depth--;
}
}
public static BtreeNode find(BtreeNode roo, int key){
BtreeNode r=null;
if(roo==null)return r;
if(roo.data==key)r= roo;
if(key>roo.data)r= find(roo.R,key);
if(key<roo.data)r= find(roo.L,key);
return r;
}
};
public class Main {
public static void main(String[] args){
int N;
Scanner sc = new Scanner(System.in);
System.out.print("Enter the number if tree items:");
N=sc.nextInt();
BtreeNode c = BtreeNode.generate(N);
BtreeNode.print(c);
/*
System.out.println("This tree has "+
BtreeNode.weight(c)+" nodes and "+
BtreeNode.height(c)+" levels.");
*/
}
}
UPDATE:
Thank you soooo much guys for your great help, you can't imagine how grateful I am for your advice!!!
I have the whole program working. I am going to post it because somebody might need something like that sometime.
import java.util.*;
class BtreeNode {
int data;
BtreeNode L,R;
static int depth=0;
public BtreeNode(){
data = 0; L = null; R=null;
}
public BtreeNode(int key){
this();data = key;
}
public String toString() {
return "["+data+"]";
}
public static ArrayList<BtreeNode> asList(BtreeNode node) {
ArrayList<BtreeNode> result = new ArrayList<BtreeNode>();
traverse(node, result);
Collections.sort(result, new Comparator<BtreeNode>() {
#Override
public int compare(BtreeNode arg0, BtreeNode arg1) {
if (arg0.data < arg1.data)
return -1;
else if (arg0.data > arg1.data)
return 1;
return 0;
}
});
return result;
}
private static void traverse(BtreeNode node, ArrayList<BtreeNode> result) {
if (node.L != null) {
traverse(node.L, result);
}
result.add(node);
if (node.R != null) {
traverse(node.R, result);
}
}
public static BtreeNode sortedArrayToBST (ArrayList<BtreeNode> result, int start, int end) {
if (start > end) return null;
// same as (start+end)/2, avoids overflow.
int mid = start + (end - start) / 2;
BtreeNode node = new BtreeNode(result.get(mid).data);
node.L = sortedArrayToBST(result, start, mid-1);
node.R = sortedArrayToBST(result, mid+1, end);
return node;
}
public static BtreeNode insOrd(BtreeNode roo, int key){
if(roo==null)return new BtreeNode(key);
if(key==roo.data)return roo;
if(key<roo.data)roo.L=insOrd(roo.L,key);
else roo.R=insOrd(roo.R,key);
return roo;
}
public static BtreeNode generate(int length) {
BtreeNode start = null;
Random rn = new Random();
for(int i = 0; i < length; i++){
start = insOrd(start,rn.nextInt(10000));
}
return start;
}
public static void spc(int n){
for(int i=0;i<n;i++)System.out.print(" ");
}
public static void print(BtreeNode roo){
if(roo!=null){
depth++;
print(roo.R);
System.out.print("Level "+depth);
spc(depth);
System.out.println(roo);
print(roo.L);
depth--;
}
}
public static BtreeNode find(BtreeNode roo, int key){
BtreeNode r=null;
if(roo==null)return r;
if(roo.data==key)r= roo;
if(key>roo.data)r= find(roo.R,key);
if(key<roo.data)r= find(roo.L,key);
return r;
}
};
public class Main {
public static void main(String[] args){
int N;
Scanner sc = new Scanner(System.in);
System.out.print("Enter the number if tree items:");
N=sc.nextInt();
BtreeNode c = BtreeNode.generate(N);
BtreeNode.print(c);
System.out.println("********************");
/*
System.out.println("This tree has "+
BtreeNode.weight(c)+" nodes and "+
BtreeNode.height(c)+" levels.");
*/
ArrayList<BtreeNode> result = BtreeNode.asList(c);
for (BtreeNode btreeNode : result) {
System.out.println(btreeNode.data);
}
// insert in sorted order
c = result.get(0);
for (int i = 1; i < result.size(); i++) {
BtreeNode.insOrd(c, result.get(i).data);
}
BtreeNode.print(c);
System.out.println("********************");
BtreeNode d = BtreeNode.generate(N);
BtreeNode.print(d);
System.out.println("********************");
ArrayList<BtreeNode> result2 = BtreeNode.asList(d);
for (BtreeNode btreeNode : result2) {
System.out.println(btreeNode.data);
}
System.out.println("********************");
BtreeNode.print(BtreeNode.sortedArrayToBST(result2, 0, result2.size()-1));
}
}
Well for the first point you have to have a global array and a traverse method.
Traverse method shoould work something like this:
in main method at the end add this:
ArrayList<BtreeNode> result = BtreeNode.asList(c);
for (BtreeNode btreeNode : result) {
System.out.println(btreeNode.data);
}
// insert in sorted order
c = result.get(0);
for (int i = 1; i < result.size(); i++) {
c.insOrd(c, result.get(i).data);
}
BtreeNode.print(c);
add this methods to BtreeNode class:
public static ArrayList<BtreeNode> asList(BtreeNode node) {
ArrayList<BtreeNode> result = new ArrayList<BtreeNode>();
traverse(node, result);
Collections.sort(result, new Comparator<BtreeNode>() {
#Override
public int compare(BtreeNode arg0, BtreeNode arg1) {
if (arg0.data < arg1.data)
return -1;
else if (arg0.data > arg1.data)
return 1;
return 0;
}
});
return result;
}
private static void traverse(BtreeNode node, ArrayList<BtreeNode> result) {
if (node.L != null) {
traverse(node.L, result);
}
result.add(node);
if (node.R != null) {
traverse(node.R, result);
}
}
1) Creating the sorted array can be done with an "inorder tree walk" - it's fairly easily implementable as a recursive function that you start on the root node. It would look something like this:
void addToListInOrder(List<BtreeNode> l) {
if(L != null) {
L.addToListInOrder(l);
}
list.add(this);
if(R != null) {
R.addToListInOrder(l);
}
}
2) A recursive algorithm would work well here as well: Pick a point in the middle (round up or down if needed) and pick that as the root node. Then subdivide the remaining points in two lists, those before and those after the chosen node, and then call the algorithm recursively on those. Then set the results as the left and right child of the current node. and finally return the node that was chosen. Be sure to handle lists with only a single or a few nodes correctly
3) Do 1 and then 2 on the BST to get a balanced recreation.
4) I've used graphviz for some nice visualizations in the past, but that's probably beyond the scope of your assignment. In it I used an inorder graph walk to create the source file for graphviz
Just check http://www.roseindia.net/java/java-get-example/java-binary-tree-code.shtml
For all of these operation you should use reqursion with end check for current node if it hasn't got more childs.

Categories