finding the LCM of n numbers - array out of bounds - java

i am trying to find lcm of n numbers and i want my recursion to run upto the last element, but i cant find an efficient method to limit it from going out of bounds at line 41.
please suggest any trick.
import java.io.*;
class lcm
{
static int x=1,k=1;
public static void main(String args[])throws IOException
{
BufferedReader br=new BufferedReader (new InputStreamReader(System.in));
System.out.println("enter the limit");
int n= Integer.parseInt(br.readLine());
System.out.println("enter the numbers");
int L;
int arr[]=new int[n];
for(int i=0;i<n;i++)
arr[i]=Integer.parseInt(br.readLine());
L=lc( arr[0],arr[1],arr,n);
System.out.println(L);
}
static int lc(int min, int max, int arr[], int n)
{
int fact;
if(x<=n-1 )
{
for(int i=1;i<=min;i++)
{
fact=max*i;
if(fact%min==0)
{
k=fact;
break;
}
}
//System.out.println("values of x"+x);
//System.out.println("values of k"+k);
x++;
return lc(arr[x],k,arr,n);
}
else
{
//System.out.println("vale of x"+x);
return k;
}
}
}

i found a solution though i still want to know if the code i wrote is efficient or not?
static int lc(int min, int max, int arr[], int n)
{
int fact;
if(x<n-1 )
{
for(int i=1;i<=min;i++)
{
fact=max*i;
if(fact%min==0)
{
k=fact;
break;
}
}
System.out.println("values of x"+x);
System.out.println("values of k"+k);
x++;
return lc(arr[x],k,arr,n);
}
else
{
min=arr[x];
max=k;
for(int i=1;i<=min;i++)
{
fact=max*i;
if(fact%min==0)
{
k=fact;
break;
}
}
return k;
}
}
}

Related

Unable to retrieve the array in main function in java

enter image description hereThe following is code for the merge sort. I am getting an error on the last line. I have also added a comment. I am unable to retrieve the array returned by the method merge_function(int[] a, int[] b). The error says " non-static method merge_sort(int[],int,int) cannot be referenced from a static context at demo1.Merge.main". Please help..!
public class Merge {
int[] merge_sort(int[] arr, int s, int e){
if(arr.length==1)
return arr;
int m=(s+e)/2;
int []a= merge_sort(arr,s,m);
int []b= merge_sort(arr,m+1,e);
int []c= merge(a,b);
print(arr);
return c;
}
public void print(int[] arr)
{
System.out.println("Elements after sorting:");
for(int i=0;i<arr.length;i++)
{
System.out.print(arr[i]+" ");
}
}
int[] merge(int[] a, int[] b)
{
int i=0,j=0,k=0;
int []r=new int[a.length+b.length];
while(i!=a.length && j!=b.length)
{
if(a[i]<b[j])
{
r[k]=a[i];
i++; j++; k++;
}
else if(a[i]==b[j])
{
r[k]=a[i];
i++; j++; k++;
}
else if(a[i]>b[j])
{
r[k]=b[j];
j++; k++;
}
}
return r;
}
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
System.out.println("Enter the length of an array.");
int n=in.nextInt();
System.out.println("Enter the numbers.");
int arr[]=new int[n];
for(int i=0;i<n;i++)
{
arr[i]=in.nextInt();
}
//error is here
int []r = merge_sort(arr,0,arr.length-1);
}
}
you cannot call non-static methods from a static context without using an instance of the class containing those methods.

Code to print Nth fibonacci number

So this is my assignemt, I have to write a function that accepts a number less than 100 and returns the fibonacci element at that position. I don't understand what is wrong with my code. please note that I wrote only getFibonacciElementAt function code
import java.util.Scanner;
public class FibonacciNumber {
public long getFibonacciElementAt(int index) {
Scanner sc= new Scanner(System.in);
System.out.println("Please enter the number");
int n= sc.nextInt();
if(n<0)
return -1;
int a=0;
int b=1;
int i;
for(i=2; i<=n; i++)
{
int temp=a;
a=b;
b=temp;
}
return a;
}
public void printFibonacciElementAt(int index) {
System.out.println(getFibonacciElementAt(index));
}
public static void main(String[] args) {
if (args.length != 1) {
System.out.println("Exactly 1 inputs required.");
return;
}
try {
int num = Integer.parseInt(args[0]);
FibonacciNumber obj = new FibonacciNumber();
obj.printFibonacciElementAt(num);
} catch (NumberFormatException e) {
System.out.println("Only integers allowed.");
}
}
}
Okay, so re-posting a better recursive version using memoization so runtime of n<=100 is less than 1 second:
public static long getFibonacciElementAt(int n, long[] d) {
if (n == 0 || n == 1)
return n;
if (d[n] == 0)
d[n] = getFibonacciElementAt(n - 1, d) + getFibonacciElementAt(n - 2, d);
return d[n];
}
But once you call the method just pass a new array of the size n+1 as the following:
System.out.println(getFibonacciElementAt(n, new long[n+1]));
You are just exchanging, not adding the previous two numbers. So try following:
int a=0;
int b=1;
int temp;
for(int i=2; i<=n; i++)
{
temp=a+b;
a=b;
b=temp;
}
return b;

unable to fix arrayoutof bound exception

I am getting these errors it's a runtime error; I have no idea why it is happening I tried to find the solution but couldn't find it.
Since I am new in java please help me to find
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 34
at UnionAndIntersection.BinarySearch(UnionAndIntersection.java:90)
at UnionAndIntersection.BinarySearch(UnionAndIntersection.java:96)
at UnionAndIntersection.BinarySearch(UnionAndIntersection.java:100)
at UnionAndIntersection.BinarySearch(UnionAndIntersection.java:100)
at UnionAndIntersection.BinarySearch(UnionAndIntersection.java:100)
at UnionAndIntersection.BinarySearch(UnionAndIntersection.java:100)
at UnionAndIntersection.Union(UnionAndIntersection.java:53)
at UnionAndIntersection.main(UnionAndIntersection.java:26)
please help me to fix this
import java.util.Scanner;
import java.util.Arrays;
class UnionAndIntersection {
public static void main(String args[]) throws Exception {
int arr1[]=new int[20];
int arr2[]=new int[20];
int m,n,i,j;
Scanner sc=new Scanner(System.in);
System.out.println("Enter no of elements in first array");
m=sc.nextInt();
System.out.println("Enter no of element of second Array");
n=sc.nextInt();
System.out.println("Enter Elements in 1st Array");
for(i=0;i<m;i++) {
arr1[i]=sc.nextInt();
}
System.out.println("Enter Elements in 2nd Array");
for(j=0;j<n;j++) {
arr2[j]=sc.nextInt();
}
UnionAndIntersection ui=new UnionAndIntersection();
ui.Union(arr1,arr2,m,n);
ui.Intersection(arr1,arr2,m,n);
}
void Union(int arr1[],int arr2[],int m,int n) {
if(m>n) {
int tempa[]=arr1;
arr1=arr2;
arr2=tempa;
int temp=m;
m=n;
n=temp;
}
Arrays.sort(arr1);
for(int i=0;i<m;i++)
{
System.out.println(arr1[i]+"");
}
for(int i=0;i<2;i++)
{
if(BinarySearch(arr1,0,m-1,arr2[i])== -1)
System.out.println(arr2[i]+"");
}
}
void Intersection(int arr1[],int arr2[],int m,int n)
{
if(m>n)
{
int tempa[]=arr1;
arr1=arr2;
arr2=tempa;
int temp=m;
m=n;
n=temp;
}
Arrays.sort(arr1);
for(int i=0;i<m;i++)
{
System.out.println(arr1[i]+"");
}
for(int i=0;i<2;i++)
{
if(BinarySearch(arr1,0,m-1,arr2[i])!= -1)
System.out.println(arr2[i]+"");
}
}
int BinarySearch(int arr[],int l,int h,int x)
{
if(h>=1)
{
int mid=l+h-1/2;
if(arr[mid]==x)
{
return mid;
}
else if(arr[mid]>x)
{
return BinarySearch(arr,l,mid-1,x);
}
else{
return BinarySearch(arr,mid+1,h,x);
}
}
return -1;
}
}
You set the size of the array to 20, not to the user input. If the user puts in a number larger than 20, you get the error.
So change:
int arr1[]=new int[20];
int arr2[]=new int[20];
to
int arr1[]=new int[m];
int arr2[]=new int[n];

Quick Sort in java in not running if the first element is the largest while considering first element as pivot

I have written a code in java for quicksort while considering the first element as pivot. The code is giving an ArrayOutOfBoundsException if I consider the first element as the largest element of the array. While the logic is running perfectly when implemented the same logic in C++.
import java.util.Scanner;
class QSort
{
private int n;
private int a[] = new int[n];
public QSort(int[] x)
{
n = x.length;
a = x;
}
private int qs(int low,int up)
{
int pivot = a[low];
int p = low+1,q = up;
while(q>=p)
{
while(pivot>=a[p])
p++;
while(pivot<a[q])
q--;
if(q>p)
{
a[p]=a[p]+a[q]-(a[q]=a[p]); //swapping(a[p],a[q])
p++;
q--;
}
}
a[low]=a[low]+a[q]-(a[q]=a[low]); //swapping(a[low],a[q])
return q;
}
public void quicksort(int low,int up)
{
if(low<up)
{
int i = qs(low,up);
quicksort(low,i-1);
quicksort(i+1,up);
}
}
public void print()
{
System.out.println("\nThe sorted array is :");
for(int i=0; i<a.length; i++)
{
System.out.println(a[i]);
}
}
}
class Quick
{
public static void main(String args[])
{
System.out.print("\nEnter the no. of values : ");
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int x[] = new int[n];
System.out.println("\nEnter the elements :");
for(int i=0; i<n; i++)
x[i] = sc.nextInt();
QSort s = new QSort(x);
s.quicksort(0,n-1);
s.print();
}
}

Mergesort Implementation.. Counting number of inversions in an array

I'm taking an online class on Algorithms and trying to implement a mergesort implementation of finding the number of inversions in a list of numbers. But, I cant figure what Im doing wrong with my implementation as the number of inversions returned is significantly lower than the number I get while doing a brute force approach. Ive placed my implementation of the mergesort approach below
/**
*
*/
package com.JavaReference;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class ReadFile {
public static void main(String args[]){
int count=0;
Integer n[];
int i=0;
try{
n=OpenFile();
int num[] = new int[n.length];
for (i=0;i<n.length;i++){
num[i]=n[i].intValue();
// System.out.println( "Num"+num[i]);
}
count=countInversions(num);
}
catch(IOException e){
e.printStackTrace();
}
System.out.println(" The number of inversions"+count);
}
public static Integer[] OpenFile()throws IOException{
FileReader fr=new FileReader("C:/IntegerArray.txt");// to put in file name.
BufferedReader textR= new BufferedReader(fr);
int nLines=readLines();
System.out.println("Number of lines"+nLines);
Integer[] nData=new Integer[nLines];
for (int i=0; i < nLines; i++) {
nData[ i ] = Integer.parseInt((textR.readLine()));
}
textR.close();
return nData;
}
public static int readLines() throws IOException{
FileReader fr=new FileReader("C:/IntegerArray.txt");
BufferedReader br=new BufferedReader(fr);
int numLines=0;
//String aLine;
while(br.readLine()!=null){
numLines++;
}
System.out.println("Number of lines readLines"+numLines);
return numLines;
}
public static int countInversions(int num[]){
int countLeft,countRight,countMerge;
int mid=num.length/2,k;
if (num.length<=1){
return 0;// Number of inversions will be zero for an array of this size.
}
int left[]=new int[mid];
int right[]=new int [num.length-mid];
for (k=0;k<mid;k++){
left[k]=num[k];
}
for (k=0;k<mid;k++){
right[k]=num[mid+k];
}
countLeft=countInversions(left);
countRight=countInversions(right);
int[] result=new int[num.length];
countMerge=mergeAndCount(left,right,result);
/*
* Assign it back to original array.
*/
for (k=0;k<num.length;k++){
num[k]=result[k];
}
return(countLeft+countRight+countMerge);
}
private static int mergeAndCount(int left[],int right[],int result[]){
int count=0;
int a=0,b=0,i,k=0;
while((a<left.length)&&(b<right.length)){
if(left[a]<right[b]){
result[k]=left[a++];// No inversions in this case.
}
else{// There are inversions.
result[k]=right[b++];
count+=left.length-a;
}
k++;
// When we finish iterating through a.
if(a==left.length){
for (i=b;i<right.length;i++){
result[k++]=right[b];
}
}
else{
for (i=a;i<left.length;i++){
}
}
}
return count;
}
}
I'm a beginner in Java and Algorithms so any insightful suggestions would be great!
I found two bugs:
In countInversions(), when num is split into left and right you assume right has m elements. When num.length is odd, however, it will be m + 1 elements. The solution is to use right.length instead of m.
In mergeAndCount(), handling of the bit where one subarray is empty and the other one still has some elements is not done correctly.
Side note:
There is absolutely no reason to use Integer in your program, except for the Integer.parseInt() method (which, by the way, returns an int).
Corrected code:
/**
*
*/
package com.JavaReference;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class ReadFile {
public static void main(String args[]){
int count=0;
Integer n[];
int i=0;
try{
n=OpenFile();
int num[] = new int[n.length];
for (i=0;i<n.length;i++){
num[i]=n[i].intValue();
// System.out.println( "Num"+num[i]);
}
count=countInversions(num);
}
catch(IOException e){
e.printStackTrace();
}
System.out.println(" The number of inversions"+count);
}
public static Integer[] OpenFile()throws IOException{
FileReader fr=new FileReader("C:/IntegerArray.txt");// to put in file name.
BufferedReader textR= new BufferedReader(fr);
int nLines=readLines();
System.out.println("Number of lines"+nLines);
Integer[] nData=new Integer[nLines];
for (int i=0; i < nLines; i++) {
nData[ i ] = Integer.parseInt((textR.readLine()));
}
textR.close();
return nData;
}
public static int readLines() throws IOException{
FileReader fr=new FileReader("C:/IntegerArray.txt");
BufferedReader br=new BufferedReader(fr);
int numLines=0;
//String aLine;
while(br.readLine()!=null){
numLines++;
}
System.out.println("Number of lines readLines"+numLines);
return numLines;
}
public static int countInversions(int num[]){
int countLeft,countRight,countMerge;
int mid=num.length/2,k;
if (num.length<=1){
return 0;// Number of inversions will be zero for an array of this size.
}
int left[]=new int[mid];
int right[]=new int [num.length-mid];
for (k=0;k<mid;k++){
left[k]=num[k];
}
// BUG 1: you can't assume right.length == m
for (k=0;k<right.length;k++){
right[k]=num[mid+k];
}
countLeft=countInversions(left);
countRight=countInversions(right);
int[] result=new int[num.length];
countMerge=mergeAndCount(left,right,result);
/*
* Assign it back to original array.
*/
for (k=0;k<num.length;k++){
num[k]=result[k];
}
return(countLeft+countRight+countMerge);
}
private static int mergeAndCount(int left[],int right[],int result[]){
int count=0;
int a=0,b=0,i,k=0;
while((a<left.length)&&(b<right.length)){
if(left[a]<right[b]){
result[k]=left[a++];// No inversions in this case.
}
else{// There are inversions.
result[k]=right[b++];
count+=left.length-a;
}
k++;
}
// BUG 2: Merging of leftovers should be done like this
while (a < left.length)
{
result[k++] = left[a++];
}
while (b < right.length)
{
result[k++] = right[b++];
}
return count;
}
}
The way I see it, counting the number of inversions in an array is finding a way to sort the array in an ascending order. Following that thought, here is my solution:
int countInversionArray(int[] A) {
if(A.length<=1) return 0;
int solution = 0;
for(int i=1;i<A.length;i++){
int j = i;
while(j+2<A.length && A[j] > A[j+1]){
invert2(j,j+1,A);
solution++;
j++;
}
j=i;
while(j>0 && A[j] < A[j-1]){
invert2(j,j-1,A);
solution++;
j--;
}
}
return solution;
}
private void invert2(int index1, int index2, int[] A){
int temp = A[index1];
A[index1] = A[index2];
A[index2] = temp;
}
I found a rigth solution in Robert Sedgewick book "Algorithms on java language"
Read here about merge
See java code for counting of inversion
You can try this In-Place Mergesort implemention on java. But minimum 1 temporary data container is needed (ArrayList in this case). Also counts inversions.
///
Sorter.java
public interface Sorter {
public void sort(Object[] data);
public void sort(Object[] data, int startIndex, int len);
}
MergeSorter implementation class (others like QuickSorter, BubbleSorter or InsertionSorter may be implemented on Sorter interface)
MergeSorter.java
import java.util.List;
import java.util.ArrayList;
public class MergeSorter implements Sorter {
private List<Comparable> dataList;
int num_inversion;
public MergeSorter() {
dataList = new ArrayList<Comparable> (500);
num_inversion = 0;
}
public void sort(Object[] data) {
sort(data, 0, data.length);
}
public int counting() {
return num_inversion;
}
public void sort(Object[] data, int start, int len) {
if (len <= 1) return;
else {
int midlen = len / 2;
sort(data, start, midlen);
sort(data, midlen + start, len - midlen);
merge(data, start, midlen, midlen + start, len - midlen);
}
}
private void merge(Object[] data, int start1, int len1, int start2, int len2) {
dataList.clear();
int len = len1 + len2;
// X is left array pointer
// Y is right array pointer
int x = start1, y = start2;
int end1 = len1 + start1 - 1;
int end2 = len2 + start2 - 1;
while (x <= end1 && y <= end2) {
Comparable obj1 = (Comparable) data[x];
Comparable obj2 = (Comparable) data[y];
Comparable<?> smallobject = null;
if (obj1.compareTo(obj2) < 0) {
smallobject = obj1;
x++;
}
else {
smallobject = obj2;
y++;
num_inversion += (end1 - x + 1);
}
dataList.add(smallobject);
}
while (x <= end1) {
dataList.add((Comparable)data[x++]);
}
while (y <= end2) {
dataList.add((Comparable)data[y++]);
}
for (int n = start1, i = 0; n <= end2; n++, i++) {
data[n] = dataList.get(i);
}
}
}
For testing, create a driver class and type the main method
public static void main(String[] args) {
Object[] data = ...............
Sorter sorter = new MergeSorter();
sorter.sort(data)
for (Object x : data) {
System.out.println(x);
}
System.out.println("Counting invertion: " + ((MergeSorter)sorter).counting());
}

Categories