I'm working on a problem that says "Write a function called splay that reorganizes a list based on the first value. The first value is called the splaymaster. This function will rearrange the list such that all of the values before the splaymaster are less than or equal to the splaymaster and all of the values after it are greater than the splaymaster. The function also returns the index where the splaymaster is located after the list is rearranged. For example, if the list is [8, 15, 4, 48, 26, 45, 18, 29, 2, 1], the function will rearrange it to become [2, 1, 4, 8, 26, 45, 18, 29, 48, 15] and return the value 3. You may not sort the list." The problem that I seem to be having is for the example above it complains that the index is out of bounds which is my first problem. The next is if I use another array such as {90, 8, 15, 4, 48, 26, 45, 18, 29, 2, 1} I get {1, 90, 8, 15, 4, 48, 26, 45, 18, 29, 2} this is my output when it's not correct. What am I doing wrong? and How do I fix it?
public static void swap(int[] array, int i, int j) {
int temp = array[i];
array[i] = array[j];
array[j] = temp;
}
public static int splay(int[] x) {
int left = 1;
int right = x.length;
int splaymaster = x[0];
while (left < right) {
if (x[left] <= splaymaster) {
left++;
} else {
swap(x, left, right);
}
swap(x, 0, left - 1);
}
return splaymaster;
}
}
int right = x.length;
The index of the last element in an array is x.length - 1, hence the index is out of bounds. Nonetheless, your algorithm seems incorrect. Merely swapping the elements at different locations is not sufficient. If an element is less than the splaymaster then you need to move all the elements up one and insert the smaller element into the array before the splaymaster. I assume there may be other conditions regarding the way to solve the problem but if there are then they are not clear to me from your question, for example it appears that the order of the elements is not important just as long as all elements before the splaymaster are less than or equal to it. I also assume you need to change the array in place, i.e. you are not allowed to use a second array.
Consider the following code:
import java.util.Arrays;
public class SplayTst {
public static int splay(int x[]) {
int index = 0;
int splaymaster = x[0];
for (int i = 1; i < x.length; i++) {
if (x[i] <= splaymaster) {
int temp = x[i];
for (int j = i; --j >= 0;) {
x[j + 1] = x[j];
}
x[0] = temp;
index++;
}
}
return index;
}
public static void main(String[] args) {
int[] test = new int[]{8, 15, 4, 48, 26, 45, 18, 29, 2, 1};
int ndx = splay(test);
System.out.println(Arrays.toString(test));
System.out.println(ndx);
test = new int[]{90, 8, 15, 4, 48, 26, 45, 18, 29, 2, 1};
ndx = splay(test);
System.out.println(Arrays.toString(test));
System.out.println(ndx);
}
}
Running the above code produces the following output:
[1, 2, 4, 8, 15, 48, 26, 45, 18, 29]
3
[1, 2, 29, 18, 45, 26, 48, 4, 15, 8, 90]
10
Alternatively, assuming that you can use any method to solve the problem, consider the following which uses ArrayList and then converts it to an array and then all the array elements are copied to the original array. Note that the single code line for converting ArrayList<Integer> to int[] is taken from the following question:
How to convert an ArrayList containing Integers to primitive int array?
I refer to this line of the below code:
int[] arr = list.stream().mapToInt(i -> i).toArray();
I iterate through the original array. If an element is greater than the splaymaster then it is appended to the ArrayList, otherwise it is inserted as the first element in the ArrayList.
import java.util.ArrayList;
import java.util.Arrays;
public class SplayTst {
public static int splay(int[] x) {
ArrayList<Integer> list = new ArrayList<>();
list.add(x[0]);
int index = 0;
for (int i = 1; i < x.length; i++) {
if (x[i] <= x[0]) {
list.add(0, x[i]);
index++;
}
else {
list.add(x[i]);
}
}
int[] arr = list.stream().mapToInt(i -> i).toArray();
for (int i = 0; i < x.length; i++) {
x[i] = arr[i];
}
return index;
}
public static void main(String[] args) {
int[] test = new int[]{8, 15, 4, 48, 26, 45, 18, 29, 2, 1};
int ndx = splay(test);
System.out.println(Arrays.toString(test));
System.out.println(ndx);
test = new int[]{90, 8, 15, 4, 48, 26, 45, 18, 29, 2, 1};
ndx = splay(test);
System.out.println(Arrays.toString(test));
System.out.println(ndx);
}
}
Related
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 1 year ago.
Improve this question
So the main idea is, the last number came on roulette machine is going to be on Index[0] and the element at index "whatNumberCame" has to become the number before
public class Main {
public static void main(String[] args) {
int[] rouletteNumbers = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36};
Scanner scanner = new Scanner(System.in);
System.out.println("Enter number : ");
int whatNumberCame = scanner.nextInt();
int collisionIndex;
for(int i = 0; i < rouletteNumbers.length ; i++){
if(rouletteNumbers[i] == whatNumberCame){
System.out.println("COLLISION AT " + rouletteNumbers[i]);
collisionIndex = rouletteNumbers[i];
System.out.println(collisionIndex);
for (int j = collisionIndex + 1; j <= 0 ; j--){
rouletteNumbers[j] = rouletteNumbers[j - 1];
System.out.print(rouletteNumbers);
}
}
}
}
}
for example if i enter 10 array should become :
{10, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36}
You can tweak your code like this to make it works:
public static void main (String [] args) {
int[] rouletteNumbers = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36};
Scanner scanner = new Scanner(System.in);
System.out.print("Enter number : ");
int whatNumberCame = scanner.nextInt();
for(int i = 0; i < rouletteNumbers.length ; i++){
if(rouletteNumbers[i] == whatNumberCame){
for (int j = i; j > 0; j--){
rouletteNumbers[j] = rouletteNumbers[j - 1];
}
rouletteNumbers[0] = whatNumberCame;
break;
}
}
System.out.println(Arrays.toString(rouletteNumbers));
}
In your loop, you used j <= 0 which is always false, so you inner loop doesn't execute at all.
And when you find the position of the number, you can break from the loop using break.
Here is a method that does the similar thing except it allows you to insert a value at whatever array index you like. With each value inserted into the array, the array will grow in length as indicated within your post example.
Usage:
To add a value to the array at index 0 (the beginning of the Array):
rouletteNumbers = insertIntoArray(rouletteNumbers, whatNumberCame, 0);
To add a value to the very end of the array:
rouletteNumbers = insertIntoArray(rouletteNumbers, whatNumberCame, rouletteNumbers.length);
To insert a value into any index within the array (say index 4):
rouletteNumbers = insertIntoArray(rouletteNumbers, whatNumberCame, 4);
The method code:
public static int[] insertIntoArray(int[] array, int valueToInsert, int insertIntoIndex) {
/* If the inertIntoIndex value is greater than the supplied Array Length
then the inertIntoIndex value is changed to the supplied Array Length.
This ensures that the valueToInsert will be place at the end of the
Array. */
if (insertIntoIndex > array.length) {
insertIntoIndex = array.length;
}
int[] tmp = new int[array.length + 1];
int idxCounter = 0;
int i = 0;
for (; i < array.length; i++) {
if (i == insertIntoIndex) {
tmp[idxCounter] = valueToInsert;
idxCounter++;
}
tmp[idxCounter] = array[i];
idxCounter++;
}
/* when at this point in code, the condition below
indicates that the desired insert index location
would be at the very end of the array. */
if (i == idxCounter) {
tmp[idxCounter] = valueToInsert;
}
return tmp;
}
I've got List<List<Integer>> with several objects. Each of inner element contains randomly shuffled indexes, for example (it's only a part of indexes).
[1, 4, 5, 2, 0, 3, 6]
[4, 2, 5, 3, 1, 6, 0]
[0, 3, 6, 1, 2, 4, 5]
I've got also an array with some values (int[][] array)
And I need to do a loop for each element to get value from indexes and move forward by 1 index and when I reach last index I need to get value from this index and the first one. After that loop end and sum values. It might look difficult but pictrue will show what I mean. But I dont know how to do this (loop is required for each element, I'm gonna have a massive List of List<Integer> inside and every object gonna have multiple indexes.
I'm reading data from file and write it to array
List<String> result = new ArrayList<>();
int[][] array = new int[][]{};
try (Scanner sc = new Scanner(theFile)) {
while (sc.hasNext()) {
result.add(sc.nextLine());
}
int max = Integer.parseInt(result.get(0).trim());
array = new int[max][max];
for (int i = 1; i < result.size(); i++) {
String[] tmp = result.get(i).trim().split(" ");
for (int j = 0; j < tmp.length; j++) {
array[i - 1][j] = Integer.parseInt(tmp[j]);
array[j][i - 1] = array[i - 1][j];
}
}
List<List<Integer>> collectionWithSubjects = new ArrayList<>();
for (int i = 0; i < 40; i++) {
List<Integer> sub = new ArrayList<>();
sub = sequence(0,51);
Collections.shuffle(sub);
collectionWithSubjects.add(sub);
}
You've done a decent job of explaining the problem. It sounds like you're getting caught up on trying to do everything in a single for loop, rather than breaking down the problem into two pieces.
This is your statement:
I need to do a loop for each element to get value from indexes and move forward by 1 index and when I reach last index I need to get value from this index and the first one.
This can be divided into two pieces:
I need to do a loop for each element to get value from indexes and move forward by 1 index
This is a for loop that iterates from 0 -> size() - 1. If we go from 0 -> size() we get an overflow.
for(int i = 0; i < list.size() - 1; i++) {
int firstCoord = list.get(i);
int secondCoord = list.get(i+1);
//do stuff
}
when I reach last index I need to get value from this index and the first one.
This is getting the last element and the first element.
int firstCoord = list.get(list.size() - 1);
int secondCoord = list.get(0);
Combine both together and you've got the framework for getting the coordinates.
for(int i = 0; i < list.size() - 1; i++) {
int firstCoord = list.get(i);
int secondCoord = list.get(i+1);
//do stuff
}
int firstCoord = list.get(list.size() - 1);
int secondCoord = list.get(0);
//do stuff
I'll leave the actual implementation up to you.
// given array
int[][] array = [[31, 21, 34, 22, 67, 14, 41],
[17, 42, 31, 57, 26, 23, 52],
[5, 92, 52, 52, 31, 22, 62],
[17, 42, 31, 57, 26, 23, 52],
[5, 92, 52, 52, 31, 22, 62],
[31, 21, 34, 22, 67, 14, 41],
[5, 92, 52, 52, 31, 22, 62]];
// given list of lists of randomly-ordered indices
List<List<Integer>> indexList = Arrays.toList([
Arrays.toList([1, 4, 5, 2, 0, 3, 6]),
Arrays.toList([4, 2, 5, 3, 1, 6, 0]),
Arrays.toList([0, 3, 6, 1, 2, 4, 5])
]);
// first, create a place to store the sums corresponding to each random list
List<Integer> sums = new ArrayList<Integer>();
// iterate over each of the lists of random elements
for(List<Integer> randomIndices: indexList){
// create a running sum for this list
int randomSum = 0;
// iterate over each element of the randomized index list
for(int j = 0; j < randomIndices.size(); j++){
// read the current and next index (using modulo to wrap around)
current = randomIndices.get(j);
next = randomIndices.get((j + 1) % randomIndices.size());
// add the relevant index in array to the running sum
randomSum += array[current][next];
}
// add the recorded randomSum to the sums list.
// Its index is the same as the random list we just iterated over
sums.add(randomSum);
}
System.out.println(sums);
You may iterate over the alues of each List<Integer> then look them by pair (use % to go back at the beginning) and use them to index the 2d array
for (List<Integer> l : list) {
int sum = 0;
for (int i = 0; i < l.size(); i++) {
int p1 = l.get(i % l.size());
int p2 = l.get((i + 1) % l.size());
sum += values[p1][p2];
}
System.out.println(sum);
}
With this as initial data
List<List<Integer>> list = List.of(List.of(1, 4, 5, 2, 0, 3, 6), List.of(4, 2, 5, 3, 1, 6, 0));
int[][] values = new int[][]{new int[]{31, 21, 34, 22, 67, 14, 41}, new int[]{17, 42, 31, 57, 26, 23, 52}, new int[]{5, 92, 52, 52, 31, 22, 62},
new int[]{17, 42, 31, 57, 26, 23, 52}, new int[]{5, 92, 52, 52, 31, 22, 62}, new int[]{31, 21, 34, 22, 67, 14, 41}, new int[]{5, 92, 52, 52, 31, 22, 62},};
it'll print
253
262
I am stuck and can't think of a way to properly shift an array by __ units. I am trying to create an array of 30 items (numbers 1-30) which can then be shifted to the right by the number the user inputs. This would mean that the first few numbers in the array would take the index's at the end of the array, and the rest of the numbers would be shifted to the left. (Ex, if shift = 3, numbers 1,2,3 would take the index of 27,28,29, and the rest of the numbers 4-30 would shift left making index 0 =4, index 1=5, index 2=6....
import java.util.*;
class Main {
public static void main(String[] args) {
Scanner input = new Scanner (System.in);
System.out.println("\nEnter the shift/rotation:");
int shiftNum = input.nextInt();
int [] numArray = new int [30];
for(int i = 0; i < 30; i++){
numArray [i] = i+1;
System.out.print(numArray[i]+" ");
}
}
}
This is the code I have so far, any suggestions to how I can do this? I have tried to make a separate for loop like
numArray [i-shiftNum] = numArray[i];
But when doing this, the index of 0-shiftNum would be negative and would not work. This is the context of the problem:
Create a program that will create an array of 30 items. Then it will rotate the array by a number selected by the user.
In order to shift the numbers in the array, the following for loop works for shifting the values within the array.
// prerequisite: array is already filled with values
for(int i = 0; i < numArray.length; i++) {
arr[i] += shiftNum;
if (numArray[i] > 30) {
numArray[i] -= 30;
} else if (numArray[i] <= 0) {
numArray[i] += 30;
}
}
According to you code, the array created will contain value from 1 - 30 including 1 and 30. If you want your code to contain values from 0 - 29 instead, change numArray[i] > 30 to numArray[i] >= 30 and change numArray[i] <= 0 to numArray[i] < 0.
Use Java's convenience methods. Most people still want to write for loops. Basically, you need to save off the elements you are overwriting with the shift. Then place those saved ones back in the array. System.arraycopy is nice in that it takes care of some nasty parts of moving elements in an array.
void shift(int shiftBy, int... array) {
int[] holdInts = Arrays.copyOf(array, shiftBy);
System.arraycopy(array, shiftBy, array, 0, array.length - shiftBy);
System.arraycopy(holdInts, 0, array, array.length - shiftBy, holdInts.length);
}
Here is quick fix for you. Please check following code.
Input :
Enter the shift/rotation: 4
Output :
Rotate given array [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30]
After Rotate [27, 28, 29, 30, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26]
public static void main(String[] args) {
RotationDemo rd = new RotationDemo();
int[] input = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30};
int k = 0;
Scanner scan = new Scanner (System.in);
try{
System.out.println("\nEnter the shift/rotation:");
int shiftNum = scan.nextInt();
if(shiftNum < 30) {
k = shiftNum;
System.out.println("Rotate given array " + Arrays.toString(input));
int[] rotatedArray = rd.rotateRight(input, input.length, k);
System.out.println("After Rotate " +
Arrays.toString(rotatedArray));
} else {
System.out.println("Shift number should be less than 30");
}
} catch(Exception ex){
} finally {
scan.close();
}
}
public int[] rotateRight(int[] input, int length, int numOfRotations) {
for (int i = 0; i < numOfRotations; i++) {
int temp = input[length - 1];
for (int j = length - 1; j > 0; j--) {
input[j] = input[j - 1];
}
input[0] = temp;
}
return input;
}
Hope this example works.
I'm using binarySearch and it's worked well with arrays that has even index, but when the array has odd index (length) it's give wrong result.
What i'v done so fare:
public static int binarySearch(int[] list, int key) {
int low = 0;
int high = list.length - 1;
while (high >= low) {
int mid = (low + high) / 2;
if (key < list[mid])
high = mid - 1;
else if (key == list[mid])
return mid;
else
low = mid + 1;
}
return - 1;
}
Input:
int[] arr1 = {5, 6, 8, 9, 11, 12, 11, 50, 1, 3, 15, 121, 33, 16, 17, 18, 19};
int[] arr2 = {5, 6, 8, 9, 11, 12, 11, 50, 1, 3, 15, 121, 33, 16, 17, 18};
Case:
System.out.println(binarySearch(arr1, 12));
System.out.println(binarySearch(arr2, 12));
OutPut:
-1
5
How i can get the right outPut in the both situation?
Binary search only works on sorted array
Solution : add Arrays.sort(list)
public static int binarySearch(int[] list, int key) {
Arrays.sort(list);
int low = 0;
int high = list.length - 1;
while (high >= low) {
int mid = (low + high) / 2;
if (key < list[mid]) high = mid - 1;
else if (key == list[mid]) return mid;
else low = mid + 1;
} return - 1;
}
You must sort the arrays before doing binary search operation.
In your question you are unable to search for the odd array length.
In java its very easy.
You can use the below code.
import java.util.Arrays;
class BS
{
public static void main(String args[])
{
int[] arr1 = {5, 6, 8, 9, 11, 12, 11, 50, 1, 3, 15, 121, 33, 16, 17, 18, 19};
System.out.println(Arrays.binarySearch(arr1 , '12'));
}
}
I have an arrayList filled with integers and I need to iterate through this arrayList, add the numbers up until a threshold is reached, then put the resulting sum into a second arrayList slot, and move back to where I left off in the original arrayList, keep iterating and summing until the threshold is reached and then put that in the second slot, and so on until all 40 original items have been summed and put into a smaller arrayList.
I've thought of using two nested loops but I can't get the two loops to work together.
I'm very new to Java and don't know how to do this. Any suggestions will be helpful.
This is what I have so far:
int threshold = 12;
int sumNum = 0;
int j = 0;
int arr1[] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
for (int i = 0; i < arr1.length; i++) {
while (sumNum <= threshold) {
sumNum += arr[j];
j++
}//end while
}//end for
You can actually do this with just one loop. You don't need to move back, just stay where you are and keep going on the sum.
public static ArrayList<Integer> sums(ArrayList<Integer> arr, int threshold){
ArrayList<Integer> sumArr = new ArrayList<Integer>();
int s = 0; //Sum thus far, for the current sum
for(int i : arr){
s += i; //Add this element to the current sum
if(s >= threshold){ //If the current sum has reached/exceeded the threshold
sumArr.add(s); //Add it to the sumArray, reset the sum to 0.
s = 0;
}
}
return sumArr;
}
You can change the input param from ArrayList to int[] or Integer[] without any trouble whatsoever. Hooray for for-each loops!
Code to use the above:
public static void main(String[] args){
ArrayList<Integer> i = new ArrayList<Integer>();
//create arraylist 1..20
for(int x = 1; x <= 20; x++){
i.add(x);
}
System.out.println(sums(i).toString());
}
package com.test;
import java.util.ArrayList;
import java.util.List;
public class Test {
public static void main(String[] args) {
int threshold = 12;
int sumNum = 0;
int j = 0;
int arr1[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
List myList = new ArrayList();
for (int i = 0 ; i < arr1.length ; i++) {
sumNum += i;
if (sumNum >= threshold) {
myList.add(sumNum);
sumNum = 0;
}
}
for (int a = 0 ; a < myList.size() ; a++) {
System.out.println(myList.get(a));
}
}
}
output
15
13
17
21
12
13
14
How about something like this:
/**
* Sequentially adds numbers found in the source array until the sum >= threshold.
* <p/>
* Stores each threshold sum in a separate array to be returned to the caller
* <p/>
* Note that if the last sequence of numbers to be summed does not meet the threshold,
* no threshold sum will be added to the result array
*
* #param numbersToSum The source number list
* #param threshold The threshold value that determines when to move on to
* the next sequence of numbers to sum
*
* #return An array of the calculated threshold sums
*/
public static Integer[] sumWithThreshold(int[] numbersToSum, int threshold)
{
List<Integer> thresholdSums = new ArrayList<Integer>();
if (numbersToSum != null)
{
int workingSum = 0;
for (int number: numbersToSum)
{
workingSum = workingSum + number;
if (workingSum >= threshold)
{
thresholdSums.add(workingSum);
workingSum = 0;
}
}
}
return thresholdSums.toArray(new Integer[thresholdSums.size()]);
}
public static void main(String[] args)
{
int[] testNumbers =
{
1,2,3,4,5,6,7,8,9,10,
11,12,13,14,15,16,17,18,19,20,
21,22,23,24,25,26,27,28,29,30,
31,32,33,34,35,36,37,38,39,40};
int[] thresholds = {1, 42, 100, 200};
for (int threshold: thresholds)
{
System.out.println("Threshold sums for threshold = " + threshold + ":\n" + Arrays.toString(sumWithThreshold(testNumbers, threshold)));
}
}
That produces the following output:
Threshold sums for threshold = 1:
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40]
Threshold sums for threshold = 42:
[45, 46, 45, 54, 63, 47, 51, 55, 59, 63, 67, 71, 75, 79]
Threshold sums for threshold = 100:
[105, 105, 115, 110, 126, 105, 114]
Threshold sums for threshold = 200:
[210, 225, 231]