One method policy in Java - java

I need some help. My professor give us an assignment that we need to "extract" these codes into ONE METHOD ONLY. Is there a way to do it? It's a heap code sorting algorithm. I'm currently do have a little knowledge about programming so bear with me guys. Can you help me?
import java.util.Arrays;
import java.util.Scanner;
class HeapSort {
private static Scanner sc;
public static void main(String args[]) {
sc = new Scanner(System.in);
System.out.println("Enter no of terms");
int n = sc.nextInt();
System.out.println("Enter the terms");
int arr[] = new int[n];
for (int i = 0; i < n; i++)
arr[i] = sc.nextInt();
System.out.println("The unsorted array is:");
System.out.println(Arrays.toString(arr));
heap(arr);
System.out.println("The sorted array is:");
System.out.println(Arrays.toString(arr));
}
static void heapify(int a[], int n, int i) {
int max, child;
child = 2 * i + 1;
max = i;
if (child < n)
if (a[child] > a[max])
max = child;
if (child + 1 < n)
if (a[child + 1] > a[max])
max = child + 1;
if (max != i) {
int temp = a[i];
a[i] = a[max];
a[max] = temp;
heapify(a, n, max);
}
}
static void buildheap(int a[]) {
for (int i = a.length / 2 - 1; i >= 0; i--)
heapify(a, a.length, i);
}
static void heap(int a[]) {
buildheap(a);
for (int i = a.length - 1; i >= 1; i--) {
int temp = a[0];
a[0] = a[i];
a[i] = temp;
heapify(a, i, 0);
}
}
}

You get there by simply replacing each method invocation with the actual body of the method. Of course, that will quickly lead to all kinds of confusion, given the poor naming of method parameters.
But the real challenge here (and probably your actual homework) is that you have to rework that heapify() method to not use recursion. In other words: you have to do the heap sort without using recursion. You can find some guidance here for example.
And of course: this code is already hard to read. Forcing all code into a single method will make it unreadable and not human comprehensive. It is like the exact opposite of good practices!

One thing you can do is replace all the code in each method to where the method is being called.
For example, instead of calling heap(arr) you can move all the code up to the place where heap(arr) is being called and continue to do so with the rest of the code.

Related

i want to find the span of a array. Span is defined as difference of maximum value and minimum value [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 1 year ago.
Improve this question
I tried by creating two functions for greatest and smallest values and then subtracting them .but the code doesn't seem to work
here's the code.See if u could help me out .im new to java and still learning.
import java.io.*;
import java.util.*;
public class Main{
public static void smler(int arr[],int j){
for (int i=0;i<=j;j++){
if(arr[i]<arr[i+1]){
int temp =arr[i];
arr[i]=arr[i+1];
arr[i+1]=temp;
}
}
}
public static void grter(int arr[],int j){
for (int i=0;i<=j;j++){
if(arr[i]>arr[i+1]){
int temp =arr[i];
arr[i]=arr[i+1];
arr[i+1]=temp;
}
}
}
public static void main(String[] args) throws Exception {
Scanner sc= new Scanner (System.in);
int n=sc.nextInt();
int[] arr= new int[n];
for(int i=0;i<=n;i++){
arr[i]=sc.nextInt();
}
grter(arr,n);
int y= arr[n];
smler(arr,n);
int z = arr[n];
System.out.println(y-z);
}
}
There are a lot of errors in your logic.
The for loop does not need to be <= it needs to be < otherwise you will get out of bounds exception.
The way you are calculating the min and max are wrong.
Here is an example for you to study that does what you are trying to accomplish:
import java.util.Scanner;
public class ArraySpan {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("Enter array size:");
int n = sc.nextInt();
int[] arr = new int[n];
for (int i = 0; i < n; i++) {
System.out.println("Enter value:");
arr[i] = sc.nextInt();
}
int min = findMin(arr);
int max = findMax(arr);
System.out.println("The span of the array = " + (max - min));
sc.close();
}
static int findMax(int[] a) {
int max = Integer.MIN_VALUE;
for (int i = 0; i < a.length; i++) {
if (a[i] > max)
max = a[i];
}
return max;
}
static int findMin(int[] a) {
int min = Integer.MAX_VALUE;
for (int i = 0; i < a.length; i++) {
if (a[i] < min)
min = a[i];
}
return min;
}
}
and output:
Enter array size:
3
Enter value:
1
Enter value:
2
Enter value:
3
The span of the array = 2
It would better if you could look for complexity improvement.
Idea is to get the max and the min in best possible way and this can be achieved using any sorting techniques, let us assume your sort method runs in O(n log n) time, and then you just need to get the difference of 1st element(0 th index) and last element(n-1 th index).
public static void main(String[] args) throws Exception {
Scanner sc= new Scanner (System.in);
int n=sc.nextInt();
int[] arr= new int[n];
// insert values into your array
if(arr.length >= 2){
sort(arr); // Implement your any sorting method
// Make sure that your arr has exactly n elements, ,
// Otherwise rest of the indices will all be zero(0)
System.out.println(arr[0]-arr[arr.length-1]); // last index is 'arr.length-1'
return; // Return from here
}
// arr has not sufficient elements to determine span
throw new UnsupportedOperationException("Invalid entry");
}
}
Index starts from 0 and it goes till n-1.
So, the condition in for-loop should be i<n instead of i<=n,for(int i=0;i<n;i++).
You have created 2 functions but it doesn't return any value nor changes anything. As you are passing the array by value, not by references.
You don't need the 2 functions, just one for finding max and min in linear, or sort the array in ascending order and array[0] will be the min and array[n-1] will be max.
There is an approach very similar to what you want to do.
import java.io.*;
import java.util.*;
public class Main{
public static int smler(int arr[],int N){
int smaller = arr[0];
for (int i=1;i<N;i++){
if(arr[i] < smaller){
smaller = arr[i];
}
}
return smaller;
}
public static int grter(int arr[],int N){
int greater = arr[0];
for (int i=0;i<N;i++){
if(arr[i] > greater){
greater = arr[i];
}
}
return greater;
}
public static void main(String[] args) throws Exception {
Scanner sc= new Scanner (System.in);
int n=sc.nextInt();
int[] arr= new int[n];
for(int i=0;i<=n;i++){
arr[i]=sc.nextInt();
}
System.out.println(grter(arr, n) - smler(arr, n));
}
}

Big Array in JAVA

I am trying to solve Spoj prime generator using Sieve Of Eratosthenes But am getting NZEC error. Can anybody help me . Some users have said using sieve already would help me .
import java.util.*;
public class Main
{
public static void main (String args[])
{
Scanner sc =new Scanner(System.in);
int n =sc.nextInt();
int g,h;
int isPrime[]=new int[1000000000];
for (int j=3;j<1000000000;j++)
{
isPrime[0]=0;
isPrime[1]=0;
isPrime[2]=1;
if(j%2==0)
isPrime[j]=0;
else
isPrime[j]=1;
}
for(int k=3;k<=Math.sqrt(1000000000);k=k+2)
{
if(isPrime[k]==1)
for (int l=k*k;l<1000000000;l=l+k)
{
isPrime[l]=0;
}
}
for (int i=0;i<n;i++)
{
g =sc.nextInt();
h =sc.nextInt();
for (int m=g; m<=h;m++)
{
if(isPrime[m]==1)
System.out.println(m);
}
System.out.println();
}
System.exit(0);
}
}`
Simple sieve may not run in the given time limit. At least it didn't for me. The better approach is segmented sieve. Here are few links that may help you:
stackoverflow
primesieve
I used the second link to understand and solve the question. But the first link also has a good explanation.
Go through both of them and you should be able to solve the problem.
Happy Coding!
P.S: You seem to be using Scanner for reading input. It will be very slow. Use BufferedReader to speed up the reading of inputs. In websites like SPOJ, it is very crucial.
Only reason is just JVM should have enough space to store new boolean[total + 1] about 4Gb:
public static void main(String... args) {
boolean[] primes = primes(1_000_000_000);
try (Scanner scan = new Scanner(System.in)) {
int n = scan.nextInt();
for (int i = 0; i < n; i++) {
int from = scan.nextInt();
int to = scan.nextInt();
for (int j = from; j <= to; j++)
if (primes[j])
System.out.println(j);
System.out.println();
}
}
}
private static boolean[] primes(int total) {
// initially assume all integers are primes
boolean[] primes = new boolean[total + 1];
Arrays.fill(primes, true);
primes[0] = false;
primes[1] = false;
// mark non-primes <= total using Sieve of Eratosthenes
for (int i = 2; i * i <= total; i++) {
// if i is primes, then mark multiples of i as nonprime
// suffices to consider mutiples i, i+1, ..., total/i
if (!primes[i])
continue;
for (int j = i; i * j <= total; j++)
primes[i * j] = false;
}
return primes;
}

Java int Array: Find Average, Min/Max, Sort

Edit: I need to do the following with the array: sort, find minimum, find maximum, find the average.
1) How do I properly access the methods in the other class 2) What variables do I need to initialize in order to make my methods work (since I got the examples from Google)
I've tried to find examples of how to work with the numbers in an array, but I find it difficult to figure out considering the code is working with different variable names and is largely unorganized and not commented.
This is what I have so far in my methods class:
//Grades Array
int[] score = {70,90,80,85,65,55,100,70,40,77,66,55,44};
int number;
//Get
public int getNumber(){
return number;
}
//Average Grade
public static double average(int[] score, int number)
{
double average = 0;
if (score.length > 0)
{
average = number / score.length;
}
return average;
}
Here is my Main class:
public class Main {
public static void main(String[] args) {
//Average Method
OtherMethods average = new OtherMethods();
int[] number = null;
OtherMethods.average(number, 0);
System.out.println(number);
}
}
So as you can see I'm all over the place. It's largely a patchwork of examples I've tried to apply.
This is the Sort code I'm using. Adhering my variables to the ones used here would be advantageous, of course, but I'm just not sure where to begin.
//Ascending Sort Method
public static void sort(int[] score, int number)
{
for(i=0; i < num-1; i++) //For each sublist
{
min = list[i];
position = i;
for (j=i+1; j < num; j++) //Find minimum
{
if (list[j] < min)
{
min = list[j];
position = j;
}
}
temp = list[position]; //Swap
list[position] = list[i];
list[i] = temp;
}
}
Any help would be greatly appreciated.
If you're using Java 8+, Check out the functional streams and in particular IntStream.
For Example, to min/max/average:
int min = IntStream.of(score)
.min(); // or .max() or .average()
and to sort:
score = IntStream.of(score)
.sorted()
.toArray();
If your trying to sort the numbers you can do something as simple as the bubble sort, which is fairly strait forward compare n to n+1 and switch if need be:
void bubbleSort(int ar[])
{
for (int i = (ar.length - 1); i >= 0; i--)
{
for (int j = 1; j ≤ i; j++)
{
if (ar[j-1] > ar[j])
{
int temp = ar[j-1];
ar[j-1] = ar[j];
ar[j] = temp;
} } } }
or like you did above the selection sort:
void selectionSort(int[] ar){
for (int i = 0; i ‹ ar.length-1; i++)
{
int min = i;
for (int j = i+1; j ‹ ar.length; j++)
if (ar[j] ‹ ar[min]) min = j;
int temp = ar[i];
ar[i] = ar[min];
ar[min] = temp;
} }
Another thing the way you currently have this set up your getNumber() function has no real use seeing that your number variable is global to begin with.
If you want more help you will have to come up with an actual question.

Given an array of integers, find out the third largest value in the array

public int thirdLargest(int[] arr){
int f_l = arr[0];
int s_l = arr[0];
int t_l = arr[0];
for(int i=1;i<arr.length;i++)
{
if (f_l < arr[i]){
t_l = s_l;
s_l = f_l;
f_l = arr[i];
}
else if (s_l < arr[i]){
t_l = s_l;
s_l = arr[i];
}
else if (t_l < arr[i]){
t_l = arr[i];
}
}
return t_l;
}
my code didn't passes some cases,any suggestion?
parameter {24,27,30,31,34,37,40,42}' , passes
parameter {2,-1,-2,-3,-4,-5}' , fails
This is simply cause by the fact that you initialize all values to arr[0]. If all elements are smaller than arr[0] this code won't update the values, even though the second-largest element for example wouldn't be arr[0]. Instead initialize the variables for the third/second/largest value with Integer.MIN_VALUE and start the search with the first element (index = 0) instead of the second.
There is actually a well-known algorithm for this, which is more generic than yours. It is called quick-select and looks like a quick sort with an optimization making it faster (linear time in average) : since we don't need to sort the array, we just recurse on the part of the array containing the index we are looking for (in your case, third item so index 2).
Here is an implementation in Java :
private static final Random rd = new Random();
public static int kthElement(int[] arr, int k) {
return kthElement(arr,k,0,arr.length);
}
private static T kthElement(int[] arr, int k, int min, int max) {
if (min < max - 1) {
int p = pivot(arr,min,max);
return p == k - 1 ? arr[p] :
p < k - 1 ? kthElement(arr,k,p + 1,max) : kthElement(arr,k,min,p);
}
return arr[min];
}
private static int pivot(int[] arr, int min, int max) {
int pivot = min + rd.nextInt(max - min);
swap(arr,pivot,max - 1);
pivot = min;
for (int i=min ; i<max ; i++)
if (arr[i] < arr[max - 1]) swap(arr,i,pivot++);
swap(arr,max - 1,pivot);
return pivot;
}
private static void swap(int[] arr, int i, int j) {
int tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
Well, as an alternative to your working code, here is a solution that will allow you to find the Nth largest integer in your array using Collections to do the heavy lifting:
import java.util.Arrays;
import java.util.Collections;
public class ArrayNthLargest {
public static int getNthLargest(int[] arrayInput, int n) {
Integer[] sortedArray = new Integer[arrayInput.length];
for (int i = 0; i < arrayInput.length; i++) {
sortedArray[i] = new Integer(arrayInput[i]);
}
Arrays.sort(sortedArray, Collections.reverseOrder());
return (sortedArray[n - 1]);
}
public static void main(String[] args){
int nth = new Integer(0);
int n = new Integer(3);
int[] testArray = {1,2,3,4,5,6,23,44,55,8,1};
nth = getNthLargest(testArray, n);
System.out.printf("The %d sorted array value is %d", n, nth);
}
}
This was actually an interesting question to me to do in O(n) complexity. I hope this solution is order n. I used an ArrayList as a stack (since Stack object won't allow addition of items in specific incidences (I've generalized it).
public int thirdLargest(int[] arr){
public int N_TH = 3; // Assuming this is nth largest you want
public ArrayList<Integer> largest = new ArrayList<Integer>(N_TH);
for(int i = 0;i<N_TH;i++)
largest.add(0); // initialize the ArrayList
for(int i = 0;i<arr.length;i++) {
for(int j=0;j<largest.size();j++){
if(arr[i] >= largest.get(j)) {
// Add the item at the correct index
// Pop the last element
largest.remove(largest.size()-1);
largest.add(j,arr[i]);
break;
}
}
}
return largest.get(N_TH);
}
Let me know if you find any problems with it, I might have mistyped part of trying to put it in OP's method.
EDIT won't work with negative numbers at the moment. You can find the smallest value in arr and initialize largest with that value. Then it'll also with negative numbers

Java backtraking problem

Hey guys. I've been strugling with a backtraking problem for hours. Can anyone lend me a hand? Here is the problem:
n camels numbered from 1 to n are the arranged order. I want to rearrange so that each camel has a diferent camel in front.
This is what I have so far:
import java.util.*;
public class NCamile{
static int size;
static int count;
static char[] arrN= new char[100];
public static void main(String[] args){
System.out.print("Enter word: ");
String numar = getInt();
size = numar.length();
count=0;
for(int i=0; i < size ; i++){
arrN[i] = numar.charAt(i);
}
backtraking(size);
}
public static void backtraking(int newsize){
if (newsize == 1){
return;
}
for(int i=0 ; i < newsize; i++){
backtraking(newsize - 1);
if(newsize == 2 ){
display();
}
rotate(newsize);
}
}
public static void rotate(int newsize){
int position = size - newsize;
for(int i = position + 1; i < newsize; i++){
char gigi;
gigi = arrN[i - 1];
arrN[i - 1] = arrN [i];
arrN[i] = gigi;
}
}
public static void display(){
if (count < 9){
System.out.print(" ");
}
System.out.print(++count+ ")" + " ");
for(int i = 0 ; i < size ; i++)
System.out.print(arrN[i]);
System.out.print(" ");
if(count % 10 == 0){
System.out.println(" ");
}
}
public static String getInt(){
Scanner scan = new Scanner(System.in);
String s = scan.next();
return s;
}
}
With this, the algorithems show me every posible solution to rearrange a string, but it dosen't respect the last condition of the problem. I've tried ading this:
for(int j = 0 ; j < size ; j++){
if (array[j] !=[array[j + 1] )
display()
}
But after I added it I got about 10 times more displayed words then it should have shown me
Can anyone give me an idea on what should I do?
If you're only asked to insure that
i) a single new arrangement is produced, and
ii)that new arrangement must satisfy the condition that each camel follows a camel different from the one it followed in the original arrangement,
then you can easily satisfy this just by reversing the list of camels.
Surely this is not optimized solution, but for simply gettin result I would consider checking all of the permutations. Method producing every permutation wouldn't be hard to write (see e.g. String permutation) and checking if some camel has the same backtraced won't be any effort at all.
--- edit
So... Few things mended, few not:
I worked on String, not char array. Char array is completely misunderstand in this problem. It's better to use String object (cause in fact, String is char array) or int array (this have been hard to me, cause I haven't found any permutation method to be applied with such parameter). So the main method looks now:
private static String word;
public static void main(String[] args)
{
System.out.print("Enter word: ");
Scanner scan = new Scanner(System.in);
word = scan.next();
permutation(word);
}
I deleted your class variables (length, count, etc...) cause they are unnecessary right now. Writing out String is quite simple and if you would like to change output format - use String.length property instead.
Permutation method is copied from mentioned source, and little modified. It looks following:
public static void permutation(String s)
{
permutation("", s);
}
private static void permutation(String prefix, String s)
{
int n = s.length();
if (n == 0)
{
if (camelFit(prefix))
System.out.println(prefix);
}
else
{
for (int i = 0; i < n; i++)
permutation(prefix + s.charAt(i),
s.substring(0, i) + s.substring(i + 1, n));
}
}
if you would uncomment line checking if (camelFit (prefix)) it would display every permutation of input String. But! We would like to print only these camel chains, which fits problem conditions. How do we check if given chain is so? Simple method:
private static boolean camelFit(String prefix)
{
for (int i = 0; i < word.length() - 1; i++)
{
char camel = word.charAt(i);
char camelFollow = word.charAt(i+1);
for (int j = 0; j < prefix.length() - 1; j++)
{
if (prefix.charAt(j)==camel && prefix.charAt(j+1)==camelFollow)
{
return false;
}
}
}
return true;
}
Maybe not so simple, because we have to check every pair of input chain (every follower and followed) with every pair of output chain. If there isn't any match between any two pairs - given chain is fine.
Please notice, that this solution is absolutely non-optimized. Finding permutations is O(n!) complexity and checking pairs is O(n^2) complexity. Final complexity is O(n^2)*O(n!) so very, very high.

Categories

Resources