I am blanking on this exam review question, can anyone help me get started? In findMinPos, I am confused by the three parameters, how do I access the nodes in data array? Can I use a loop even though it's a recursive method?
public class ArraySwapMin
{
public static void swapMin( int[] data, int cur )
{
int min = findMinPos( data, cur, cur );
/////////////////////////////////////////////////////////////
// swap the min position value with the one in the cur position
////////////////////////////////////////////////////////////////
}
/**
* Check the nodes in "data" from position "start" to the end of the array.
* to see if any value in this part of the array is less than the min
* value found so far (up to the "cur" position).
*/
private static int findMinPos( int[] data, int cur, int minPosSoFar )
{
//////////////////////////////////////////////////////////////
// Compare this entry's value (if it is a valid entry) with the
// value in the entry "minPosSoFar". If this value is less, then
// this entry is now the "minPosSoFar".
// Recurse for the rest of the array.
///////////////////////////////////////////////////////////////
return minPosSoFar;
}
/**
* unit tester
*/
public static void main( String[] args )
{
int[] data = { 12, 3, 10, 5, 1, 8 };
int count = 0;
System.out.println( "++++++++++++++++ ArraySwapMin ++++++++++++++++" );
printArray( "starting array ", data );
for ( int i = 0; i < data.length - 1; i++ )
{
swapMin( data, i );
printArray( "swap Min with " + i, data );
}
}
public static void printArray( String label, int[] data )
{
System.out.print( label + ": [ " );
for ( int i = 0; i < data.length - 1; i++ )
System.out.print( data[ i ] + ", " );
System.out.println( data[ data.length - 1 ] + " ]" );
}
}
In swapMin() you have to switch the current position with the one with the minimum.
public static void swapMin( int[] data, int cur )
{
int min = findMinPos( data, cur, cur );
int minValue = data[min];
data[min] = data[cur];
data[cur] = minValue;
}
The minimum will recursively determined in findMinPos(). The whole idea of recurseiv programming is to use the returnvalues of an inner method call instead of using a loop. What you need is an overall break condition (in your case the length of the array) and usually multiple return statements.
This one here will do the trick:
private static int findMinPos( int[] data, int cur, int minPosSoFar )
{
if(cur < data.length)
{
if(data[cur] < data[minPosSoFar]) // set new minimum to position cur
{
return findMinPos(data, cur + 1, cur);
}
else // keep old minimum
{
return findMinPos(data, cur + 1, minPosSoFar);
}
}
return minPosSoFar;
}
And since the multiple return statements in the if-else block makes the code long and messy you can shorten it like this
private static int findMinPos( int[] data, int cur, int minPosSoFar )
{
if(cur < data.length)
{
return (data[cur] < data[minPosSoFar]) ?
findMinPos(data, cur + 1, cur) :
findMinPos(data, cur + 1, minPosSoFar);
}
return minPosSoFar;
}
They have given you pseudocode. Just do exactly what it says. First change the instructions to step by step.
Compare this entry's value (if it is a valid entry) with the value in the entry "minPosSoFar".
If this value is less, then this entry is now the "minPosSoFar".
Recurse for the rest of the array.
So:
private static int findMinPos( int[] data, int cur, int minPosSoFar )
{
if (cur < data.length) { // Needed for stopping at the end of the array
if (data[cur] < data[minPosSoFar]) { // 1.
minPosSoFar = cur; // 2.
}
return findMinPos(data, cur+1, minPosSoFar); // 3.
}
return minPosSoFar;
}
Since this is for school, I don't want to do the whole thing for you, hopefully this will give you a good idea what to do.
Related
I'm trying to learn a bit Java with tutorials and currently I'm struggling with piece of code where I should find on which index is difference between arrays (if there is difference at all)
My code
Scanner scanner = new Scanner(System.in);
int[] arrOne = Arrays.stream(scanner.nextLine().split(" ")).mapToInt(Integer::parseInt).toArray();
int[] arrTwo = Arrays.stream(scanner.nextLine().split(" ")).mapToInt(Integer::parseInt).toArray();
int sumArrOne = 0;
int index = 0;
boolean diff = false;
for (int k : arrOne) {
if (Arrays.equals(arrOne, arrTwo)) {
sumArrOne += k;
} else {
for (int i : arrTwo) {
if (k != i) {
index = i;
diff = true;
break;
}
}
}
}
if (diff) {
System.out.println("Found difference at " + index + " index.");
} else {
System.out.println("Sum: " + sumArrOne);
}
So, if arrays are identical I'm sum array elements in arrOne. If they are not identical -> must show at which index they are not.
With this code when I input
1 2 3 4 5
1 2 4 3 5
I should get that difference is at index 2 instead I've got index 1.
I'm not quite sure why and would be glad if someone point me out where is my mistake.
I updated your code. Looks like you're misunderstanding the concept of indexes yet.
Use one common index to check with in both arrays, in my example it's simply called i:
import java.util.Arrays;
import java.util.Scanner;
public class BadArray {
static private final int INVALID_INDEX = Integer.MIN_VALUE;
public static void main(final String[] args) {
try (final Scanner scanner = new Scanner(System.in);) {
final int[] arrOne = Arrays.stream(scanner.nextLine().split(" ")).mapToInt(Integer::parseInt).toArray();
final int[] arrTwo = Arrays.stream(scanner.nextLine().split(" ")).mapToInt(Integer::parseInt).toArray();
int sumArrOne = 0;
int diffIndex = INVALID_INDEX;
final int minLen = Math.min(arrOne.length, arrTwo.length);
for (int i = 0; i < minLen; i++) {
sumArrOne += arrOne[i];
if (arrOne[i] != arrTwo[i]) {
diffIndex = i;
break;
}
}
if (diffIndex != INVALID_INDEX) {
System.out.println("Found difference at " + diffIndex + " index.");
} else if (arrOne.length != arrTwo.length) {
System.out.println("Arrays are equal but have different length!");
} else {
System.out.println("Sum: " + sumArrOne);
}
}
}
}
I also put the scanner into a try-resource-catch to handle resource releasing properly.
Note you could also do the array lengths comparison right at the start if different array lengths play a more crucial role.
You are trying to find out which index has the first difference so you should iterate via the index rather than using a for-each loop (aka enhanced for loop). The following method should work for this.
/**
* Returns the index of the first element of the two arrays that are not the same.
* Returns -1 if both arrays have the same values in the same order.
* #param left an int[]
* #param right an int[]
* #return index of difference or -1 if none
*/
public int findIndexOfDifference(int[] left, int[] right) {
// short-circuit if we're comparing an array against itself
if (left == right) return -1;
for (int index = 0 ; index < left.length && index < right.length ; ++index) {
if (left[index] != right[index]) {
return index;
}
}
return -1;
}
In your code you compare, where the indexes are different, not the values at the indexes. Also your code has several other issues. I'll try to go through them step by step:
// compare the whole array only once, not inside a loop:
diff = !Arrays.equals(arrOne, arrTwo));
if (!diff) {
// do the summing without a loop
sumArrOne = Arrays.stream(arrOne).sum();
} else {
// find the difference
// it could be the length
index = Math.min(arrOne.length, arrTwo.length);
// or in some different values
for (int i = 0; i < index; i++) { // do a loop with counter
if (arrOne[i] != arrTwo[i]) {
index = i;
break;
}
}
}
It doesn't matter that I set index here above the loop as it's value will be overwritten anyways inside the loop, if relevant.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 10 months ago.
Improve this question
In this code, we have to add a method set() which will take two parameters, an int index, and an Integer value, which will set the array element at the specified index to the specified value and the array will grow if an attempt is made to set a value beyond the end of the array by using the method resize().
This is the code I currently have:
public class MyVector {
protected Integer[] internalArray;
public MyVector( int initialSize )
{
internalArray = new Integer[initialSize];
}
public void resize( int newSize )
{
if ( newSize != internalArray.length ) {
Integer[] newArray = new Integer[newSize];
for (int i=0; i < Math.min(newSize,internalArray.length); i++)
newArray[i] = internalArray[i];
internalArray = newArray;
}
}
public Integer get( int index )
{
if ( index < internalArray.length )
return internalArray[index];
return null;
}
public static void main(String[] args)
{
MyVector vec = new MyVector(5);
for ( int i = 0 ; i < 20 ; i++ )
vec.set(i, i*i );
for ( int i = 0 ; i < 20 ; i++ )
System.out.println( "Element" + i + "=" + vec.get(i) );
}
}
This is the current set()-method I have made. I am not quite sure how to use or execute the set() method. How should I proceed?
public int set(int a, int b){
a = b;
if (b>19){
resize(b);
}
return a;
}
Welcome to stackoverflow! I have a feeling this is a homework question, if it is - please try to do your homework on your own since it will greatly assist you in the future.
As you can see in the code you have provided there is currently no function set() for your MyVector class.
In order to make a set() function you have to declare it. This w3schools guide will most likely explain the basics for you: https://www.w3schools.com/java/java_encapsulation.asp
For your code that could be:
public void set(int index, int value) {}
Assuming you don't want a return value from the function.
Then you can just change the value of the array to what you want it to be:
public void set( int index, int value ) {
internalArray[index] = value;
}
More information if you are interested:
What is an interesting point is that many people discuss the reasoning behind why we in OOP should need a use for setters and getters. In your example it seems like you only want your list to be of size = initialSize which you set to 5. What if someone inputs an index higher than 5? What if they input 10 instead? What will your list look like? If you want to limit those things you can in your set() function add limits to the values and indexes acceptable (which from an OOP standpoint) might be a better idea.
As I tried to explain there might be occasions where you would want to handle events when the index goes beyond. This is an example of what set() can look like if you want to increase the array size if the index is out of bounds. I really suggest you look into array and deep copying though.
public void set( int index, int value ) {
if (index > internalArray.length - 1) {
Integer[] newInternalArray = new Integer[internalArray.length + 1];
for(int i = 0; i < internalArray.length; i++) {
newInternalArray[i] = internalArray[i];
}
newInternalArray[newInternalArray.length-1] = value;
internalArray = newInternalArray;
} else {
internalArray[index] = value;
}
}
Or by using the resize() function:
public void set( int index, int value ) {
if (index > internalArray.length -1) {
resize(index + 1);
}
internalArray[index] = value;
}
With this solution you may consider to make the resize() private unless you want others to call it publicly. This is what can be so interesting and what I tried to tell you. By making it private and using it in the set-method you allow for setting values but you are in charge of how the values are changed.
Your vector class contains an internal array. There you have to modify the value at the given position. If the given position is outside of the array then you can use the resize method to enlarge the internal array:
public class MyVector {
protected Integer[] internalArray;
public MyVector( int initialSize )
{
internalArray = new Integer[initialSize];
}
public void resize( int newSize )
{
if ( newSize != internalArray.length ) {
Integer[] newArray = new Integer[newSize];
for (int i=0; i < Math.min(newSize, internalArray.length); i++)
newArray[i] = internalArray[i];
internalArray = newArray;
}
}
public Integer get( int index )
{
if ( index < internalArray.length )
return internalArray[index];
return null;
}
public void set( int index, int value )
{
if (index > internalArray.length -1) {
resize(index + 1);
}
internalArray[index] = value;
}
public static void main(String[] args)
{
MyVector vec = new MyVector(5);
for ( int i = 0 ; i < 20 ; i++ )
vec.set(i, i*i );
for ( int i = 0 ; i < 20 ; i++ )
System.out.println( "Element" + i + "=" + vec.get(i) );
}
}
$ java MyVector.java
Element0=0
Element1=1
Element2=4
Element3=9
Element4=16
...
Element17=289
Element18=324
Element19=361
Okay okay. I have been working on a recursive selection sort in Java. I have done my reading, googling, stack overflowing, and am still unable to figure it out. I think the code is getting worse the more time I spend on it due to overcomplicating it. All the examples I have seen use multiple parameters, and the single parameter is throwing me off.
Below is the recursive method and the driver. The first 3 if statements are given so I am assuming required.
public static void selectionSort_Rec(int[] arr)
{
if(arr == null) throw new NullPointerException();
if(arr.length == 0) throw new IllegalArgumentException();
if(arr.length == 1) return;
int startIndex = 0;
if ( startIndex >= arr.length - 1 )
return;
int minIndex = startIndex;
for ( int index = startIndex + 1; index < arr.length; index++ )
{
if (arr[index] < arr[minIndex] )
minIndex = index;
}
int temp = arr[startIndex];
arr[startIndex] = arr[minIndex];
arr[minIndex] = temp;
startIndex++;
selectionSort_Rec(arr);
}
// Driver method
public static void main(String args[])
{
int arr[] = {3, 1, 5, 2, 7, 0};
// Calling function
selectionSort_Rec(arr);
for(int i :arr){
System.out.print(i);
}
}
There is some problem in your code.
at the first you use startIndex and find good number from your array for that, then increment it at the end of code which is redundant because when function called again, it use 0 for it again. each function call has it's own variable and so the next call, function create new startIndex and use that which is zero again.
You must pass it to function and increment at each next function call. because of this, you base check is not true anymore and it is changed to check until we get at the end of our array.
also this line of code is redundant because when we get to this line, we know that arr.lenghth() is more than one. (however our logic of code changed and there is no need to this too)
if ( startIndex >= arr.length - 1 )
return;
return when get to base condition like 1 is better and throw exception is not necessary because when it is one, we return without going lower. (conditions always false for zero or empty array. you don't remove anything from array too)
I define recursive function as a function that sort array from start index sent to it.
This is the result:
public class GFG
{
public static void selectionSort_Rec(int[] arr) {
selectionSortHelper(arr, 0);
}
static void selectionSortHelper(int[] arr, int startIndex) {
if (startIndex >= arr.length)
return;
int minIndex = startIndex;
for (int index = startIndex + 1; index < arr.length; index++)
{
if (arr[index] < arr[minIndex])
minIndex = index;
}
int temp = arr[startIndex];
arr[startIndex] = arr[minIndex];
arr[minIndex] = temp;
selectionSortHelper(arr, startIndex + 1);
}
// Driver method
public static void main(String args[]) {
int arr[] = {3, 1, 5, 2, 7, 0};
// Calling function
selectionSort_Rec(arr);
for (int i : arr)
{
System.out.print(i + " ");
}
}
}
I hope this is what you want.
Every source I've looked at I either don't understand, doesn't seem to apply, or uses something like an Array list. I'm not familiar with those. So I'd like to use a basic toString method that prints out the index of the array as well as the number held when compared to the variable 'length' -- num.length could be different as that's the physical size of the underlying array. The for loop at the bottom has the gist of it. I'm trying to print out the index (0-infinite) with int's that are held in the resizeable array. The variable 'length' is not the actual size of the array but a working size that contains 0 until another cell is added. The 'strang' variable is just something I've tried. I don't think it will work, but anything else I doesn't seem to help as I'm stuck.
public class XArray
{
private int[] nums;
private int length;
public XArray()
{
nums = new int[10];
length = 0;
}
public void add(int value)
{
if (length == nums.length)
{
int[] nums2 = new int[(int)(nums.length * 1.2)];
for ( int i = length - 1; i >= 0; i-- )
{
nums2[i] = nums[i];
}
nums = nums2;
}
nums[length] = value;
length++;
}
public void set(int index, int value)
{
if (index < length)
{
nums[index] = value;
}
}
public int get(int index)
{
return nums[index];
}
public int size()
{
return length;
}
public void remove()
{
nums[length - 1] = 0;
length--;
}
public String toString(int[] nums)
{
String strang = "l";
for ( int i = 0 ; i < length; i++ )
{
strang = "Index: " + i + " Number: " + nums[i] + ", ";
}
return strang;
}
}
You need to concatenate the values on each iteration of the loop...something like...
public String toString(int[] nums)
{
StringBuilder strang = new StringBuilder(length);
for ( int i = 0 ; i < length; i++ )
{
strang.append("Index: ").append(i).append(" Number: ").append(nums[i]).append(", ");
}
return strang.toString();
}
Generally speaking, toString should't take parameters, there would a difference between nums and length which could cause issues
#Override
public String toString() {...
This way, you will be printing the contents of the objects num array, which is contextually associated with length
You probably meant to use += instead of = in that method (though many people will tell you to use a StringBuilder because successive concatenations, if not optimized by a compiler` will generate a lot of garbage).
Also, don't pass in nums! You want to use the field nums; passing in an argument will use the argument. The real toString has no parameters (and should have an #Override annotation).
I've got an random array generated and I need a way to return the index of value of user input. So if it gives 8 random numbers, it then asks user to find a value in array.. Once that value is entered it needs to return the first index of that value. We haven't gone over this much in class and I don't know the best way to return this. Here's what I have so far:
Scanner input = new Scanner(System.in);
System.out.println("Enter an integer to find in the array:");
int target = input.nextInt();
// Find the index of target in the generated array.
/*
** 3. write findValue **
*/
int index = findValue(array, target);
if (index == -1)
{
// target was not found
System.out.println("value " + target + " not found");
}
else
{
// target was found
System.out.println("value " + target + " found at index " + index);
}
}
/*
allocate a random int[] array with size elements, fill with
random values between 0 and 100
*/
public static int[] generateRandomArray(int size)
{
// this is the array we are going to fill up with random stuff
int[] rval = new int[size];
Random rand = new Random();
for (int i=0; i<rval.length; i++)
{
rval[i] = rand.nextInt(100);
}
return rval;
}
/*
print out the contents of array on one line, separated by delim
*/
public static void printArray(int[] array, String delim)
{
// your code goes here
System.out.println (Arrays.toString(array));
}
/*
return the count of values in array that are not divisible evenly by 2
*/
public static int countOdds(int[] array)
{
int count=0;
// your code goes here
for (int i=0; i<array.length; i++){
if (array[i] %2 !=0) {
count++;
}
}
return count;
}
/*
return the first index of value in array. Return -1 if value is not present.
*/
public static int findValue(int[] array, int value)
{
// your code goes here
return -1;
}
}
First of all, please fix your question title.
And now to the solution. How would you do that in real life? You would go through the array and check every single entry if it matches the searched value.
And thats exactly how you can do this in Java.
public static int findValue(int[] array, int value) {
for (int i = 0; i < array.length; i++) { // iterate over the content of the given array
if (array[i] == value) { // check if the current entry matches the searched value
return i; // if it does return the index of the entry
}
}
return -1; // value not found, return -1
}
Here is an example for calling this method:
public static void main(String[] args) {
int[] array = new int[] { 1, 2, 3, 4, 5, 6 };
System.out.println(findValue(array, 6));
}
This will print 5, because the number 6 is on the 5th position in the given array. Keep in mind that the index starts with 0.