I am able to create a Max Heap using a function heapify() but when i try to call it again(to delete max and create a sorted array) the program gets stuck/doesn't stop taking input. What's wrong?
Is this a memory problem?If I increase the number of calls by increasing the frequency of for loop it still works fine.
public class HeapSort
{
int[] heap;
public void sort(int length)
{
int temp;
for(int i=length;i>=1;i--)
{
heapify(i,length);
}
//if I try to call heapify again(even once) after this,the program gets stuck
}
public void heapify(int i,int l)
{
int lchild=2*i,rchild,max;
int temp;
while(lchild<=l)
{
rchild=(2*i)+1;
if(rchild<=l)
max=(heap[lchild]>heap[rchild])? lchild:rchild;
else
max=lchild;
if(heap[i]<heap[max])
{
temp=heap[i];
heap[i]=heap[max];
heap[max]=temp;
i=max;
}
lchild=2*i;
}
}
public static void main(String args[]) throws IOException
{
BufferedReader r= new BufferedReader(new InputStreamReader(System.in));
int length=Integer.parseInt(r.readLine());
HeapSort Heap=new HeapSort();
Heap.heap=new int[length+1];
for(int i=1;i<=length;i++)
Heap.heap[i]=Integer.parseInt(r.readLine());
Heap.sort(length);
for(int i=1;i<=length;i++)
System.out.print(Heap.heap[i]+" ");
}
}
Heapify should be done for length/2 iterations because it is like a tree structure.
Here is a complete code for heap sort...This sort array 's'
public class HeapSort {
public static void main(String[] args) {
String s[]={"aaaa","dddd","cccc","gggg","bbbbb"};
AsHeap(s);
HeapSort(s);
for(String x:s){
System.out.println(x);
}
}
public static void AsHeap(String s[]){
for( int i = s.length / 2; i >= 0; i-- ){
DownHeap( s, i, s.length );
}
}
public static void HeapSort(String[] s){
for(int i=s.length-1;i>0;i--){
swap(s,0,i);
DownHeap(s,0,i);
}
}
public static int getLeftChildIndex(int i){
return 2 * i + 1;
}
private static void DownHeap(String[] s, int i, int length) {
int indexOfChild;
String temp;
for(temp=s[i];getLeftChildIndex(i)<length;i=indexOfChild){
indexOfChild=getLeftChildIndex(i);
if(indexOfChild !=length-1 && s[indexOfChild].compareTo(s[indexOfChild+1])<0){
indexOfChild++;
}
if(temp.compareTo(s[indexOfChild])<0){
s[i] = s[indexOfChild];
} else{
break;
}
}
s[i] = temp;
}
public static void swap(String s[],int x,int y){
String temp=s[x];
s[x]=s[y];
s[y]=temp;
}
}
The while loop isn't terminating when there is no swap between the parent and the child(i.e. the parent is greater than the child).
The value of i(just above main method) doesn't change when parent is greater. Simply taking the line i=max outside the if block [if(heap[i]
Also,is there any sequence to learn Algorithms?If so,kindly guide me.
Thank you.
Related
I was asked to write a class NumberOcc with these methods:
-method getNbOcc which takes as arguments a string str and a character 'c' and return the number of occurence of the character 'c'.
-method dspNbOcc which displays the value returned by getNbOcc
-method getNbVoy which returns the number of vowel inside a string str
-method dspNbVoy which displays the value returned by getNbVoy
The problem is the value returned by getNbVoy is wrong, example: for str=stackexchange it returns 34 vowels.
public class NumberOcc {
static int count1=0;
static int count2=0;
public static int getNbOcc(String str, char c) {
for(int i=0;i<str.length();i++) {
if (str.charAt(i)==c)
count1++;}
return count1;
}
public static void dspNbOcc() {
System.out.println(count1);
}
public static int getNbVoy(String str) {
String vowel="aeiouy";
for(int j=0;j<vowel.length();j++) {
count2+=getNbOcc(str,vowel.charAt(j));}
return count2;
}
public static void dspNbVoy() {
System.out.println(count2);
}
}
TestClass
public class TestNumberOcc {
public static void main(String[] args) {
String str="stackexchange";
NumberOcc.getNbOcc(str, 'e');
NumberOcc.dspNbOcc();
NumberOcc.getNbVoy(str);
NumberOcc.dspNbVoy();
}
}
Thanks for helping
Remove the static fields, pass the values to the methods. And use them to display the results. Like,
public static int getNbOcc(String str, char c) {
int count = 0;
for (int i = 0; i < str.length(); i++) {
if (str.charAt(i) == c) {
count++;
}
}
return count;
}
public static void dspNbOcc(String str, char c) {
System.out.println(getNbOcc(str, c));
}
public static int getNbVoy(String str) {
int count = 0;
char[] vowels = "aeiouy".toCharArray();
for (char ch : vowels) {
count += getNbOcc(str.toLowerCase(), ch);
}
return count;
}
public static void dspNbVoy(String str) {
System.out.println(getNbVoy(str));
}
And then testing everything is as simple as
public static void main(String[] args) {
String str = "stackexchange";
NumberOcc.dspNbOcc(str, 'e');
NumberOcc.dspNbVoy(str);
}
the issue is you're not initializing your count1 (nor count2, but that bug doesn't affect anything in this case) at the beginning of your count method... add this line to the beginning of your getNbOcc method before the loop:
public static int getNbOcc(String str, char c) {
count1 = 0; // add this line
for(int i=0;i<str.length();i++) {
The solution is to apply what you did in your countLetterInString function to countVowelsInString. Just remember to use local variables. You will run into issues with static/global variables if the function is called more than once, but local variables will work the same way every time.
public static int countVowelsInString(String str) {
String vowels = "aeiouy";
// Move counter into the function
int numVowels = 0;
for(int j = 0;j<vowel.length();j++) {
numVowels += getNbOcc(str, vowel.charAt(j));
}
return numVowels;
}
Whenever I give the size of array more than 3, my program gives me StackOverflowError.
package database;
import java.util.Scanner;
public class The_Maximum_Subarray {
int a[];
public The_Maximum_Subarray(int size) {
a=new int[size];
}
public int maxsubArray(int[] a,int li,int ui)
{
if(ui ==li)
return a[li];
int m=(ui-li)/2;
int leftMaxSubarray=maxsubArray(a, li, m);
int rightMaxSubarray=maxsubArray(a, m+1, ui);
int leftSum=0,rightSum=0,sum=0;
for(int i=m;i>=li;i--)
{
sum+=a[i];
if(sum>leftSum)
leftSum=sum;
}
sum=0;
for(int i=m+1;i<=ui;i++)
{
sum+=a[i];
if(sum>rightSum)
rightSum=sum;
}
sum=leftSum+rightSum;
if(rightMaxSubarray>=leftMaxSubarray && rightMaxSubarray>=sum)
return rightSum;
else if(leftMaxSubarray>=rightMaxSubarray && leftMaxSubarray>=sum)
return leftSum;
else
return sum;
}
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
int size=sc.nextInt();
The_Maximum_Subarray obj=new The_Maximum_Subarray(size);
for(int j=0;j<size;j++)
obj.a[j]=sc.nextInt();
System.out.println(obj.maxsubArray(obj.a, 0, size-1));
}
}
Can anyone tell me why it's giving me this exception for this small size array ?
From your question:
Can anyone tell me why its giving me this exception for this small size array ?
For the part Why it is causing??
According to the java language specifications for java.lang.StackOverflowError, this error occurs when an application recurses too deeply.
This recursion results in filling the stack and it tries to exceed the limit of the stack which is Xs.
Take a simple example:
class StackOverflowDemo {
private void causeOverflow(int i) {
causeOverflow(i);
System.out.println(i);
}
public static void main(String args[]) {
StackOverflowDemo demo = new StackOverflowDemo();
demo.causeOverflow(5);
}
}
Here, the System.out.println(i) will be called recursively i.e it will be pushed to the stack when it is called.
Here I am working on the following problem where we are given n types of coin denominations of values v(1) > v(2) > ... > v(n) (all integers) The following code tries to find the minimum number of coins that are required to make a sum-C. Here the C is 100(see main function).When I run the code, error--"java.lang.StackOverflowError" comes. Please help.
import java.util.ArrayList;
public class Problem2 {
public static int count=4;
public static int []v={25,10,5,1}; //Array storing denominations
private static int findminimum(ArrayList<Integer> v2) {
int count=v2.get(0);
for(int i=0;i<v2.size();i++)
{
if(count>v2.get(i))
{
count=v2.get(i);
}
}
return count;
}
public static int countmincoins(int n)
{
int t;
if(n<0)
{
t=Integer.MAX_VALUE-100 ;
}
if(n==0)
{
t= 0;
}
else
{
ArrayList<Integer> a=new ArrayList<Integer>();
for(int i=0;i<v.length;i++)
{
int temp=0;
temp=countmincoins(n-v[i])+1; //Stackoverflow error
a.add(temp);
}
t=findminimum(a);
}
return t;
}
public static void main(String args[])
{
System.out.println(countmincoins(100));
}
}
If you use recursion then you need to reach a condition to terminate the recursion. But in your code I do not seen any termination logic. Thats why, it get to infinite loop and StackOverflowException. In your code you use following code to terminate.
if(n==0)
{
t= 0;
}
But here n may not be zero. Becuase countmincoins(n-v[i]) do not ensure you to n will be 0.
Your code is infinite cause t will never be <0 or ==0 given that the values in the array and the condition (n - v[i] )+1, v[i] will always return the same value in every call to the method, therefore infinite recursion.
If your not restricted to using recursion the following would be much simpler:
public static int[] denominations = {25,10,5,1};
public static int minimumCoins(int amount){
int total = 0;
for(int denomination: denominations){
while(amount - denomination >= 0){
amount -= denomination;
total++;
}
}
return total;
}
public static void main(String args[])
{
System.out.println(minimumCoins(98));
}
Is there a hack to print the first n fibonacci numbers without calling a loop
for(int i=1; i<n; i++)
System.out.println(computeF(n));
from the main program?
public static int computeF(int n)
{
if(n==0)
{
return 0;
}
else if(n==1)
{
return 1;
}
else
{
return computeF(n-1)+computeF(n-2);
}
}
There might be a way to print the intermediate values in recursion which will print the fibonacci numbers.
You could use tail recursion.
public class Fid
{
static int n1=0;
static int n2=1;
static int nex=0;
public static void fb(int n)
{
if(n<10)
{
if(n==0)
{
System.out.print(" "+n);
n++;
fb(n);
}
else
if(n==1)
{
System.out.print(" "+n);
n++;
fb(n);
}
else{
nex=n1+n2;
System.out.print(" "+nex);
n1=n2;
n2=nex;
n++;
fb(n);
}
}
}
public static void main(String[] args)
{
fb(0);
}
}
using recursion:-
class FibonacciRecursion
{
private static int index = 0;
private static int stoppingPoint = 9;
public static void main (String[] args)
{
int n1 = 0;
int n2 = 1;
fibonacciSequence(n1, n2);
}
public static void fibonacciSequence(int n1, int n2)
{
System.out.println("index: " + index + " -> " + n1);
// make sure we have set an ending point so this Java recursion
// doesn't go on forever.
if (index == stoppingPoint)
return;
// make sure we increment our index so we make progress
// toward the end.
index++;
fibonacciSequence(n2, n1+n2);
}
}
//Java program to print Fibonacci Series up to n terms given by user without using loop
import java.util.* ;
public class Fibonacci
{
public static void main(String[] arguments)
{
Scanner s = new Scanner(System.in);
System.out.print("Enter the no of terms :");
int no_of_terms= s.nextInt(),a=1,b=0,c=0,count=1;
System.out.print("0 ");//printing the first term
fib(no_of_terms,a,b,c,count);}
public static void fib(int no_of_terms,int a,int b,int c,int count)
{
//when value of count will be equal to the no of terms given by user the program will terminate
if (count==no_of_terms)
System.exit(0);
else
{
count++;
System.out.print(a+" ");
c=b;
b=a;
a=b+c;//calculating the next term
fib(no_of_terms,a,b,c,count);//calling the function again with updated value
}
}
}
import java.util.*;
public class Fibonacci{
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("Enter a no.");
int n= sc.nextInt(),a=1,b=0,c=0;
num(n,a,b,c);
}
public static void num(int n,int a,int b,int c){
if(a<=n){
System.out.println(a);
c=b;
b=a;
a=b+c;
num(n,a,b,c);
}
}
}
I have written the code but it displays Stackoverflowerror message.
class Sum
{
int ans=0,temp,temp2;
int getsum(int no)
{
if(no>0)
{
temp=no % 10;
ans=ans + temp;
getsum(no/10);
}
else
{
return ans;
}
}
}
class recsum
{
public static void main(String args[])
{
Sum s=new Sum();
int no,len;
len=args.length;
if(len==0)
{
System.out.println("No argruments are given ! ");
}
else
{
no=Integer.valueOf(args[0]).intValue();
System.out.println("Sum of digits= " + s.getsum(no));
}
}
}
You are over-complicating things a lot in your code. Here is a simpler working example:
public static int getSum(final String[] args, final int index) {
if (index < args.length) {
return Integer.valueOf(args[index]) + getSum(args, index + 1);
} else {
return 0;
}
}
public static void main(String[] args) {
if (args.length == 0) {
System.out.println("You need to provide numbers as arguments.");
}
final int sum = getSum(args, 0);
System.out.println("Sum: " + sum);
}
You are supposed to be recursive, this is in the getSum function, because it is calling itself with differing parameters.
In recursive functions, you always need to have an exit branch that causes the calling to stop.
As sums won't change if you add 0 this can be exploited for a very clean exit.
The Stack overflow is normally because you never bottom out of the recursion.
Change class Sum to this:
class Sum {
int ans = 0, temp = 0;
int getsum(int no) {
if((no/10)-.5 >= 1)
ans += getsum(no/10);
else
return ans;
}
}
I'm not completely sure if this will work, and I can't compile it right now. I think this is one way to do it, but again, I'm not completely sure.
Program: Write a program to use Command Line Arguments.
class Sumnum1
{
int i,t,num,sum=0;
void getData(String s)
{
num=Integer.parseInt(s);
}
int digitSum()
{
for(i=num;i>=1;i=i/10)
{
t=i%10;
sum=sum+t;
}
return sum;
}
public static void main(String arg[])
{
int ds=0;
Sumnum1 obj=new Sumnum1();
obj.getData(arg[0]);
ds=obj.digitSum();
System.out.println("sum of digit="+ds);
}
}
BY :ANKIT AGRAWAL (A.A.)