My DFS is undergoing stackoverflow while finding the bridge in the graph. In this question I am provided with the edges along with their id's in a graph having vertices (1 to n ). I need to find whether the edge associated with given id (q queries) is a bridge or not. Please help me understand what's wrong with my code:
import java.util.*;
class TestClass {
static int time=0;
static class pair{
int v,id;
pair(int v,int id){
this.v=v;
this.id=id;
}
}
static class graph{
static int v;
static ArrayList<pair>[] adj;
graph(int v){
this.v=v;
adj=new ArrayList[v+1];
for(int i=1;i<=v;i++)
adj[i]=new ArrayList<pair>();
}
static void addedge(int u,int v,int id){
adj[u].add(new pair(v,id));
adj[v].add(new pair(u,id));
}
}
static void dfs(graph g,int[] disc,int[] low,int[] parent,boolean[] visited,boolean[] bridge,int src){
visited[src]=true;
disc[src]=low[src]=++time;
for(pair p:g.adj[src]){
int i=p.v;
int id=p.id;
if(!visited[i]){
//System.out.println(i);
parent[i]=src;
dfs(g,disc,low,parent,visited,bridge,i);
low[src]=Math.min(low[src],low[i]);
if(low[i]>disc[src]){
bridge[id]=true;
}
}
else if(parent[src]!=i){
low[src]=Math.min(low[src],disc[i]);
}
}
}
public static void main(String args[] ) throws Exception {
Scanner input=new Scanner(System.in);
int n=input.nextInt();
int m=input.nextInt();
int q=input.nextInt();
graph g=new graph(n);
for(int i=0;i<m;i++){
int u=input.nextInt();
int v=input.nextInt();
int id=input.nextInt();
g.addedge(u,v,id);
}
int[] disc=new int[n+1];
int[] parent=new int[n+1];
int[] low=new int[n+1];
boolean[] visited=new boolean[n+1];
boolean[] bridge=new boolean[m+1];
for(int i=1;i<=n;i++){
if(!visited[i]){
parent[i]=-1;
dfs(g,disc,low,parent,visited,bridge,i);
}
}
while(q-->0){
int i=input.nextInt();
if(bridge[i])
System.out.println("YES");
else
System.out.println("no");
}
}
}
Please help me understand what's wrong with my code
There is too much code for me to read ... and reverse engineer your intent.
A StackOverflowError typically occurs when a recursive algorithm recurses too deeply and fills the stack. For example:
// This is a recursive infinite loop. It will throw SOE
public void callMe() {
callMe();
}
// This is a finite loop but it may throw SOE if 'n' is too big
// or if it is negative
public void countDown(int n) {
if (n != 0) {
countDown(n - 1);
}
}
That's the general idea ...
To find the cause of the problem in your code:
Examine the stacktrace. That will tell you which methods and which lines of code are involved in the deep recursion.
Examine the code, and see if you can spot an obvious error.
Run the code in your IDE's debugger. Set a breakpoint at a key method (involved in the recursion) and use the debugger's function to display local variables to try to understand what is going on. The dfs method would be a good place to set a breakpoint.
If 3 isn't enlightening, add some trace printing to the code to help you figure out what is happening. For example, print the value of src at the start of each dfs call.
Related
cannot able to identify my error, checked a-lot pls go through it it does not produce the correct output,
the code is implementation of quick sort through java.
this code produces the same output as input,
as i am new to java and algorithms I am not able to figure it out.
class Codechef
{
public static void main (String[] args) throws java.lang.Exception
{
int a[]=new int[5];
Scanner s=new Scanner(System.in);
for(int i=0;i<5;i++)
a[i]=s.nextInt();
quick(a,0,4);
for(int i=0;i<5;i++)
System.out.print(a[i]+" ");
}
public static void quick(int a[],int s,int l)
{
if(s<l)
{
System.out.println("in quick");
int pi=part(a,s,l);
quick(a,s,pi-1);
quick(a,pi+1,l);
}
}
public static int part(int a[],int s,int l)
{
System.out.println("in part");
int pivot=a[l];
int pin=s;
for(int i=s;i<l;i++)
{
if(a[i]<=pivot)
{
swap(a[i],a[pin]);
pin++;
}
}
swap(a[pin],a[l]);
System.out.println(pin);
return pin;
}
public static void swap(int a,int b)
{
System.out.println("in swap");
int t;
t=a;
a=b;
b=t;
}
}
Your swap function doesn't work, that's why quick leaves your array untouched.
This addresses exactly your issue: Java: Why does this swap method not work? -- those are fundamental concepts and it more than pays to understand them.
Anyway, since you're working on an array, you could go about it like this:
/** Swap array[i] and array[j] */
public static void swap(int[] array, int i, int j)
{
int t = array[i];
array[i] = array[j];
array[j] = t;
}
Note: I haven't delved into the logic of your sorting -- you may be able to figure it out once this is fixed.
You're not actually swapping array elements when calling swap. All the method is doing is swapping the parameters.
You could either pass the array into the swap method along with the indices, or more practically, just copy your swap code into your part method
I have no idea whether you are learning QuickSort, but if you want a quick way to sort a list of numbers, I'd suggest you to use an ArrayList, which is basically declared like this:
ArrayList<Integer> yourArrayList = new ArrayList<Integer>();
Among the diamond operator (<>) insert the data type, in this case is Integer, but you could also insert Double, to obtain a decimal result.
After you declared it, you have to add your numbers:
yourArrayList.add(1)
yourArrayList.add(3);
etc...
When you are done use Collections.sort(yourArrayList);
I hope I was clear, this is the code to use it:
ArrayList<Integer> yourArrayList = new ArrayList<Integer>();
yourArrayList.add(10);
yourArrayList.add(3);
yourArrayList.add(7);
yourArrayList.add(-3);
Collections.sort(yourArrayList);
System.out.println(yourArrayList);
I was trying to execute the below code. It ran without any compilation errors. But the remove(int index) method is not working as expected.
import java.util.*;
public class Stones {
static int findLastStoneWeight(ArrayList<Integer> weight)
{
while(true)
{
Collections.sort(weight);
int n=weight.size();
if (n==1)
return weight.get(0);
else if(weight.get(n-1)>weight.get(n-2))
{
int temp1=weight.get(n-1);
int temp2=weight.get(n-2);
weight.add(n-2,temp1-temp2);
weight.remove(n-1);
System.out.println(weight.size()); //The new size of weight should be decreased by 1 but it does not!!
}
else
{
weight.remove(n-1);
weight.remove(n-2);
}
}
}
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
ArrayList<Integer> weight=new ArrayList<Integer>();
System.out.println("Enter the weights:");
while(true)
{
int w=sc.nextInt();
if(w<0)
break;
weight.add(w);
}
int lswt=findLastStoneWeight(weight);
System.out.println("Last stone weight:"+lswt);
}
}
When I used the remove(int index) method on the ArrayList weight the size of the ArrayList should get reduced by 1 but it remains the same. Why?
in the else if branch you noted, you first add an element to the weight ArrayList:
weight.add(n-2,temp1-temp2);
and then remove an element:
weight.remove(n-1);
All in all, you've added an element and removed an element, so the size of the list at the end of the method will be same as it was in the metho'd begining.
I'm trying to write a recursive method that accepts an int array, number of elements in the array, and an integer, and returns whether the integer is present as an element in the array.I just can't figure out why I this isn't working for all my test cases. Any help would be much appreciated!
public static boolean search(int[] findIn, int target, int len){
if(len == 0){
return false;
}else if(findIn[len-1] == target){
return true;
}else{
return search(findIn, target, len-1);
}
}
Yes I realize there are better ways other than recursion to do this, but it is required that I do it this way.
My main method looks like this: I'm just hard-coding it for the time being:
int[] arr = {1};
System.out.println(search(arr,1,1));
Testcases:
I am almost certain, that your method parameters are in the wrong order:
Your results hint that you switched the 2nd and 3rd parameter!
Maybe this
static boolean search(int[] findIn, int target, int len)
should actually be
static boolean search(int[] findIn, int len, int target)
From what I can see, that code should work fine so I suspect your problem lies in your test cases rather than here.
One thing I will mention is that use of if-return-else constructs tend to complicate your code unnecessarily.
It's usually better to avoid that with something like:
public static boolean search(
int[] findIn, int target, int len)
{
if (len == 0)
return false;
if (findIn[len-1] == target)
return true;
return search(findIn, target, len-1);
}
I find that a lot easier to follow at a glance than trying to track what if clause I happen to be in at any given moment.
In any case, both it and your version perform fine, at least for small test cases. The first time you pass in a ten-million-element array is probably when you'll discover it's not the best poster child for recursion.
I tried something like this and it is working..
I am using a static instance variable to find the position of number in array.
In stead of returning the position of number you can modify to return a boolean
public class RecSearch {
static int pos=0;
public static void main(String[] args) {
int a[] = {1};
System.out.println(recSearch(a, 0));
System.out.println(recSearch(a, 1));
}
public static int recursiveSearch(int[] arr, int numtoSearch) {
if (pos>=arr.length) {
pos=0;
return -1;
}
if (arr[pos]==numtoSearch)
return (pos+1);
else {
pos++;
return recursiveSearch(arr, numtoSearch);
}
}
}
public class Solution {
public static boolean checkNumber(int input[], int x) {
return check(input,x,0);
}
public static boolean check(int input[],int x,int start){
if(start==input.length)
return false;
if(input[start]==x)
return true;
return check(input,x,start+1);
}
}
I have the following code (it doesn't matter what it does, but for the curious, it's the start of an implementation of a square bending algorithm).
The problem is, it loops for no reason:
import java.util.*;
import java.io.*;
import java.lang.*;
class Solution
{
public static class kll
{
int ni;
int nj;
int pi;
int pj;
int v;
kll(){};
}
public static class g
{
static kll[][] a;
static int wh;
}
public static void f(int i1,int i2,int j1,int j2)
{
int nj1,nj2;
while (g.a[i1][i2].ni!=g.wh && g.a[i1][i2].nj!=g.wh)
{
i1=g.a[i1][i2].ni;
i2=g.a[i1][i2].nj;
}
while (g.a[j1][j2].ni!=g.wh && g.a[j1][j2].nj!=g.wh)
{
j1=g.a[j1][j2].ni;
j2=g.a[j1][j2].nj;
}
while (j1!=0)
{
nj2=g.a[j1][j2].pj;
nj1=g.a[j1][j2].pi;
g.a[i1][i2].ni=j1;
g.a[i1][i2].nj=j2;
g.a[j1][j2].pi=i1;
g.a[j1][j2].pj=i2;
i1=j1;
i2=j2;
j1=nj1;
j2=nj2;
}
g.a[i1][i2].ni=g.wh;
g.a[i1][i2].nj=g.wh;
}
public static void main(String[] args)
{
try
{
FileWriter oos1 = new FileWriter("output.txt");
File inTxt=new File("input.txt");
Scanner kbd = new Scanner(inTxt);
int input=kbd.nextInt();
kbd.close();
int number=(int)Math.pow(4,input);
g.wh=(int)Math.sqrt(number);
g.a=new kll[g.wh+1][g.wh+1];
for(int i=0;i<g.wh+1;i++)
for(int j=0;j<g.wh+1;j++)
g.a[i][j]=new kll();
for(int i=0;i<g.wh;i++)
for(int j=0;j<g.wh;j++)
{
g.a[i][j].ni=g.wh;
g.a[i][j].nj=g.wh;
g.a[i][j].pi=0;
g.a[i][j].pj=0;
g.a[i][j].v=0;
}
int separator=g.wh;
int half;
while(separator>1)
{
half=separator/2;
for(int i=0;i<half;i++)
for(int j=0;j<separator;j++)
f(j,i,j,separator-1-i);
for(int i=0;i<half;i++)
for(int j=0;j<separator;j++)
f(i,j,separator-1-i,j);
separator=half;
}
}
catch (FileNotFoundException ex) {}
catch(IOException ex) {}
}
}
Where have I gone wrong? That is, where is the infinite loop? What is causing it, and how can I fix it?
EDIT:
I have tried the debugger and it showed me that the infinite loop is here:
while (j1!=0)
{
nj2=g.a[j1][j2].pj;
nj1=g.a[j1][j2].pi;
g.a[i1][i2].ni=j1;
g.a[i1][i2].nj=j2;
g.a[j1][j2].pi=i1;
g.a[j1][j2].pj=i2;
i1=j1;
i2=j2;
j1=nj1;
j2=nj2;
}
I don't have any idea why it's infinite. j1 has got to be zero when it takes nj1 which is also zero. What's going wrong?
Simply put, j1 is never set to 0, because nj1 is never set to 0, because g.a[ji][j2].pi is never set to 0.
Place breakpoints and inspect g.a[ji][j2].pi -- you will see that it is never 0, given a particular set of arguments.
In particular, you will want to look at the arguments that feed your f() function that are causing that function to infinitely loop.
Once you have determined the problematic arguments, you can place an if-statement that causes a breakpoint to be hit before that function is called -- if you have not already determined why f() fails.
i know that horners method for polynomial pultiplication is faster but here i dont know what is happening here is code
public class horner{
public static final int n=10;
public static final int x=7;
public static void main(String[] args){
//non fast version
int a[]=new int[]{1,2,3,4,5,6,7,8,9,10};
int xi=1;
int y=a[0];
for (int i=1;i<n;i++){
xi=x*xi;
y=y+a[i]*xi;
}
System.out.println(y);
//fast method
int y1=a[n-1];
for (int i=n-2;i>=0;i--){
y1=x*y+a[i];
}
System.out.println(y1);
}
}
result of this two methods are not same
result of first method is
462945547
and result of second method is
-1054348465
please help
You're using y on the second loop:
y1=x*y+a[i];
This is where writing two function would come in handy - it would be impossible to reuse the same variable.
Look at this loop:
for (int i=1;i<n;i++){
xi=x*xi;
y=y+a[i]*xi;
}
I think you should use
for (int i=0;i<n;i++){
xi=x*xi;
y=y+a[i]*xi;
}