Related
I am working on a game in Java and I need to cache some position-based information. If I have the following array:
int[][] array = {
{1, 2, 3},
{1, 2, 3},
{1, 2, 3}
};
And then I have this other array:
int[][] otherArray = {
{4, 5, 6},
{4, 5, 6},
{4, 5, 6}
};
Now I want to combine them in a special way. I want to add otherArray to the left of array. So the result would look like this:
int[][] combinedArray = {
{4, 5, 6, 1, 2, 3},
{4, 5, 6, 1, 2, 3},
{4, 5, 6, 1, 2, 3}
};
Then I have this other combined array:
int[][] otherCombinedArray = {
{30, 17, 139, 65, 335, 99},
{50, 43, 57, 53, 423, 534},
{90, 67, 78, 24, 99, 67}
};
Now I want to add it to the top of the original combined array. So the final result would look like this:
int[][] finalCombinedArray = {
{30, 17, 139, 65, 335, 99},
{50, 43, 57, 53, 423, 534},
{90, 67, 78, 24, 99, 67},
{4, 5, 6, 1, 2, 3},
{4, 5, 6, 1, 2, 3},
{4, 5, 6, 1, 2, 3}
};
Can someone point me to a good library or built in method for doing this? I also wanted to note that the method shouldn't be too computationally heavy (like looping through all the arrays multiple times, and it shouldn't use too much memory, like 80MB).
Thank you for the help!
On it's own, Java does not provide concatenation methods, but we can use System.arraycopy (as suggested by #user16320675 above)
With System.arraycopy you specify the array to copy + the destination array -> you have array A of size 10 and B of size 2, and you use the command to copy your B array into A.
int[] source = { 1,2,3,4,5 };
int[] destination = new int[10];
// You can play with the numbers below
int COPY_AT_INDEX = 0; // Start to copy at position destination[0]
int AMOUNT_TO_COPY = 5; // Copying from 0 to source.length
System.arraycopy(source, 0, destination, COPY_AT_INDEX, AMOUNT_TO_COPY);
System.out.println(Arrays.toString(source)); // [1, 2, 3, 4, 5]
System.out.println(Arrays.toString(destination)); // [1, 2, 3, 4, 5, 0, 0, 0, 0, 0]
Now, if we use arraycopy, seems you have to determine when to copy as rows, and when to copy as columns.
// Assuming a[][] and b[][] have the same size.
public int[][] mergeAsColumns(int[][] a, int[][] b) {
int rows = a.length;
int columns = a[0].length;
int[][] merged = new int[rows][2 * columns];
for (int i = 0; i < a.length; i++) {
System.arraycopy(a[i], 0, merged[i], 0, columns);
System.arraycopy(b[i], 0, merged[i], rows, columns);
}
return merged;
}
Merging as Rows is similar to the other one, but changes in which positions you want to affect and how you create the merged array.
// Assuming a[][] and b[][] have the same size.
public int[][] mergeAsRows(int[][] a, int[][] b) {
int rows = a.length;
int columns = a[0].length;
int[][] merged = new int[2 * rows][columns];
for (int i = 0; i < rows; i++) {
System.arraycopy(a[i], 0, merged[i], 0, columns);
System.arraycopy(b[i], 0, merged[rows + i], 0, columns);
}
return merged;
}
I have a troubles with an application.
I would like to move my String into this ArrayList.
My String contains numbers like 15 17 18 110 113 (numbers from 1 do 200).
I have about 80 numbers in one String, eg.:
I/System.out: 15 13 13 12 12 11 11 21 21 39 39 38 38 40 40 41 41 42 42 43 43 74 74 75 75 76 76 77 77 78 78 80 80 99 99 100 100 102 102 103 103 105 105 104
While I have List<String> tmpPath = new ArrayList<>(); and I have tried two different methods:
1.
public void transferStringToArray(string s1){
for(int i = 0; i < s1.length(); i++){
int extra = 0;
if(s1.charAt(i) != ' '){
String x = Character.toString(s1.charAt(i));
tmpPath.add(extra, x);
else extra++;
}
}
where the output is:
I/System.out: [4, 0, 1, 5, 0, 1, 5, 0, 1, 3, 0, 1, 3, 0, 1, 2, 0, 1, 2, 0, 1, 0, 0, 1, 0, 0, 1, 9, 9, 9, 9, 0, 8, 0, 8, 8, 7, 8, 7, 7, 7, 7, 7, 6, 7, 6, 7, 5, 7, 5, 7, 4, 7, 4, 7, 3, 4, 3, 4, 2, 4, 2, 4, 1, 4, 1, 4, 0, 4, 0, 4, 8, 3, 8, 3, 9, 3, 9, 3, 1, 2, 1, 2, 1, 1, 1, 1, 2, 1, 2, 1, 3, 1, 3, 1, 5, 1]
(numbers are printed from last to first number which is wrong with my assumptions)
2.
public void transferStringToArray(string s1){
for(int i = 0; i < s1.length(); i++)
if(s1.charAt(i) != ' '){
String x = Character.toString(s1.charAt(i));
tmpPath.add(x);
}
where the output is in good order, but one number means one index of an array.
I/System.out: [1, 5, 1, 3, 1, 3, 1, 2, 1, 2, 1, 1, 1, 1, 2, 1, 2, 1, 3, 9, 3, 9, 3, 8, 3, 8, 4, 0, 4, 0, 4, 1, 4, 1, 4, 2, 4, 2, 4, 3, 4, 3, 7, 4, 7, 4, 7, 5, 7, 5, 7, 6, 7, 6, 7, 7, 7, 7, 7, 8, 7, 8, 8, 0, 8, 0, 9, 9, 9, 9, 1, 0, 0, 1, 0, 0, 1, 0, 2, 1, 0, 2, 1, 0, 3, 1, 0, 3, 1, 0, 5, 1, 0, 5, 1, 0, 4]
Do you have any ideas how to move full number as one index separated by a space?
Also I have one more question:
How could I delete all repeated numbers? I know, that numbers are printed once or twice but in the result I have to have unique numbers.
All you need to do is a split with space s.split("\\s+"), and then put the result in a Set like this:
Set<String> set = new HashSet<>(Arrays.asList(s.split("\\s+")));
Or if you want to maintain the order, you can use :
Set<String> set = new LinkedHashSet<>(Arrays.asList(s.split("\\s+")));
If you are looking to use List and nothing else, then you can use, distinct like so :
List<String> set = Arrays.stream(s.split("\\s+"))
.distinct()
.collect(Collectors.toList());
Outputs
[15, 13, 12, 11, 21, 39, 38, 40, 41, 42, 43, 74, 75, 76, 77, 78, 80, 99, 100, 102, 103, 105, 104]
To convert space separated string into an array list :
You first need to split your string into an string array and then convert it into array list
public void convertStringToList() {
String stringToSplit = "15 13 13 12";
String[] splittedString = stringToSplit.split(" "); // Will split string based upon the space into an string array
List<String> listOfStrings = Arrays.asList(splittedString);
}
To remove the duplicates, you can insert all the array lists value into a Set. A set is a data structure in java which stores only unique values.
Set<String> uniqueValuesSet = new HashSet<>(listOfStrings);
for(String str : uniqueValuesSet) {
System.out.println(str);
}
In 2nd point, you might see your output is in random order. That is because HashSet doesn't maintain order of elements. If you need to maintain order as well. Use LinkedHashSet.
Set<String> uniqueValuesSet = new LinkedHashSet<>(listOfStrings);
for(String str : uniqueValuesSet) {
System.out.println(str);
}
Note: This solution assumes number in the original string are single space separated. If you want solution irrespective of number of spaces between 2 numbers, replace this line in point 1
String[] splittedString = stringToSplit.split(" ");
To
String[] splittedString = stringToSplit.split("\\s+");
I'm sticking with Set, as MaciejB wanted to eliminate duplicates and that's the contract of Set.
And, as MaciejB mentioned order too, I parsed them as Integer & put 'em in a TreeSet.
That looks like this:
Set<Integer> set = Stream.of(s.split("\\s+")).map(Integer::parseInt).collect(Collectors.toCollection(TreeSet::new));
Or if you prefer multiple lines:
Set<Integer> set = Stream // Result is ordered, parsed Set
.of(s.split("\\s+")) // -> String[]
.map(Integer::parseInt) // -> Integer[] for order in TreeSet
.collect(Collectors.toCollection(TreeSet::new)); // no duplicates
Outputs:
[11, 12, 13, 15, 21, 38, 39, 40, 41, 42, 43, 74, 75, 76, 77, 78, 80, 99, 100, 102, 103, 104, 105]
I have a function that builds an array with N elements, with the distribution to 0 to 100 . For example:
int[] a = {100,80, 50,20, 0};
I want to resize this array to fill a new array with the size of N = 10, but keep the number distribution of the previous array. I think that with some probabilistic distribution, I can achieve this, but don't know how to do it.
Can someone please help?
If I understood the question right, the goal is to redistribute numbers from source array into new array, putting numbers in bins by 10. So, if number is 0 it should go to new array at index 0 (since it's in the range [0, 10]), and if the number is 20 - it should go to index 1 (since, it's in the range [11, 20]), and so forth.
If the assumption is correct, then this is one approach:
import java.util.Arrays;
public class ReDistribution {
public static void main(String[] args) {
int[] distribution = {100, 80, 50, 20, 0};
System.out.println(Arrays.toString(reDistribute(distribution)));
// prints: [0, 20, 0, 0, 50, 0, 0, 80, 0, 100]
}
/**
* Assuming source array contains only integers in range [0, 100], redistributes into array
* index 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
* range [0, 10], [11, 20], [21, 30], [31, 40], [41, 50], [51, 60], [61, 70], [71, 80], [81, 90], [91, 100]
*/
private static int[] reDistribute(int[] source) {
int[] target = new int[10];
for (int num : source) {
target[(num - 1) / 10] = num;
}
return target;
}
}
So I have this data
{ { 1, 3, 5, 3, 1 },
{ 3, 5, 6, 5, 1 },
{ 7, 2, 3, 5, 0 },
{ 12, 1, 5, 3, 0 },
{ 20, 6, 3, 6, 1 },
{ 20, 7, 4, 7, 1 } }
and i want to save it into some kind of collection, list or set. So if that collection was named List,if i were to type List[0][3] it would reffer to int 4.
I tried with
ArrayList<int[]> myNumberList = new ArrayList<int[]>();
but i have trouble putting that data into list
The array access operator [] is only applicable to arrays. So you can only create 2-dimensional array.
int a[][] = new int[][]{
{1, 3, 5, 3, 1},
{3, 5, 6, 5, 1},
{7, 2, 3, 5, 0},
{12, 1, 5, 3, 0},
{20, 6, 3, 6, 1},
{20, 7, 4, 7, 1}
};
System.out.println(a[0][3]);
But you can't create any type of collection that can use [] to access it's values.
Yoy can still use List of arrays. But you will have to index first dimension, using get() method
List<int[]> a2 = Arrays.asList(
new int[]{1, 3, 5, 3, 1},
new int[]{3, 5, 6, 5, 1},
new int[]{7, 2, 3, 5, 0},
new int[]{12, 1, 5, 3, 0},
new int[]{20, 6, 3, 6, 1},
new int[]{20, 7, 4, 7, 1}
);
System.out.println(a2.get(0)[3]);
You could make it an Integer[][] and create a List<List<Integer>>. Something like,
Integer[][] arr = { { 1, 3, 5, 3, 1 }, { 3, 5, 6, 5, 1 },
{ 7, 2, 3, 5, 0 }, { 12, 1, 5, 3, 0 }, { 20, 6, 3, 6, 1 },
{ 20, 7, 4, 7, 1 } };
System.out.println(Arrays.deepToString(arr));
List<List<Integer>> al = new ArrayList<>();
for (Integer[] inArr : arr) {
al.add(Arrays.asList(inArr));
}
System.out.println(al);
which outputs (formatted for this post)
[[1, 3, 5, 3, 1], [3, 5, 6, 5, 1], [7, 2, 3, 5, 0],
[12, 1, 5, 3, 0], [20, 6, 3, 6, 1], [20, 7, 4, 7, 1]]
[[1, 3, 5, 3, 1], [3, 5, 6, 5, 1], [7, 2, 3, 5, 0],
[12, 1, 5, 3, 0], [20, 6, 3, 6, 1], [20, 7, 4, 7, 1]]
Hard to answer what do you really need in your particular case. But in general list-equivalent of 2-dimensional array, which, I guess, you are looking for, will be List<List<Integer>> type, and in java-8 you can convert it in such way:
int a[][] = new int[][]{
{1, 3, 5, 3, 1},
{3, 5, 6, 5, 1},
{7, 2, 3, 5, 0},
{12, 1, 5, 3, 0},
{20, 6, 3, 6, 1},
{20, 7, 4, 7, 1}};
List<List<Integer>> l2 = new ArrayList<>();
Stream.of(a).forEach(a1 -> l2.add(Arrays.stream(a1).boxed().collect(Collectors.toList())));
I am attempting to make a QuickSort program and while I feel like it should be outputting as desired, it is not. I feel the problems lies in how I have constructed my loops but that may not be the case. As you can see, the first test with the runner prints out as I want and everything eventually gets sorted right. Any help would be greatly appreciated.
My main program:
import static java.lang.System.*;
import java.util.Arrays;
//use Arrays.toString() to help print out the array
public class QuickSort
{
private static int passCount;
public static void quickSort(Comparable[] list)
{
passCount=0;
quickSort(list, 0, list.length-1);
}
private static void quickSort(Comparable[] list, int low, int high)
{
if(low >= high)
return;
int a = partition(list, low, high);
quickSort(list, low, a-1);
quickSort(list, a+1, high);
}
private static int partition(Comparable[] list, int low, int high)
{
int x = low + 1;
int y = high;
while(x <= y)
{
if(list[x].compareTo(list[low]) <= 0)
{x++;}
else if(list[y].compareTo(list[low]) > 0)
{y--;}
else if(y < x)
{break;}
else
exchange(list, x, y);
}
exchange(list, low, y);
out.println("pass " + passCount++ + " " + Arrays.toString(list) + "\n");
return y;
}
private static void exchange(Object[] list, int x, int y) {
Object temporary = list[x];
list[x] = list[y];
list[y] = temporary;
}
}
My runner:
public class QuickSortRunner
{
public static void main(String args[])
{
QuickSort.quickSort(new Comparable[]{9,5,3,2});
System.out.println("\n");
QuickSort.quickSort(new Comparable[]{19,52,3,2,7,21});
System.out.println("\n");
QuickSort.quickSort(new Comparable[]{68,66,11,2,42,31});
System.out.println("\n");
}
}
My output:
pass 0 [2, 5, 3, 9]
pass 1 [2, 5, 3, 9]
pass 2 [2, 3, 5, 9]
pass 0 [2, 7, 3, 19, 52, 21]
pass 1 [2, 7, 3, 19, 52, 21]
pass 2 [2, 3, 7, 19, 52, 21]
pass 3 [2, 3, 7, 19, 21, 52]
pass 0 [31, 66, 11, 2, 42, 68]
pass 1 [11, 2, 31, 66, 42, 68]
pass 2 [2, 11, 31, 66, 42, 68]
pass 3 [2, 11, 31, 42, 66, 68]
Desired output:
pass 0 [2, 5, 3, 9]
pass 1 [2, 5, 3, 9]
pass 2 [2, 3, 5, 9]
pass 0 [7, 2, 3, 52, 19, 21]
pass 1 [3, 2, 7, 52, 19, 21]
pass 2 [2, 3, 7, 52, 19, 21]
pass 3 [2, 3, 7, 21, 19, 52]
pass 4 [2, 3, 7, 19, 21, 52]
pass 0 [31, 66, 11, 2, 42, 68]
pass 1 [2, 11, 66, 31, 42, 68]
pass 2 [2, 11, 66, 31, 42, 68]
pass 3 [2, 11, 42, 31, 66, 68]
pass 4 [2, 11, 31, 42, 66, 68]
The x++ and y-- to skip exchanges need to be in while loops so that exchange happens only when it is called for.