Referring to an instance that refers to an instance - java

I am not sure if the title to this question is correct.
I have this school assignment where we have to create two classes.
In one class, we define relationships between people e.g. A knows B, and in the other class we ask questions about that, e.g. does A know B?
The first class below defines relationships and gives methods, the second class inquires about them.
I am sure that my mistake lies somewhere in the public boolean 'knowsWithDegree'. Are you able to help?
public class SocialGraph {
private HashMap<String, List<String>> map = new HashMap<String, List<String>>();
public SocialGraph() { // empty constructor
map = new HashMap<String, List<String>>();
}
public void addIndividual(String a) {
if (!map.containsKey(a)) {
map.put(a, new ArrayList<String>());
} else {
}
}
public boolean hasKnowsArrow(String a, String b) {
if (map.containsKey(a)) {
return map.get(a).contains(b);
} else {
return false;
}
}
public void addKnowsArrow(String a, String b) {
if ((!map.containsKey(a) || !map.containsKey(b)) || (hasKnowsArrow(a, b))) {
} else {
map.get(a).add(b);
}
}
public void removeKnowsArrow(String a, String b) {
if ((!map.containsKey(a) || !map.containsKey(b)) || (!hasKnowsArrow(a, b))) {
} else {
map.get(a).remove(b);
}
}
public boolean knowsWithDegree(String a, String b, int x) {
Object[] keys = map.keySet().toArray();
int y;
y = 0;
if (map.get(a).contains(b)) {
y = 1;
} else {
if ((map.get(a).contains(map.get(keys[0]).contains(b))) || (map.get(a).contains(map.get(keys[1]).contains(b))) ||
(map.get(a).contains(map.get(keys[2]).contains(b))) || (map.get(a).contains(map.get(keys[3]).contains(b)))) {
y = 2;
}
}
if (x == y) {
return true;
} else
return false;
}
}
public class SocialGraphTest {
public static void main(String[] args) {
SocialGraph socialGraph = new SocialGraph();
socialGraph.addIndividual("Anne");
socialGraph.addIndividual("Daisy");
socialGraph.addIndividual("Bob");
socialGraph.addIndividual("Charlie");
socialGraph.addKnowsArrow("Anne", "Bob");
socialGraph.addKnowsArrow("Anne", "Daisy");
socialGraph.addKnowsArrow("Bob", "Daisy");
socialGraph.addKnowsArrow("Bob", "Charlie");
System.out.println(socialGraph.hasKnowsArrow("Anne", "Bob")); //should be true
System.out.println(socialGraph.hasKnowsArrow("Anne", "Daisy"));//should be true
System.out.println(socialGraph.hasKnowsArrow("Bob", "Daisy"));//should be true
System.out.println(socialGraph.hasKnowsArrow("Bob", "Charlie"));//should be true
System.out.println(socialGraph.hasKnowsArrow("Anne", "Charlie")); //should be false
System.out.println ();
System.out.println (socialGraph.knowsWithDegree ("Anne", "Daisy", 1));
System.out.println (socialGraph.knowsWithDegree ("Anne", "Charlie", 2));
System.out.println (socialGraph.knowsWithDegree ("Anne", "Daisy", 3));
}
}
}

Here is an example using recursion:
public boolean knowsWithDegree(String a, String b, int x) {
return knowsWithDegreeRecursive(a, b, x, new HashSet<>());
}
private boolean knowsWithDegreeRecursive(String a, String b, int x, Set<String> visited) {
if (x < 1) {
// x must be at least 1
return false;
}
if (map.get(a).contains(b)) {
// If a knows b, then the number of degrees should be 1
return x == 1;
}
if (x == 1) {
// Since the degree is 1 and a does not know b, then a does not know b to the specified degree
return false;
}
// Go through each person that a knows
for (String c : map.get(a)) {
if (visited.contains(c)) {
// We've already checked this person
continue;
}
// Mark c as visited so we don't check them again
visited.add(c);
// See if this person knows b, with one fewer degree
// e.g. if we're seeing if a knows b with a degree of 2, then c should know b with a degree of 1
boolean knowsWithDegree = knowsWithDegreeRecursive(c, b, x - 1, visited);
// If c knows b with the degree minus 1, then a knows b with the specified degree
if (knowsWithDegree) {
return true;
}
}
// a does not know b to the specified degree
return false;
}
If the order of the knowsArrows doesn't matter, I would recommend using HashSet in your map over ArrayList.

Related

compareTo with objects returns a false while it is true

I am trying to check whether my levelorder of my Binary Search Tree is equal to the other one. To do this, I tried to make a compareTo method. I only give equal values to the method, but it keeps on saying the condition is false. When I place breakpoints, I see that the values are still equal. I am probably not understanding it correctly. Does anyone know how to solve this?
Here is what I did, as you can see below, the compareTo returns a 1 instead of a 0:
import edu.princeton.cs.algs4.BST;
import java.util.*;
public class MyBST implements Comparable<MyBST>{
private Object e;
public MyBST(Object e){
this.e = e;
}
private Object getE(){
return e;
}
public static void main(String[] args) {
int size = 4;
Random r = new Random();
Set<Integer> tes = new LinkedHashSet<>(size);
Stack<Integer> stack = new Stack<>();
while (tes.size() < size) {
tes.add(r.nextInt(10));
}
System.out.println("possible combinations");
Set<Stack<Integer>> combos = combos(tes, stack, tes.size());
Object[] arr = combos.toArray();
List<String> d = new ArrayList<>();
for (Object s : arr) {
String b = s.toString();
b = b.replaceAll("\\[", "").replaceAll("\\]", "");
d.add(b);
}
int index = 0;
do {
BST<String, Integer> bst1 = new BST<String, Integer>();
BST<String, Integer> bst2 = new BST<String, Integer>();
String key1 = d.get(index);
String key2 = d.get(index);
key1 = key1.replaceAll(" ", "");
String[] m = key1.split(",");
key2 = key2.replaceAll(" ", "");
String[] n = key2.split(",");
System.out.println("1e order");
for (int j = 0; j < m.length; j++) {
System.out.println(m[j]);
bst1.put(m[j], 0);
}
System.out.println("2e order");
for (int j = 0; j < n.length; j++) {
System.out.println(n[j]);
bst2.put(n[j], 0);
}
System.out.println("levelorder 1e BST");
MyBST e = new MyBST(bst1.levelOrder());
MyBST y = new MyBST(bst2.levelOrder());
System.out.println(bst1.levelOrder());
System.out.println("levelorder 2e BST");
System.out.println(bst2.levelOrder());
System.out.println(e.compareTo(y) + "\n");
index++;
} while (index < arr.length - 1);
}
public static Set<Stack<Integer>> combos(Set<Integer> items, Stack<Integer> stack, int size) {
Set<Stack<Integer>> set = new HashSet<>();
if (stack.size() == size) {
set.add((Stack) stack.clone());
}
Integer[] itemz = items.toArray(new Integer[0]);
for (Integer i : itemz) {
stack.push(i);
items.remove(i);
set.addAll(combos(items, stack, size));
items.add(stack.pop());
}
return set;
}
#Override
public int compareTo(MyBST o) {
if (this.e == o.e) {
return 0;
}
else
return 1;
}
}
Here you can find the BST.java class: BST.java
And the output is something like:
The breakpoint at the compareTo method says:
When you're using the == operator you're actually checking to see if the references point to the same object in memory. From your debugging screenshot you can see that they are not. this.e points to object Queue#817 while o.e points to Queue#819.
If all you want to do is test for equality, then just override equals and hashCode. You can do it like this (rest of class omitted):
public class MyBST {
private Object e;
public MyBST(Object e) {
this.e = e;
}
public Object getE(){
return e;
}
#Override
public int hashCode() {
return Objects.hashCode(e);
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (!(obj instanceof MyBST))
return false;
MyBST me = (MyBST) obj;
if (e == null) {
if (me.e != null)
return false;
} else if (!e.equals(me.e))
return false;
return true;
}
}
Implementing Comparable is more involved since you need to check for less, equal, or greater than other instances of MyBST. Unfortunately, the only field in MyBST is an Object which does not tell you anything about its actual fields. So without specific fields with which to test you need to ensure that the Object you pass also implements Comparable. Then you can declare your class like this. Rest of class omitted.
It simply says that
MyBST is comparable.
And the object that is passed in the constructor is comparable.
class MyBST<T extends Comparable<? super T>> implements Comparable<MyBST<T>>{
private T e;
public MyBST(T e){
this.e = e;
}
public T getE(){
return e;
}
#Override
public int compareTo(MyBST<T> o) {
return e.compareTo(o.e);
}
}
The other alternative is to simply pass the actual object type and store it as such, not as Object. Then just implement Comparable in MyBST and use the appropriate fields of the passed object. Lets say the object was an Apple object, you could do this.
class Apple {
String type;
int weight;
}
class MyBST implements Comparable<MyBST> {
private Apple apple;
public MyBST(Apple apple) {
this.apple = apple;
}
#Override
public int compareTo(MyBST e) {
// this could be different depending on how you wanted
// to compare one apple to another. This comparison favors
// type over weight.
// check type - String class implements comparable
int ret = apple.type.compareTo(e.apple.type);
if (ret != 0) {
return ret;
}
// same type so check weight
if (apple.weight < e.apple.weight) {
return -1;
}
if (apple.weight > e.apple.weight) {
return 1;
}
return 0; // equals apples based on criteria
}
}
Finally, you have this.
private Object getE(){
return e;
}
A private getter is not usually very useful. Make it public.

Sorting through an array list of objects

I am trying to read data in from a CSV file containing 4 columns to an array list. Let's call the columns a,b,c,d (They each contain integers). Then I would like to sort the array list according to the contents of the rows of a,b,c,d.
So if you are comparing row 1 and 2 for example, if the value of 1d<2d then return a certain value. If 1d=2d then compare 1c to 2c and so on. I am having trouble with finding a way to create an array list that allows me to differentiate and compare each row/column.
public class Speed {
public static void main(String[] args) throws IOException {
// TODO code application logic here
readCSV();
}
public static void readCSV() throws FileNotFoundException, IOException {
BufferedReader br = new BufferedReader(new FileReader("amis.csv"));
String line = "";
ArrayList<String> amis = new ArrayList<String>();
while ((line = br.readLine()) != null) {
line = line.replaceAll("\"", "");
amis.add(line);
}
amis.remove(0);
for (String alphabet: amis) {
Object[] parts = alphabet.split(",");
Object studentID = (parts[0]);
Object a = parts[1];
Object b = parts[2];
Object c = (parts[3]);
Object d = parts[4];
ArrayList<Object> Compare = new ArrayList();
Compare.add(a);
Compare.sort(new customComparator());
}
My custom comparator class
public class customComparator implements Comparator<Object> {
public int compare(Object o1, Object o2) {
int a = (Integer) o1;
int b = (Integer) o2;
if (a < b) {
return 1;
}
else if(a > b)
return -1;
else
return 0;
}
}
Let's take a look at your current sorting method
for(String alphabet: amis)
{
Object[] parts = alphabet.split(",");
Object studentID = (parts[0]);
Object a = parts[1];
Object b = parts[2];
Object c = (parts[3]);
Object d = parts[4];
ArrayList<Object> Compare = new ArrayList();
Compare.add(a);
Compare.sort(new customComparator());
}
The most blatant issue is you're creating an ArrayList, Compare, adding/sorting, then discarding it
If you're trying to make a second, sorted list:
List<String> sorted = new ArrayList<String>(amis);
sorted.sort(new CustomComparator());
If you're just trying to sort the original list:
amis.sort(new CustomComparator());
You've gotten fairly close to what you want to do, by making a comparator, but it needs tweaking
Your current implementation stops after it checks the first value, it returns 0 instead of continuing
public class CustomComparator implements Comparator<String>
{
public int compare(String A, String B)
{
String[] as = A.split(",");
String[] bs = B.split(",");
int a = Integer.parseInt(a[4]); //column d, as an int
int b = Integer.parseInt(b[4]);
if(a < b)
return 1;
else
if(a > b)
return -1;
else
{
a = Integer.parseInt(a[3]); //column c, as an int
b = Integer.parseInt(b[3]);
if(a < b)
return -1;
else
if(a > b)
return 1;
else
{
a = Integer.parseInt(a[2]); //column b, as an int
b = Integer.parseInt(b[2]);
if(a < b)
return -1;
else
if(a > b)
return 1;
else
{
a = Integer.parseInt(a[1]); //column a, as an int
b = Integer.parseInt(b[1]);
if(a < b)
return -1;
else
if(a > b)
return 1;
else
return 0; //all columns are the same
}
}
}
}
}
Noticing that there is a lot of similar code, we can instead change it into a loop
public int compare(String A, String B)
{
String[] as = A.split(",");
String[] bs = B.split(",");
for(int i = 4; i >= 1; i--) //columns d-a
{
int a = Integer.parseInt(a[i]);
int b = Integer.parseInt(b[i]);
if(a < b)
return -1;
if(a > b)
return 1;
}
return 0;
}
You should rather create POJO for each string and comparator for it. In the comparator you should compare more "important" columns first and go to less important if previous are equal.
public class Pojo {
private int a;
private int b;
private int c;
private int d;
public int getA() {
return a;
}
public void setA(int a) {
this.a = a;
}
public int getB() {
return b;
}
public void setB(int b) {
this.b = b;
}
public int getC() {
return c;
}
public void setC(int c) {
this.c = c;
}
public int getD() {
return d;
}
public void setD(int d) {
this.d = d;
}
public static class PojoComparator implements Comparator<Pojo> {
#Override
public int compare(Pojo pojo1, Pojo pojo2) {
return pojo1==null ? (pojo2==null ? 0:1) :(pojo2==null?-1:
(pojo1.d!=pojo2.d? pojo1.d-pojo2.d :
(pojo1.c!=pojo2.c ? pojo1.c-pojo2.c:
(pojo1.b!=pojo2.b? pojo1.b-pojo2.b:
pojo1.a-pojo2.a))) );
}
}
}

Java script takes too much time to finish

I don't know how to make my code less time consuming. My task was to make brute force password break. I knew how long password is and which characters it contains. So far i have this method.
public boolean moznosti(char [] arr, String pr, int a, int b) {
if (b == 0) {
char [] heslo = pr.toCharArray();
if(tryOpen(heslo)) {
return false;
}
return true;
}
for (int i = 0; i < a; i++) {
String tmp = pr+arr[i];
if (moznosti(arr, tmp, a, b-1) == false) {
return false;
}
moznosti(arr, tmp, a, b-1);
}
return true;
}
}
where heslo is password. any ideas?
Have a look at your code structure.
You have a for loop which recursively calls your moznosti method, and each time it's called it doing the same thing.
I don't know what your variables mean but assuming a and b are 4. Your first cycle will call your moznosti method 4 times with the same b parameter.
Not that this is causing the time issue but where you have:
if (moznosti(arr, tmp, a, b-1) == false)
Because the moznosti method returns a Boolean value, you don't need to check if it's equal to false or true, the if statement brackets only pass when the condition is true. So in your case this might be more applicable:
if (!moznosti(arr, tmp, a, b-1))
I think the part which is taking most of the time is where you are checking your base case
if (moznosti(arr, tmp, a, b-1) == false)
Okay i did it!
public class BruteForceAttacker extends Thief {
private boolean konec;
#Override
public void breakPassword(int sizeOfPassword) {
moznosti(getCharacters(), "", getCharacters().length, sizeOfPassword);
}
public void moznosti(char [] arr, String pr, int a, int b) {
if (konec != true) {
if (b == 0) {
char [] heslo = pr.toCharArray();
if (tryOpen(heslo)) {
konec = true;
}
return;
}
for (int i = 0; i < a; i++) {
String tmp = pr+arr[i];
moznosti(arr, tmp, a, b-1);
}
}
}
}

How to find the most common character in a String

I have a quick question. How would I find the most common character in a string in Java. I know logically how to do it, but I am not sure if my syntax in correct:
public class HelloWorld {
public static void main(String[] args){
String votes = "ABBAB";
char[] StoringArray = votes.toCharArray();
int numOFB = 0;
int numOFA = 0;
if (StoringArray.contains("A")) {
numOFA++;
} else if (StoringArray.contains("B")) {
numOFAB++;
}
if (numOFA = numOFB) {
System.out.println("Tie");
} else if (numOFA > B) {
System.out.println("A");
} else {
System.out.println("B");
}
}
}
Could anyone help me with how to correctly do this in Java?
You can not compare char Array with string, below logic should work and give you what you need:
public static void main(String[] args){
String votes = "ABBAB";
char[] storingArray = votes.toCharArray();
int numOFB = 0;
int numOFA = 0;
for(char c : storingArray) {
if(c == 'A') {
numOFA++;
}
if(c == 'B') {
numOFB++;
}
}
if (numOFA == numOFB) {
System.out.println("Tie");
} else if (numOFA > numOFB) {
System.out.println("A");
} else {
System.out.println("B");
}
}
There are couple of mistakes in your code:
You can not use if (numOFA = numOFB) it is not valid expression. You should use == to compare
You can not compare char Array with contains method. It should be used on String object
As the comments said; it looks like you're counting the number of A's or B's, not the longest substring. Are you only analyzing a String composed of A's and B's?
Also, you're using = to check for equality when you should be using ==. I would recommend using an IDE like Eclipse which would show you when you're doing this.
Edit: also, you're not looping through the array. You're just checking if the String contains an A or a B and adding 1 if it does. You need to loop through the entire array.
Actually, I was working with it, and I found this is the nicest way to do it:
String votes = "ABBAB";
char[] StoringArray = votes.toCharArray();
int B = 0;
int A = 0;
for (int i = 0; i < StoringArray.length; i ++) {
if (StoringArray[i] == 'A') {
A++;
} else if (StoringArray[i] == 'B') {
B++;
}
}
if (A == B) {
System.out.println("Tie");
} else if (A > B) {
System.out.println("A");
} else {
System.out.println("B");
}
I would give you a more abstract solution:
public class Counter{
private char c;
private int count;
Counter(char c, int count){
this.c=c;
this.count=count;
}
public char getC() {
return c;
}
public void setC(char c) {
this.c = c;
}
public int getCount() {
return count;
}
public void addOcurrence() {
this.count++;
}
#Override
public boolean equals(Object obj) {
if(obj!=null)
if(((Counter)obj).getC()== this.c)
return true;
return false;
}
}
public static void main(String[] args){
String votes = "whateveryouwanttoputhereorcanbefromaparameter";
char[] storingArray = votes.toCharArray();
List<Counter> listCounter = new ArrayList<Counter>();
for(char aChar : storingArray){
Counter compareCounter = new Counter(aChar,1);
if(listCounter.contains(compareCounter)){
listCounter.get(listCounter.indexOf(compareCounter)).addOcurrence();
}else{
listCounter.add(compareCounter);
}
}
Counter max = listCounter.get(0);
for( Counter c : listCounter){
if(c.getCount() > max.getCount()){
max = c;
}
}
System.out.println("the character with more ocurrence is: "+max.getC());
}

binary search tree, insert method won't compile

I'm attempting to write my own binary search tree in java. I have written all my methods and I am now trying to write a program to test the methods.
However, when I try to implement my "insert" method, it will not compile and I have no idea why.
public class lab05driver {
public static void main(String[] args) {
BST q = new BST();
int a = 5;
String b = "jed";
double c = 1.8;
char d = 'r';
boolean e = false;
int f = 35;
String g = "yay";
double h = 2.1;
char i = 'i';
boolean j = true;
Integer k = 5;
q.insert(k);
}}
and my BST class looks like this:
public class BST implements myBST {
private myTreeNode root;
public BST() {
}
public void insert(Comparable x) {
if(root == null) {
root = new myTreeNode();
root.data = x;
} else if ( !lookup(x) ) {
root.insert(x);
}
}
...more code...
}
and, myBST looks like:
public interface myBST {
public void insert(Comparable x);
public void delete(Comparable x);
public boolean lookup(Comparable x);
public void printPreOrder();
public void printInOrder();
public void printPostOrder();
}
finally, myTreeNode looks like:
public class myTreeNode {
public myTreeNode() {
}
public Comparable data ;
public myTreeNode leftchild;
public myTreeNode rightchild;
public myTreeNode parent;
public void insert(Comparable d) {
//if less than
//does left exist? if it doesnt, make it, give it d
//if it exists call insertrecursive on rightchild
if(d.compareTo(data) <= 0) {
if(leftchild != null) {
leftchild.insert(d);
} else {
leftchild = new myTreeNode();
leftchild.data = d;
leftchild.parent = this;
}
} else {
if(rightchild != null) {
rightchild.insert(d);
} else {
rightchild = new myTreeNode();
rightchild.data = d;
rightchild.parent = this;
}
}
}
...more code...
}
it is throwing an error at "q.insert(k)" in the lab05driver. any help/suggestions would be greatly appreciated...
~~~~~
EDIT: sorry i jsut copied that wrong... there is a main method and Integer k is an integer...
the error im getting the command line is:
warning: [unchecked] unchecked call to compareTo(T) as a member of the raw type java.lang.Comparable
q.insert(k); is a statement. Statements need to be in methods, it isn't currently in a method.
So do something like:
public class lab05driver
{
public static void main( String[] args )
{
BST q = new BST();
int a = 5;
String b = "jed";
double c = 1.8;
char d = 'r';
boolean e = false;
int f = 35;
String g = "yay";
double h = 2.1;
char i = 'i';
boolean j = true;
Integer k = 1; // changed because "Integer k = "test";" doesn't compile
q.insert(k);
}
}
Note the signature I used for the method. This is the signature that Java sees as the entry method (where the program will start).
The most obvious problem that I can see is:
Integer k = "test";
k needs to be an integer of some sort - you've assigned it a String. This is not a valid assignment. Valid values would be -1, 0, 1 etc - any integer value.
Once you assign a value value (or change k to be the String class) your code should be ok

Categories

Resources