I am trying to sum the all children values from its node between a specific range from its root node.
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class Program {
public static class Node {
int data;
List<Node> children;
public Node(int data) {
this.data = data;
children = new ArrayList<>();
}
public void addChildren(Node... children) {
this.children.addAll(Arrays.asList(children));
}
}
public int sumRange(Node root, int min, int max) {
int sum = 0;
if(root.data >= min && root.data <= max) {
sum = root.value;
}
int size = root.children.size();
for (int i = 0; i < size; ++i) {
if(root.children.get(i).data >= min && root.children.get(i).data <= max) {
sum += sumRange(root.children.get(i), min, max);
}
}
return sum;
}
public static void main(String[] args) {
Node node3 = new Node(3);
Node node4 = new Node(4);
Node node6 = new Node(6);
Node node7 = new Node(7);
Node node2 = new Node(2);
node2.addChildren(node3, node4);
Node node5 = new Node(5);
node5.addChildren(node6, node7);
Node node8 = new Node(8);
Node node1 = new Node(1);
node1.addChildren(node2, node5, node8);
Program program = new Program();
System.out.println(program.sumRange(node1, 3, 5)); // Should print 12
System.out.println(program.sumRange(node2, 3, 5)); // Should print 7
}
}
I have tried this code to calculate the sum of nodes between a specific range:
public int sumRange(Node root, int min, int max) {
int sum = 0;
if(root.data >= min && root.data <= max) {
sum = root.value;
}
int size = root.children.size();
for (int i = 0; i < size; ++i) {
if(root.children.get(i).data >= min && root.children.get(i).data <= max) {
sum += sumRange(root.children.get(i), min, max);
}
}
return sum;
}
And, its summation correctly the only that nodes which have no children. In this line its the node1 have multiple child and it should calculate only the specific range nodes which should sum result 12. But its printing the sum result 5.
System.out.println(program.sumRange(node1, 3, 5)); // Should print 12
I wants to calculate all the child nodes data also. Any help will be appreciated!
The problem is that you only visit child nodes that are within your range. This means if node2 has value 2 its children are never visited and you cannot sum the values 3 and 4. The solution to your problem is removing the if condition in the loop like this:
public int sumRange(Node root, int min, int max) {
int sum = 0;
if(root.data >= min && root.data <= max) {
sum = root.data;
}
int size = root.children.size();
for (int i = 0; i < size; ++i) {
sum += sumRange(root.children.get(i), min, max);
}
return sum;
}
If you try again the output should be 12 for node 1.
Related
So given this.
//Fibonacci Series using Recursion
class fibonacci
{
static int fib(int n)
{
if (n <= 1)
return n;
return fib(n-1) + fib(n-2);
}
public static void main (String args[])
{
int n = 10;
System.out.println(fib(n));
}
}
How could I transform it so it takes an index as a parameter and returns the given Fibonacci number at that index? So say I put in index = 5 and it should return 8.
static int fib(int index)
{
int counter = 0;
int current = 0;
int previous = 0;
int temp = 0;
while(counter < index)
{
temp = previous;
previous = current;
current += temp;
counter++;
}
return current;
}
If it does not have to be recursive, then I think this might work. Haven't tested it but tried to answer your question
int main(){
int index, temp1 = 0, temp2 = 1, value_at_index = 0;
printf("Enter index: ");
scanf("%d",&index);
if(index==1){
printf("Fib value at index 1 = 1");
}
else{
for (int i = 2; i <= index; ++i){
value_at_index = temp1 + temp2;
temp1 = temp2;
temp2 = value_at_index;
}
printf("Fib value at index %d = ", index);
printf("%d\n", value_at_index);
return 0;
}
}
I would like to construct a graph from a given array and root where the node is described below,
static class TreeNode {
private int value;
private ArrayList<TreeNode> children;
public TreeNode(int nodeValue) {
this.value = nodeValue;
this.children = new ArrayList<TreeNode>();
}
public int getValue() {
return this.value;
}
public void addChild(TreeNode child) {
this.children.add(child);
}
public ArrayList<TreeNode> getChildren() {
return this.children;
}
}
An array provided below to construct the graph,
T[0] = 1
T[1] = 2
T[2] = 3
T[3] = 3
T[4] = 2
T[5] = 1
T[6] = 4
Array T describes a network of cities if T[P] = Q and P ≠ Q, then there is a direct road between cities P and Q. If the index of 2 is root, then the graph is provided below,
2 - 3
/ \
1 4
/ | |
0 5 6
Obviously, I can do it manually for the given array,
final int N = 7;
TreeNode[] nodes = new TreeNode[N];
for (int i = 0; i < N; i++) {
nodes[i] = new TreeNode(i);
}
TreeNode root = nodes[2];
root.addChild(nodes[1]);
root.addChild(nodes[3]);
root.addChild(nodes[4]);
nodes[1].addChild(nodes[0]);
nodes[1].addChild(nodes[5]);
nodes[4].addChild(nodes[6]);
How do I construct programmatically when I have given an array and K value? Please help.
After you construct the TreeNode[] array, it's easy:
TreeNode root = null;
for (int i=0; i<T.length; ++i) {
if (T[i] == i) { // if it's a root node
//TODO: Test for multiple root nodes here
root = nodes[i];
} else {
nodes[T[i]].addChild(nodes[i]);
}
}
I would add a private TreeNode parent; object to the TreeNode class, initialize it to null and set it to the parent reference in the addChild method. That's handy to have during debug, even if you don't need it for the first use of this class. Maybe you'll need it later.
Iterate over all nodes,
for each node get the node's value and add the current node to the node at the value.
for (int i = 0; i < N; i++) {
nodes[nodes[i].getValue()].addChild(nodes[i])
}
I write an answer, however, it's not showing all the children. The code is provided below,
public class App {
static class TreeNode {
private int value;
private ArrayList<TreeNode> children;
public TreeNode(int nodeValue) {
this.value = nodeValue;
this.children = new ArrayList<TreeNode>();
}
public int getValue() {
return this.value;
}
public void addChild(TreeNode child) {
this.children.add(child);
}
public ArrayList<TreeNode> getChildren() {
return this.children;
}
}
public static TreeNode buildGraph(int[] T, int K) {
final int N = T.length;
TreeNode[] nodes = new TreeNode[N];
for (int i = 0; i < N; i++) {
nodes[i] = new TreeNode(i);
}
/*
T[0] = 1
T[1] = 2
T[2] = 3
T[3] = 3
T[4] = 2
T[5] = 1
T[6] = 4
2 - 3
/ \
1 4
/ | |
0 5 6
* */
TreeNode root = nodes[K];
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
boolean[] visited = new boolean[N];
while (!queue.isEmpty()) {
TreeNode node = queue.poll();
int index = node.getValue();
visited[index] = true;
// T[3] = 3 is a leaf with no further connection to develop
if (index == T[index]) {
continue;
}
// 2 != 3 for the root node and we havent visited node 3 earlier
if (index != T[index] && !visited[T[index]]) {
node.addChild(nodes[T[index]]);
queue.offer(nodes[T[index]]);
}
int left = 0, right = N - 1;
while (left < index && right > index) {
if (T[left] == index) {
node.addChild(nodes[left]);
queue.offer(nodes[left]);
}
if (T[right] == index) {
node.addChild(nodes[right]);
queue.offer(nodes[right]);
}
left++;
right--;
}
}
return root;
}
public static void main(String[] args) {
int[] T = new int[7];
T[0] = 1;
T[1] = 2;
T[2] = 3;
T[3] = 3;
T[4] = 2;
T[5] = 1;
T[6] = 4;
TreeNode root = buildGraph(T, 2);
System.out.println("The root = " + root.getValue());
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
while(!queue.isEmpty()){
TreeNode node = queue.poll();
ArrayList<TreeNode> children = node.getChildren();
for (int i = 0; i < children.size(); i++) {
TreeNode child = children.get(i);
queue.offer(child);
System.out.println("Parent "+ node.getValue()+ " has children = "+ child.getValue());
}
}
}
}
At the time I run, I get output like,
The root = 2
Parent 2 has children = 3
Parent 2 has children = 1
Parent 1 has children = 0
Anyone can help me to correct how do I miss the other children?
Update
I write it based on the other answer which seems simpler.
public static TreeNode buildGraph1(int[] T, int K) {
final int N = T.length;
TreeNode[] nodes = new TreeNode[N];
for (int i = 0; i < N; i++) {
nodes[i] = new TreeNode(i);
}
/*
T[children] = parent if the children != K
T[0] = 1
T[1] = 2
T[2] = 3
T[3] = 3
T[4] = 2
T[5] = 1
T[6] = 4
2 - 3
/ \
1 4
/ | |
0 5 6
* */
TreeNode root = nodes[K];
int value = root.getValue();
if (T[K] != K) {
nodes[K].addChild(nodes[T[K]]);
}
for (int i = 0; i < T.length; ++i) {
if (K == i) {
continue;
}
if (T[i] != i) {
nodes[T[i]].addChild(nodes[i]);
}
}
return root;
}
The output is provided below:
The root = 2
Parent 2 has children = 3
Parent 2 has children = 1
Parent 2 has children = 4
Parent 1 has children = 0
Parent 1 has children = 5
Parent 4 has children = 6
I'm writing a program to find the longest path for a DAG with input from standard in.I finally got it to compile, with it saying it is using unchecked or unsafe operations due to my Array list, but I am getting an index out of bounds error and it feels like I have tried changing every loop I must be missing something, thanks in advanced for any tips.
Here is my code:
import java.io.*;
import java.util.*;
public class countLongPaths
{
static final int NINF = Integer.MIN_VALUE;
public class AdjListNode
{
private int v;
private int weight;
AdjListNode(int inV, int inW)
{
v = inV;
weight = inW;
}
int getV()
{
return v;
}
int getWeight()
{
return weight;
}
}//end of adj list class
public class Graph
{
private int V;
private LinkedList<AdjListNode>adj[];
//set up graph with given number of verticies
Graph(int v)
{
V=v;
adj = new LinkedList[V];
for (int i = 0; i < v; ++i)
adj[i] = new LinkedList<AdjListNode>();
}
//function to add edges to graph
void addEdge(int u, int v, int weight)
{
AdjListNode node = new AdjListNode(v,weight);
adj[u].add(node);// Add v to u's list
}
//function to set order to go through vertices
void setOrder(int v, Boolean visited[], Stack stack)
{
//Set node to visited when on it
visited[v] = true;
Integer i;
//for all nodes connected to current repeat
Iterator<AdjListNode> it = adj[v].iterator();
while (it.hasNext())
{
AdjListNode node =it.next();
if (!visited[node.getV()])
setOrder(node.getV(), visited, stack);
}
//Once done with current add it to the stack
stack.push(new Integer(v));
}
//function to find longest paths from s
int longestPath()
{
Stack stack = new Stack();
int LP[] = new int[V];
//set all vertices to unvisited
Boolean visited[] = new Boolean[V];
for(int i = 1; i <= V; i++)
visited[i] = false;
//call set order function from each vertex
for (int i = 1; i <= V; i++)
{
if(visited[i] == false)
setOrder(i, visited, stack);
}
//initialize distaces to all verices as negative infinity
//set distace to source to 0
LP[1] = 0;
for(int i = 2; i <= V; i++)
LP[i] = NINF;
//go through vertices in order
while(stack.empty() == false)
{
int u = (int)stack.pop();
//update LP for adj vertices
Iterator<AdjListNode> it;
if (LP[u] != NINF)
{
it = adj[u].iterator();
while (it.hasNext())
{
AdjListNode i = it.next();
if(LP[i.getV()] < LP[u] + i.getWeight())
LP[i.getV()] = LP[u] + i.getWeight();
}
}
}
return LP[V];
}
}//end of graph class
//Method to make a new graph
public Graph newGraph(int number)
{
return new Graph(number);
}
public static void main(String[]args)
{
countLongPaths n = new countLongPaths();
int GN = 0;
int count = 1;
Scanner scan = new Scanner(System.in);
GN = scan.nextInt();
while (count<= GN)
{
int N = 0;// nodes
int M = 0;//edges
N = scan.nextInt();
M = scan.nextInt();
//setup a new graph
Graph g = n.newGraph(N);
//set edges for new graph
for(int i = 1; i <= M; i ++)
{
int I = scan.nextInt();
int J = scan.nextInt();
int W = scan.nextInt();
g.addEdge(I, J, W);
}
int dist = 0;
dist = g.longestPath();
System.out.println("graph number: " + count);
System.out.println("longest path: " + dist);
System.out.println("number of longest paths: ");
System.out.println();
count++;
}//end of while
}//end main
}//end program
EDIT 1
with current code this is the error:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 5
at countLongPaths$Graph.<init>(countLongPaths.java:36)
at countLongPaths.newGraph(countLongPaths.java:108)
at countLongPaths.main(countLongPaths.java:127)
As your stack trace says, the exception occurs in your Graph class constructor.
More specifically it happens inside the only line in your loop:
adj = new LinkedList[V];
for (int i = 0; i <= v; ++i)
adj[i] = new LinkedList<AdjListNode>();
Assuming you've meant both lowercase v and uppercase V to be the same variable, you're defining an array of size V which is indexed from 0 to V-1, but you're running on it from 0 to V (your condition is i <= V), which is why you're getting an IndexOutOfBoundsException.
Simply change the loop's condition (remove the =):
for (int i = 0; i < v; ++i)
I am supposed to create a method that calculates the average. I can't figure out why i am having so much trouble. My list has a set of random numbers generated but i keep getting an error in my method saying " Exception in thread "main" java.lang.ArithmeticException: / by zero
at Node.avg(Node.java:58)
at Node.main(Node.java:51)"
public class Node<T>
{
private T data; // data portion
private Node<T> next; // link to next node
public Node(T dataPortion)
{
data = dataPortion;
next = null;
} // end constructor
public Node(T dataPortion, Node<T> nextNode)
{
data = dataPortion;
next = nextNode;
} // end constructor
public T getData()
{
return data;
} // end getData
public void setData(T newData)
{
data = newData;
} // end setData
public Node<T> getNextNode()
{
return next;
} // end getNextNode
public void setNextNode(Node<T> nextNode)
{
next = nextNode;
} // end setNextNode
public static void main(String[] args)
{
Integer num;
LList<Integer> firstNode = new LList<Integer>();
for (int counter = 0; counter < 5; counter ++)
{
num = new Integer((int)(Math.random() * 100));
firstNode.add(num);
avg(firstNode);
}
}
public static int avg(LList<Integer> firstNode)
{
int count = 0, total = 0;
int avg = total/count;
for (int i = 1; i < 5; i++)
{
total += ((ListInterface<Integer>) firstNode).getEntry(i);
count++;
}
return avg;
You're trying to calculate the average before you find out what the count and the total is.
Right now, you're doing:
int count = 0, total = 0;
int avg = total / count;
// for loop to find count and total
return avg
When you try and find the average, total and count are still equal to zero so naturally you end up with a divide by zero exception. Instead, do the division after the loop:
public static int avg(LList<Integer> firstNode)
{
int count = 0, total = 0;
for (int i = 1; i < 5; i++)
{
total += ((ListInterface<Integer>) firstNode).getEntry(i);
count++;
}
return total / count;
}
You have a bug in here:
int count = 0, total = 0;
int avg = total/count; //HERE
You are initializing count to 0 and then trying to divide by 0 to initialize the avg. That will fail every single time.
you can divid anything by zero
you divided total/count which both are initialized with 0
you should find avg after the for loop
You may want to do the division after the for loop, otherwise it is clear that count is zero:
int count = 0, total = 0;
for (int i = 1; i < 5; i++)
{
total += ((ListInterface<Integer>) firstNode).getEntry(i);
count++;
}
int avg = total/count;
return avg;
Moreover, the average is likely a real number, not an integer. So the calculation is better done as:
double avg = ((double)total) / count;
This is the merge sort algorithm provided by the java book im using, but the code doesnt work. It returns an array with some numbers duplicated that werent in the original number list. Any ideas why this code isnt working, thanks? Edit: The output of running this is: "
7
2
12
4
2
So it duplicates the 2's
2
2
2
4
12
public class Nothing1{
public static void main(String[] args)
{
comp<Integer> c = new comp<Integer>();
Integer[] values1 = new Integer[5];
values1[0] = 7;
values1[1] = 2;
values1[2] = 12;
values1[3] = 4;
values1[4] = 2;
for(int index= 0; index <= values1.length-1; ++index)
{
System.out.println(values1[index]);
}
c.mergeSort(values1);
for(int index= 0; index <= values1.length-1; ++index)
{
System.out.println(values1[index]);
}
}
public static <T extends Comparable<T>> void mergeSort(T[] data)
{
mergeSort(data, 0, data.length-1);
}
private static <T extends Comparable<T>> void mergeSort(T[] data, int min, int max)
{
if(min < max)
{
int mid = (min + max)/2;
mergeSort(data, min, mid);
mergeSort(data, mid+1, max);
merge(data, min, mid, max);
}
}
private static <T extends Comparable <T>>
void merge(T[] data, int first, int mid, int last)
{
T[] temp = (T[])(new Comparable[data.length]);
int first1 = first, last1=mid;
int first2 = mid+1, last2=last;
int index = first1;
while(first1 <= last1 && first2 <= last2)
{
if(data[first1].compareTo(data[first2]) < 0)
{
temp[index] = data[first];
first1++;
}
else
{
temp[index] = data[first2];
first2++;
}
index++;
}
while(first1 <= last1)
{
temp[index] = data[first1];
first1++;
index++;
}
while(first2 <= last2)
{
temp[index] = data[first2];
first2++;
index++;
}
for(index = first; index <=last; index++)
data[index] = temp[index];
}
}
Are you forgetting to change one of variables, arent you?
Imagine you have 4 and 3 in the current to merge array.
Your first1 and last1 is 0
Your first2 and last2 is 1
When you compare it, you enter to the else and copy the 3 to the first position of index, that is right. And then you move first2 one above.
But what about the 4?? You should copy it after the 3, right? Just in the second position of the index.
Maybe Im wrong.
Im sorry, my english is bad.
The error basically comes down to a typo in your merge function:
private static <T extends Comparable <T>>
void merge(T[] data, int first, int mid, int last)
{
T[] temp = (T[])(new Comparable[data.length]);
int first1 = first, last1=mid;
int first2 = mid+1, last2=last;
int index = first1;
while(first1 <= last1 && first2 <= last2)
{
if(data[first1].compareTo(data[first2]) < 0)
{
// the next line has to use indices that can change during this loop
temp[index] = data[first1]; // change in this line first->first1
first1++;
}
else
{
temp[index] = data[first2];
first2++;
}
index++;
}
//...
With the wrong code your array goes through the following conditions:
7 2 12 4 2 (initial state; merge indices 0;1 next)
2 7 12 4 2 (still correct; merge indices 0-1;2 next)
2 2 12 4 2 (error here)
2 2 12 2 4
2 2 2 4 12
In the erroneous merge step the following happens:
copy from index 0 to index 0
copy from index 0 to index 1 (error here: should be copied from index 1)
copy from index 2 to index 2
the error happens, because the data is read from index first, but index first1 is changed
import java.util.*;
public class Main {
static void merge(ArrayList < Integer > orig, ArrayList < Integer > left, ArrayList < Integer > right) {
ArrayList < Integer > temp = new ArrayList < Integer > ();
int ls = left.size();
int rs = right.size();
int i = 0, j = 0, k = 0;
while (i < ls && j < rs) {
if (left.get(i) <= right.get(j)) {
orig.set(k, left.get(i));
i++;
} else {
orig.set(k, right.get(j));
j++;
}
k++;
}
int tempind = 0;
if (i >= ls) {
temp = right;
tempind = j;
} else {
temp = left;
tempind = i;
}
for (int n = tempind; n < temp.size(); n++) {
orig.set(k, temp.get(n));
k++;
}
}
static void merge_sort(ArrayList < Integer > list) {
int len = list.size();
if (len < 2) {
return;
}
ArrayList < Integer > leftHalf = new ArrayList < Integer > ();
ArrayList < Integer > rightHalf = new ArrayList < Integer > ();
int mid = len / 2;
for (int i = 0; i < mid; i++) {
leftHalf.add(list.get(i));
}
for (int i = mid; i < len; i++) {
rightHalf.add(list.get(i));
}
merge_sort(leftHalf);
merge_sort(rightHalf);
merge(list, leftHalf, rightHalf);
}
public static void main(String[] args) {
Random r = new Random();
ArrayList < Integer > x = new ArrayList < Integer > ();
int[] arr = {
9,
8,
4,
5,
2,
7,
1,
3,
0,
2
};
for (int i = 0; i < arr.length; i++) {
x.add(arr[i]);
}
System.out.println(x);
merge_sort(x);
System.out.println(x);
}
}