I have come across many examples to split the given array or array list into two arrays or multiple arrays using an index point. I tried them and they are working perfectly. My question is, is it possible to split the array into multiple arrays of varying chunk size given the index point?
For example:
array[] = {10,1,2,3,10,4,5,10,6,7,10,8,10};
index_value = 10;
Then the output should be four arrays such as:
arr1[] = {1,2,3}
arr2[] = {4,5}
arr3[] = {6,7}
arr4[] = {8}
I was able to split them and display the results when the given array is static with no changes. But implementing the same for an array with random numbers and random size was hard. I need to store the split values in many sub arrays and not just printing the values.
For this solution, the index_value does not have to be at the start or end of the array:
int[] arr = new int[]{10,10,1,10,1,2,3,10,4,5,10,6,7,10,8,10,9,8,7,6,5,4,3,10,1,2,3,4,5,6,7,10,5,4,10,10};
int index_value = 10;
/** walk through the array and create the arraylist of arraylists */
ArrayList<ArrayList<Integer>> al = new ArrayList<ArrayList<Integer>>();
ArrayList<Integer> currAl = null;
for (int i=0; i < arr.length; i++) {
if (arr[i] == index_value) {
if (currAl != null && currAl.size() > 0)
al.add(currAl);
currAl = new ArrayList<Integer>();
} else {
if (currAl == null)
currAl = new ArrayList<Integer>();
currAl.add(arr[i]);
}
}
if (arr[arr.length-1]!= index_value && currAl.size() > 0) {
al.add(currAl);
}
/** print out the arraylist of arraylists */
for (int i=0; i < al.size(); i++) {
currAl = al.get(i);
for (int j=0; j < currAl.size(); j++) {
System.out.print(currAl.get(j) + " ");
}
System.out.println();
}
You can build your arrays by using the ArrayList class to fill in your values
array[] = {10,1,2,3,10,4,5,10,6,7,10,8,10};
index_value = 10;
ArrayList<ArrayList<int>> allLists = new ArrayList<ArrayList<int>>();
ArrayList<int> currentList;
for (int i = 0;i < array.length;i++)
{
//in case your array doesn't contain the index_value at index 0
//check for the null case
if (array[i] == index_value || currentList == null)
{
currentList = new ArrayList<int>();
allLists.add(currentList);
}
else
{
currentList.add(array[i]);
}
}
if (allLists.size() > 0 && allLists.get(allLists.size() - 1).size() == 0)
{
allLists.remove(allLists.size() - 1);
}
What you should have is an ArrayList that contains ArrayLists that contain the numbers you are interested in. If the index_value is repeated twice in a row, however, you will end up with empty lists (which can be removed later). This includes the final list, which I automatically remove if it is empty (since your example lists the index_value as being at both the start and the end.
If you would like the output to be in arrays, you can just call .toArray() on the ArrayList
You might try the following strategy: look for your marker boundaries, form an array from each segment as encountered, and put result in a Vector (for example).
package com.splitter;
import java.util.Vector;
public class Splitter {
/**
* #param args
*/
public static void main(String[] args) {
int[] array = {10, 1,2,3,10,4,5,10,6,7,10,8,10};
Vector <int[]> result;
result = split(array,10);
for (int i = 0; i < result.size(); i++) {
int[] split = result.get(i);
System.out.println("Array " + i);
for (int j=0; j<split.length; j++) {
System.out.println(split[j]);
}
}
}
private static Vector<int[]> split(int[] array, int value) {
Vector<int[]> result = new Vector<int[]>();
int loc = 0;
int start = 0;
boolean isInside = false;
while (loc < array.length) {
if (array[loc] == value) {
if (isInside) { // make array from start to here
// make an array from start+1 to loc-1
System.out.println(" .." + start + " " + loc + " v=" + array[loc] );
int[] split = new int[loc - start - 1];
for (int i = 0; i < split.length; i++) {
split[i] = array[start+1+i];
}
result.add(split);
isInside = true;
}
start = loc;
isInside = true;
}
loc++;
}
return result;
}
}
I tried in NetBeans, debug, and works well.
The values will be stored like in a ArrayList with more ArrayLists inside, like this:
arrayOfIntList.get(0) = > 1,2,3
arrayOfIntList.get(0).get(0) -> 1
arrayOfIntList.get(0).get(1) -> 2
arrayOfIntList.get(0).get(2) -> 3
arrayOfIntList.get(1) = > 4,5
arrayOfIntList.get(1).get(0) -> 4
arrayOfIntList.get(1).get(1) -> 5
arrayOfIntList.get(2) = > 6,7
arrayOfIntList.get(2).get(0) -> 6
arrayOfIntList.get(2).get(1) -> 7
arrayOfIntList.get(3) = > 8
arrayOfIntList.get(3).get(0) -> 8
import java.util.ArrayList;
public class Javaprueba {
public static void main(String[] args) {
int[] myarray = {10,1,2,3,10,4,5,10,6,7,10,8,10};
int splitterInt = 10;
int j = 0;
int k = 0;
ArrayList<Integer> tempArray = new ArrayList<Integer>();
ArrayList<ArrayList<Integer>> arrayOfIntList = new ArrayList<ArrayList<Integer>>();
for(int i=0; i<myarray.length; i++){
if(myarray[i] != splitterInt){
tempArray.add(j, myarray[i]);
j++;
}else{
if(tempArray.size() > 0){
arrayOfIntList.add(k, tempArray);
k++;
tempArray = new ArrayList<Integer>();
j=0;
}
}
if(i == myarray.length-1 && tempArray.size()>0){
arrayOfIntList.add(k, tempArray);
}
}
}
}
Related
public static String[] dictionary(String s){
int count=0;
String[] ans = sentence(s);
int size = ans.length;
for (int i = 0; i < size - 1; i++) {
for (int j = i + 1; j < ans.length; j++) {
if (ans[i].compareTo(ans[j]) > 0) {
String temp = ans[i];
ans[i] = ans[j];
ans[j] = temp;
}
}
}
for (int i = 0; i < ans.length; i++) {
ans[i] = [i].to lowerCase);
}
return ans;
}
I have to find duplicated strings and remove them from an array of strings that are sorted lexicographically
Because you know that incoming array sorted, you can get current element and compare next elements with current one. If it is equals skip it, otherwise add this element to the result, and change current. Something like this
public static String[] dictionary(String s){
String[] ans = sentence(s);
if (ans == null || ans.length == 0) {
return ans;
}
List<String> result = new ArrayList<String>();
String current = ans[0];
result.add(current);
for (int i= 1; i < ans.length; i++) {
if (!ans[i].equals(current)) {
result.add(ans[i]);
current = ans[i];
}
}
return result.toArray(new String[0]);
}
If you don't want to use sets, you can do it like this. And it does not require a sorted array. It works as follows. Note: This changes the passed in array.
Get the first element. If it is null continue to next element.
Compare first element to next.
If equal, replace next with a null and increment removed
Continue processing elements.
Now create a new array of original size minus - removed.
And copy all non null values to new array and return it.
public static String[] removeDups(String[] arr) {
// keep track of removed values
int removed = 0;
for (int i = 0; i < arr.length-1; i++) {
for (int j = i+1; j < arr.length; j++) {
if (arr[i] == null) {
// skip this entry and go to next
break;
}
if (arr[i].equals(arr[j])) {
// designate as removed
arr[j] = null;
removed++;
}
}
}
// copy remaining items to new array and return.
String[] result = new String[arr.length-removed];
int k = 0;
for (int i = 0; i < arr.length; i++) {
if (arr[i] != null) {
result[k++] = arr[i];
}
}
return result;
}
If you want to do it with streams you can do it this way.
String[] result = Arrays.stream(arr).distinct().toArray(String[]::new);
A simple way to do this would be to place them into a set
Set<String> setsHaveNoDuplicates = new HashSet<>(Arrays.asList(ans));
Sets have no duplicates, and if you want to convert the set back to an array of strings, you can do this
String[] result = setsHaveNoDuplicates.toArray(new String[0]);
How can I randomize arrayList
so that old index must not be the same as new index for all elements
for example
with a list with 3 items
after arrayList randomize
old index<->new index
1<-->2 <--different
2<-->1 <--different
3<-->3 <--same is not allowed
I want to make sure it will be
1<-->3 <--different
2<-->1 <--different
3<-->2 <--different
Collections.shuffle(List<?> list)
This should work with Lists which don't contain null values:
static <T> void shuffleList(List<T> list) {
List<T> temp = new ArrayList<T>(list);
Random rand = new Random();
for (int i = 0; i < list.size(); i++) {
int newPos = rand.nextInt(list.size());
while (newPos == i||temp.get(newPos)==null) {
newPos = rand.nextInt(list.size());
}
list.set(i, temp.get(newPos));
temp.set(newPos,null);
}
}
For list with null values:
static <T> void shuffleList(List<T> list) {
List<T> temp = new ArrayList<T>(list);
Integer [] indexes=new Integer[list.size()];
for (int i=0;i<list.size();i++){
indexes[i]=i;
}
Random rand = new Random();
for (int i = 0; i < list.size(); i++) {
int newPos = rand.nextInt(list.size());
while (newPos == i||indexes[newPos]==null) {
newPos = rand.nextInt(list.size());
}
list.set(i, temp.get(newPos));
indexes[newPos]=null;
}
}
That's something you have to implement yourself.
The shuffle is probably a series of random swaps (e.g. swap 1 -> 4,
swap 3 -> 2).
Keep track of each element's new position (e.g. 4 3 2
1 5 for a list with 5 elements and the above shuffle operations).
If any element is still at it's old place (5 in that example),
keep on shuffling.
Sounds like fun.
var numExist = [];
while(numExist.length!=array.length){
var randomizer = new Random();
int i =0;
var num = randomizer.nextInt(array.length);
if(!numExist.contains(num)){
array[i]=array[num];
numExist.add(num);
i++;
}
}
The following is a variation of Fisher-Yates which caters to the possibility that at least one item will remain in its original position.
The current Collections.shuffle() does not perform a complete randomization of the list.
public static void shuffle(List<Integer> list) {
Random r = new Random();
int size = list.size();
boolean flag = true;
for (int i = size - 1; i >= 0 && flag; i--) {
int pos = r.nextInt(i + 1);
if (list.get(i) == pos) {
if (i == 0) {
flag = false;
break;
}
// counter the upcoming decrement by incrementing i
i++;
continue;
}
int temp = list.get(i);
list.set(i, list.get(pos));
list.set(pos, temp);
}
// At this juncture, list.get(0) points to itself so choose a random candidate
// and swap them.
if (!flag) {
int pos = r.nextInt(size - 1) + 1;
int temp = list.get(0);
list.set(0, list.get(pos));
list.set(pos, list.get(0));
}
}
There may still be eventual problems but I used the following code to test the
shuffle with no problems detected.
for (int k = 0; k < 100000; k++) {
List<Integer> list =
IntStream.range(0, 52).boxed().collect(Collectors.toList());
System.out.println("Test run #" + k);
// Collections.shuffle(list);
shuffle(list);
for (int i = 0; i < list.size(); i++) {
if (i == list.get(i)) {
System.out.printf("Oops! List.get(%d) == %d%n", list.get(i), i);
}
}
}
So I need a way to find the mode(s) in an array of 1000 elements, with each element generated randomly using math.Random() from 0-300.
int[] nums = new int[1000];
for(int counter = 0; counter < nums.length; counter++)
nums[counter] = (int)(Math.random()*300);
int maxKey = 0;
int maxCounts = 0;
sortData(array);
int[] counts = new int[301];
for (int i = 0; i < array.length; i++)
{
counts[array[i]]++;
if (maxCounts < counts[array[i]])
{
maxCounts = counts[array[i]];
maxKey = array[i];
}
}
This is my current method, and it gives me the most occurring number, but if it turns out that something else occurred the same amount of times, it only outputs one number and ignore the rest.
WE ARE NOT ALLOWED TO USE ARRAYLIST or HASHMAP (teacher forbade it)
Please help me on how I can modify this code to generate an output of array that contains all the modes in the random array.
Thank you guys!
EDIT:
Thanks to you guys, I got it:
private static String calcMode(int[] array)
{
int[] counts = new int[array.length];
for (int i = 0; i < array.length; i++) {
counts[array[i]]++;
}
int max = counts[0];
for (int counter = 1; counter < counts.length; counter++) {
if (counts[counter] > max) {
max = counts[counter];
}
}
int[] modes = new int[array.length];
int j = 0;
for (int i = 0; i < counts.length; i++) {
if (counts[i] == max)
modes[j++] = array[i];
}
toString(modes);
return "";
}
public static void toString(int[] array)
{
System.out.print("{");
for(int element: array)
{
if(element > 0)
System.out.print(element + " ");
}
System.out.print("}");
}
Look at this, not full tested. But I think it implements what #ajb said:
private static int[] computeModes(int[] array)
{
int[] counts = new int[array.length];
for (int i = 0; i < array.length; i++) {
counts[array[i]]++;
}
int max = counts[0];
for (int counter = 1; counter < counts.length; counter++) {
if (counts[counter] > max) {
max = counts[counter];
}
}
int[] modes = new int[array.length];
int j = 0;
for (int i = 0; i < counts.length; i++) {
if (counts[i] == max)
modes[j++] = array[i];
}
return modes;
}
This will return an array int[] with the modes. It will contain a lot of 0s, because the result array (modes[]) has to be initialized with the same length of the array passed. Since it is possible that every element appears just one time.
When calling it at the main method:
public static void main(String args[])
{
int[] nums = new int[300];
for (int counter = 0; counter < nums.length; counter++)
nums[counter] = (int) (Math.random() * 300);
int[] modes = computeModes(nums);
for (int i : modes)
if (i != 0) // Discard 0's
System.out.println(i);
}
Your first approach is promising, you can expand it as follows:
for (int i = 0; i < array.length; i++)
{
counts[array[i]]++;
if (maxCounts < counts[array[i]])
{
maxCounts = counts[array[i]];
maxKey = array[i];
}
}
// Now counts holds the number of occurrences of any number x in counts[x]
// We want to find all modes: all x such that counts[x] == maxCounts
// First, we have to determine how many modes there are
int nModes = 0;
for (int i = 0; i < counts.length; i++)
{
// increase nModes if counts[i] == maxCounts
}
// Now we can create an array that has an entry for every mode:
int[] result = new int[nModes];
// And then fill it with all modes, e.g:
int modeCounter = 0;
for (int i = 0; i < counts.length; i++)
{
// if this is a mode, set result[modeCounter] = i and increase modeCounter
}
return result;
THIS USES AN ARRAYLIST but I thought I should answer this question anyways so that maybe you can use my thought process and remove the ArrayList usage yourself. That, and this could help another viewer.
Here's something that I came up with. I don't really have an explanation for it, but I might as well share my progress:
Method to take in an int array, and return that array with no duplicates ints:
public static int[] noDups(int[] myArray)
{
// create an Integer list for adding the unique numbers to
List<Integer> list = new ArrayList<Integer>();
list.add(myArray[0]); // first number in array will always be first
// number in list (loop starts at second number)
for (int i = 1; i < myArray.length; i++)
{
// if number in array after current number in array is different
if (myArray[i] != myArray[i - 1])
list.add(myArray[i]); // add it to the list
}
int[] returnArr = new int[list.size()]; // create the final return array
int count = 0;
for (int x : list) // for every Integer in the list of unique numbers
{
returnArr[count] = list.get(count); // add the list value to the array
count++; // move to the next element in the list and array
}
return returnArr; // return the ordered, unique array
}
Method to find the mode:
public static String findMode(int[] intSet)
{
Arrays.sort(intSet); // needs to be sorted
int[] noDupSet = noDups(intSet);
int[] modePositions = new int[noDupSet.length];
String modes = "modes: no modes."; boolean isMode = false;
int pos = 0;
for (int i = 0; i < intSet.length-1; i++)
{
if (intSet[i] != intSet[i + 1]) {
modePositions[pos]++;
pos++;
}
else {
modePositions[pos]++;
}
}
modePositions[pos]++;
for (int modeNum = 0; modeNum < modePositions.length; modeNum++)
{
if (modePositions[modeNum] > 1 && modePositions[modeNum] != intSet.length)
isMode = true;
}
List<Integer> MODES = new ArrayList<Integer>();
int maxModePos = 0;
if (isMode) {
for (int i = 0; i< modePositions.length;i++)
{
if (modePositions[maxModePos] < modePositions[i]) {
maxModePos = i;
}
}
MODES.add(maxModePos);
for (int i = 0; i < modePositions.length;i++)
{
if (modePositions[i] == modePositions[maxModePos] && i != maxModePos)
MODES.add(i);
}
// THIS LIMITS THERE TO BE ONLY TWO MODES
// TAKE THIS IF STATEMENT OUT IF YOU WANT MORE
if (MODES.size() > 2) {
modes = "modes: no modes.";
}
else {
modes = "mode(s): ";
for (int m : MODES)
{
modes += noDupSet[m] + ", ";
}
}
}
return modes.substring(0,modes.length() - 2);
}
Testing the methods:
public static void main(String args[])
{
int[] set = {4, 4, 5, 4, 3, 3, 3};
int[] set2 = {4, 4, 5, 4, 3, 3};
System.out.println(findMode(set)); // mode(s): 3, 4
System.out.println(findMode(set2)); // mode(s): 4
}
There is a logic error in the last part of constructing the modes array. The original code reads modes[j++] = array[i];. Instead, it should be modes[j++] = i. In other words, we need to add that number to the modes whose occurrence count is equal to the maximum occurrence count
I'm completely new in Java. I am writing an Android game, and I need to generate an array of int arrays that contains all possible sums (excluding combinations that contains number 2 or is bigger than 8 numbers) that add up to a given number.
For example:
ganeratePatterns(5) must return array
[patternNumber][summandNumber] = value
[0][0] = 5
[1][0] = 1
[1][1] = 1
[1][2] = 1
[1][3] = 1
[1][4] = 1
[2][0] = 3
[2][1] = 1
[2][2] = 1
[3][0] = 4
[3][1] = 1
I already try to do this like there Getting all possible sums that add up to a given number
but it's very difficult to me to make it like this http://introcs.cs.princeton.edu/java/23recursion/Partition.java.html
Solution
int n = 10;
int dimension = 0;
//First we need to count number of posible combinations to create a 2dimensionarray
for(List<Integer> sumt : new SumIterator(n)) {
if(!sumt.contains(2) && sumt.size() < 9) {
dimension++;
}
}
int[][] combinationPattern = new int[dimension][];
int foo = 0;
for(List<Integer> sum : new SumIterator(n)) {
if(!sum.contains(2) && sum.size() < 9) {
System.out.println(sum);
combinationPattern[foo] = toIntArray(sum);
foo++;
}
}
It's work not 100% correctly, and very pretty, but it is enough for my game
I have used SumIterator class from here SumIterator.class
I have to changed this code for(int j = n-1; j > n/2; j--) { to this for(int j = n-1; j >= n/2; j--) { because old version doesn't return all combinations (like [5,5] for 10)
And I used toIntArray function. I have founded hare on StackOverflow, but forget a link so here it's source:
public static int[] toIntArray(final Collection<Integer> data){
int[] result;
// null result for null input
if(data == null){
result = null;
// empty array for empty collection
} else if(data.isEmpty()){
result = new int[0];
} else{
final Collection<Integer> effective;
// if data contains null make defensive copy
// and remove null values
if(data.contains(null)){
effective = new ArrayList<Integer>(data);
while(effective.remove(null)){}
// otherwise use original collection
}else{
effective = data;
}
result = new int[effective.size()];
int offset = 0;
// store values
for(final Integer i : effective){
result[offset++] = i.intValue();
}
}
return result;
}
This is not the most beautiful code, but it does what you would like, having modified the code you referenced. It is also quite fast. It could be made faster by staying away from recursion (using a stack), and completely avoiding String-to-integer conversion. I may come back and edit those changes in. Running on my pretty outdated laptop, it printed the partitions of 50 (all 204226 of them) in under 5 seconds.
When partition(N) exits in this code, partitions will hold the partitions of N.
First, it builds an ArrayList of string representations of the sums in space-delimited format (example: " 1 1 1").
It then creates a two-dimensional array of ints which can hold all of the results.
It splits each String in the ArrayList into an array of Strings which each contain only a single number.
For each String, it creates an array of ints by parsing each number into an array.
This int array is then added to the two-dimensional array of ints.
Let me know if you have any questions!
import java.util.ArrayList;
public class Partition
{
static ArrayList<String> list = new ArrayList<String>();
static int[][] partitions;
public static void partition(int n)
{
partition(n, n, "");
partitions = new int[list.size()][0];
for (int i = 0; i < list.size(); i++)
{
String s = list.get(i);
String[] stringAsArray = s.trim().split(" ");
int[] intArray = new int[stringAsArray.length];
for (int j = 0; j < stringAsArray.length; j++)
{
intArray[j] = Integer.parseInt(stringAsArray[j]);
}
partitions[i] = intArray;
}
}
public static void partition(int n, int max, String prefix)
{
if(prefix.trim().split(" ").length > 8 || (prefix + " ").contains(" 2 "))
{
return;
}
if (n == 0)
{
list.add(prefix);
return;
}
for (int i = Math.min(max, n); i >= 1; i--)
{
partition(n - i, i, prefix + " " + i);
}
}
public static void main(String[] args)
{
int N = 50;
partition(N);
/**
* Demonstrates that the above code works as intended.
*/
for (int i = 0; i < partitions.length; i++)
{
int[] currentArray = partitions[i];
for (int j = 0; j < currentArray.length; j++)
{
System.out.print(currentArray[j] + " ");
}
System.out.println();
}
}
}
I currently have this piece of code.
Currently what happens is that two arrays are being taken in, and all possible sequential combinations of the indices of Array A are being stored as a list of seperate arrays, each of which are the same size as array B. Currently to do this sizeA has to be smaller than sizeB.
import java.util.*;
public class Main {
public static void main(final String[] args) throws FileNotFoundException {
ArrayList<String> storeB= new ArrayList();
ArrayList<String> storeA = new ArrayList();
Scanner scannerB = new Scanner(new File("fileB"));
Scanner scannerA = new Scanner(new File("fileA"));
while(scannerB.hasNext()) {
String b = scannerB.next();{
storeB.add(b);
}
}
while(scannerA.hasNext()) {
String A = scannerA.next();{
storeA.add(A);
}
}
final int sizeA = storeA.size();
final int sizeB = storeB.size();
final List<int[]> combinations = getOrderings(sizeA-1, sizeB);
for(final int[] combo : combinations) {
for(final int value : combo) {
System.out.print(value + " ");
}
System.out.println();
}
}
private static List<int[]> getOrderings(final int maxIndex, final int size) {
final List<int[]> result = new ArrayList<int[]>();
if(maxIndex == 0) {
final int[] array = new int[size];
Arrays.fill(array, maxIndex);
result.add(array);
return result;
}
// creating an array for each occurence of maxIndex, and generating each head
//recursively
for(int i = 1; i < size - maxIndex + 1; ++i) {
//Generating every possible head for the array
final List<int[]> heads = getOrderings(maxIndex - 1, size - i);
//Combining every head with the tail
for(final int[] head : heads) {
final int[] array = new int[size];
System.arraycopy(head, 0, array, 0, head.length);
//Filling the tail of the array with i maxIndex values
for(int j = 1; j <= i; ++j)
array[size - j] = maxIndex;
result.add(array);
}
}
return result;
}
}
I'm wondering, regardless of sizeA and sizeB, how do I modify this to create arrays which are double sizeB and duplicate each index value. So if we had:
[0,1,1,2]
this would become:
[0,0,1,1,1,1,2,2]
i.e duplicating each value and placing it next to it.
Also, how would I eliminate recursion in this so that rather than producing all possible combinations, on each call, a single array at random is produced rather than a list of arrays.
Thank you.
So if we had: [0,1,1,2] this would become: [0,0,1,1,1,1,2,2] i.e duplicating each value and placing it next to it.
public int[] getArray(int originSize) {
// Create a array double the size of originSize
int[] result = new int[originSize * 2];
// Iterate through 0 to originSize - 1 (This are your indicies)
for (int i = 0, j = 0; i < originSize; ++i, j+=2)
{
// i is the index to insert into the new array.
// j holds the current position in the new array.
// On the first iteration i = 0 is written onto the
// position 0 and 1 in the new array
// after that j is incremented by 2
// to step over the written values.
result[j] = i;
result[j+1] = i;
}
return result;
}
int[] sizeB_double = new int[sizeB.length()*2];
for(int i = 0; i<sizeB_double; i+=2)
{
sizeB_double[i] = sizeB[i/2];
if(sizeB_double.length > (i+1))
sizeB_double[i+1] = sizeB[i/2];
}