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);
Related
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.
In below code string is passed in a method with numbers separated by space,
now we need to provide sum of smallest two numbers in the string.
public class SumNearZero {
public static int SumNearZero(String s) {
String temp=s;
int t1=0;
for (int i = 0; i <s.length(); i++) {
if(temp.contains(" "))
{
t1++;
temp=temp.substring(temp.indexOf(" ")+1);
}
}
int a[]=new int[++t1];
int index=0;
for(int i=0; i<s.length(); i++)
{
if(s.contains(" "))
{
a[index]=Integer.parseInt(s.substring(0,s.indexOf(" ")));
s=s.substring(s.indexOf(" ")+1);
index++;
}
}
a[index]=Integer.parseInt(s);
for (int i = 0; i < a.length; i++) {
for(int j=0; j<a.length-1; j++)
{
int c=a[j],n=a[j+1];
if(c>n)
{
int t=c;
a[j]=n;
a[j+1]=t;
} } }
int result=a.length>1 ? a[0]+a[1]:a[0];
return result;
}
public static void main(String[] args) {
System.out.println(SumNearZero("35 96 10 20 5"));
}
}
Above code is working fine but i want to reduce the code. if you provide some suggestion regarding this, I'll be happy to learn from you.
Restrictions : use of Collections, predefined methods e.g(String.split(),Arrays.sort()...)
I would suggest you not perform your calculation and display in a constructor, create a static method and invoke it. Next, in that method, create a List of Integer by iterating the substrings generated by splitting your input on one (or more) white space characters. Then, sort the List. Finally, return the sum of the first two elements1. It's also a good to do some error checking for one number (or no numbers). That might look something like
public static int sumNearZero(String s) {
List<Integer> al = new ArrayList<>();
for (String str : s.split("\\s+")) {
al.add(Integer.parseInt(str));
}
if (al.isEmpty()) {
return 0;
}
Collections.sort(al);
if (al.size() == 1) {
return al.get(0);
}
return (al.get(0) + al.get(1));
}
Then invoke it like
public static void main(String[] args) {
System.out.println(sumNearZero("35 96 10 20 5"));
}
I get (as I expected)
15
1once sorted the first two are the minimum, and the last two are the maximum
You can make it faster by using for each loop instead of for loop every time, it is more recommended and faster approach whenever loop is increasing for array, lists etc.
Plus more you can get all numbers in string by using split function which retrives you array of those numbers.and then you can put your logic for getting small numbers.this will reduce counting and increase speed highly in general if you want to learn about optimization then this is definitive guide i suggest you to go through it. and see this answer.
Looks like an exercise, so not giving actual code.
Use String.split and Arrays.sort
I am writing a program that will add 2 arrays that are 40 elements long together. I have to keep the add() method as a HugeInteger (can’t change it to a integer) so when I try to return the sum of the 2 integers it gives me “HugeInteger#77e1ee5d”. Could someone let me know what this means and also tell me how I could fix it.
Thank you
public class HugeInteger {
private int[] integer ;
public HugeInteger(int num[]){
integer =new int [40];
for(int x=1; x<=39; x++){
integer[x]= num[x];
}
}
public void parse(String s){
for(int i=0; i<=s.length(); i++){
integer[i]=Integer.parseInt(s.substring(i,i+1));
}
}
public HugeInteger add(HugeInteger a1){
HugeInteger sum = new HugeInteger(integer);
int cary=0;
for (int i=39; i>=0; i--){
sum.integer[i]=integer[i]+a1.integer[i]+cary;
if(sum.integer[i]>=10){
cary=1;
sum.integer[i]-=10;
}else{
cary=0;
}
}
return sum;
}}
//This is my test program
public class HugeIntegerTest {
public static void main(String[] args) {
int []num={1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
HugeInteger hi= new HugeInteger(num);
System.out.println("Addition: "+hi.add(hi));
}
}
That's the output of the default Object.toString() method. You need to override toString and provide a better implementation yourself. An example:
#Override
public String toString() {
StringBuilder builder = new StringBuilder(integer.length);
for(int digit : integer) {
builder.append(digit);
}
return builder.toString();
}
Note that this implementation does not trim leading zeros, i.e. it will print "0000...000123" instead of just "123". This is left as an exercise for the reader, erm, programmer. ;-)
Another tip: in your constructor, your loop should start at i=0. Otherwise the most significant digit (integer[0]) will always be zero, for example your test program would give you a HugeInteger representing 0 instead of 1039.
You have to write your own version of the toString() for HugeInteger to make it display correctly.
I need to generate a program that generates the Fibonacci Sequence
Here is what I have so far:
import java.util.Scanner;
public class FibonacciRunner
{
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
System.out.println("Enter n:");
int n = in.nextInt();
EP64 fg = new EP64();
for (int i = 1; i <= n; i++)
System.out.println(fg.nextNumber());
}
}
public class EP64
{
public static void nextNumber(int n)
{
int fold1 = 1;
int fold2 = 1;
int fnew = fold1 + fold2;
fold1 = fnew;
}
}
I get an error on:
System.out.println(fg.nextNumber());
saying:
method nextNumber in class EP64 cannot be applied to given types:
required: int
found: no arguments
reason: actual and formal argument lists differ in length
and can someone also tell me if I am doing this program right? If not, help! I looked at other similar questions but I cannot make much sense of them
Thank you all!
method nextNumber in class EP64 cannot be applied to given types: required: int found: no arguments reason: actual and formal argument lists differ in length
Your
public static void nextNumber(int n)
^^^^^^^
says that any call to the method must provide an integer as argument. But here:
System.out.println(fg.nextNumber());
^^ you need to add an integer argument
you violate this by providing no argument.
As your code reads now, I'd probably drop the int n argument.
and can someone also tell me if I am doing this program right?
Naah, not really...
fold1 and fold2 should probably be member variables (so they don't get reset in every call to the method),
You're forgetting to update fold2 (you only update fold1),
Also, you probably want to return an int from the nextNumber method.
Read up on
Official Java Tutorial: Defining Methods
You are calling a static method to a object reference instead of the class itself.
And
Not passing any argument at all for nextNumber() method.
Make the method non-static as :
public void nextNumber(int n) {}
Pass arg to the method as :
for (int i = 1; i <= n; i++)
System.out.println(fg.nextNumber(n));
And also don't forget to return the processed number from your nextNumber method,which you collecting in System.out.println.
Your declaration of nextNumber says it takes an int argument, but you are calling it with no arguments.
Also, your code isn't going to do what you want. You probably should make fold1 and fold2 members of class EP64 and make the method an instance method rather than a static method. You also need to do fold2 = fold1; before you update fold1.
Finally, you need to declare nextNumber to return an int value, and then actually have it return an int value.
You have two problems. Firstly, your method doesn't return anything, i.e. it is void. You need to make it int and add a return fnew; at the end. The other problem is you are starting from scratch every time, it will return 2 each time. You need to make fold1 and fold2 fields by moving them above the nextNumber line. Oh, and drop the int n argument as it doesn't do anything.
I agree on the diagnostics of the other posts, but don't suggest a member variable, but a rename and local variables.
You can ask for the 5th Fibonacci-Number with 5 calls to
fib.next ();
or with a single call to
fib (5);
Since the fibonacci-sequence increases very rapidly, you have very few calls (54) before hitting the overflow boundary. So if you repeatedly recalc the same sequence, to print the sequence, it's not a big problem. A recursive solution would be fine.
Btw.: EP64 is a very bad name.
I think this is enough:
import java.util.Scanner;
public class Fibnocci
{
public static void main(String []abc)
{
int a=0,b=1,c;
Scanner in=new Scanner(System.in);
System.out.print("Enter the Range: ");
int n= in.nextInt();
System.out.print(a+" "+b);
for(int i=0;i<n-2;i++) //n-2 because we are showing 0,1 initially.
{
c=a+b;
System.out.print(" "+c);
a=b;
b=c;
}
}
}
If you want to call this as a method then:
import java.util.Scanner;
public class Fibnocci
{
public static void main(String []abc)
{
Scanner in=new Scanner(System.in);
System.out.print("Enter the Range: ");
int n= in.nextInt();
callFibonocci(n);
}
public static void callFibonocci(int n)
{
int a=0,b=1,c;
System.out.print(a+" "+b);
for(int i=0;i<n-2;i++) //n-2 because we are showing 0,1 initially.
{
c=a+b;
System.out.print(" "+c);
a=b;
b=c;
}
}
}
You can call this method out of the class;
// Fibnocci Using c#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CodeProject
{
class FibnocciSeries
{
public int[] FibonacciArray(int length)
{
int[] fseries = new int[length];
fseries[0] = 0;
fseries[1] = 1;
if (length == 0)
return null;
//Iterating through the loup to add adjacent numbers and create the memeber of series
for (int i = 2; i < length; i++)
{
fseries[i] = fseries[i - 1] + fseries[i - 2];
}
return fseries;
}
}
}
////////////////////
class Program
{
static void Main(string[] args)
{
FibnocciSeries fb = new FibnocciSeries();
Console.WriteLine("Please Enter Integer Length of Fibnocci series");
int length = Convert.ToInt32(Console.ReadLine());
int[] result = fb.FibonacciArray(length);
foreach(int i in result)
Console.Write(i.ToString()+ " ");
Console.ReadLine();
}
}
|
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;
}