I was wondering if this is the most efficient or even good code practice to add arrays to a single array as far as my knowllage goes its time would be O(n). This is only for practice and I want to do it for int [] not for the code to be changed so it is a List.
static int[] allArrayDirections(int row[], int col [], int diag []) {
int counter = 0;
int allDirectionsInMatrix [] = new int [row.length + col.length + diag.length];
for(int i = 0; i < row.length; i++) {
allDirectionsInMatrix[counter++] = row[i];
}
for(int j = 0; j < col.length; j++) {
allDirectionsInMatrix[counter++] = col[j];
}
for(int i = 0; i < diag.length; i++) {
allDirectionsInMatrix[counter++] = diag[i];
}
return allDirectionsInMatrix;
}
You could compare your linear solution to a sort of unravelled:
Find the longest of the three arrays, take its length as counter boundary
assign the longest array to a new variable first, the other two to second and third – just fiddling with the references so the for looks straightforward
loop once from 0 to the counter boundary
fill your target array in three steps, using the other array's length as offset – unless the smaller arrays are already exhausted, so skip them
This will need some add operation for the offset calculation to write to allDirectionsInMatrix and two greater then checks. Depending on the VM's optimization/ array lengths/ call frequency this might cut it in half.
The single for-loop looks similar to this:
// assuming first.length >= second.length >= third.length;
for(int i=0;i<largestLength;i++) {
allDirectionsInMatrix[i]=first[i];
if (second.length > i)
allDirectionsInMatrix[i+first.length]=second[i];
// I assume when called often enough VM does auto trickery
// with the repeated addition of i and first.length
if (third.length > i)
allDirectionsInMatrix[i+first.length+second.length]=third[i];
}
But this might also break other VM optimizations when treating the arrays independently. So really compare runtime. I'd appreciate to read about your measurements.
Just FYI (and not a reals answer to your question, but maybe interesting for comparison)
One way to concatenate integer arrays (using Streams) would be
int[] a = {1,2,3};
int[] b = {4,5,6,7};
int[] c = IntStream.concat(Arrays.stream(a), Arrays.stream(b)).toArray();
System.out.println(Arrays.toString(c));
(Stream.concat for arrays of other types)
So I've got this method:
public static int[] select(int maxWidth, int maxHeight) {
int rHeight = StdRandom.uniform(0, maxHeight);
int rWidth = StdRandom.uniform(0, maxWidth);
return new int[] {rHeight, rWidth};
}
And I'm not advanced enough to work with it on the right way.
I've got a second method where I want to execute 'select' several times. My idea was to do it with a for-loop like that (in which 'n' is a int):
for(int i = 0; i < n; i++){
select(h, w);
}
But now I don't know how to save the result from this for-loop in an 1d-array, since I will always get an error when trying to save like that:
int[] a = new int[select(h, w)];
I'm very aware that this looks very strange and wrong but I just don't know how to do it in the right way and I don't know for what I have to search on google.
Here is a way you could do it:
int[][] a = new int[n][];
for(int i = 0; i < n; i++){
a[i] = select(h, w);
}
Basically this code creates a 2d array, then in the for loop, adds the result of select to each element of the array.
I don't think you can do this in a 1D array, if you want to run select multiple times, and each time it returns an array, you'll have to have an array of arrays. If you are adamant about having a 1D array to store the answers, you'll have to implement a tuple class, although I think you're better off just doing a 2D array the way Sub 6 Resources showed.
int[] combined = new int[n*2];
for(int i = 0; i < n; i++){
int a[] = select(h, w);
System.arraycopy(a, 0, combined, i*2, 2);
}
I have to generate prime number. For this reason I have to initialize all array elements to -1. From c/c++, I came to know I have to initialize them by using a for loop. Please see the code below
public static void main(String[] args){
final int SIZE = 1000;
int[] intArray = new int[SIZE];
Arrays.fill(intArray, -1);
for(int i=0; i<SIZE; i++){
intArray[i] = -1;
}
for(int i = 0; i<SIZE; i++){
System.out.println(intArray[i]);
}
}
In java is there any better way to do this?
Well, Arrays.fill(intArray, -1); already fills your array, so there's no need for the redundant for loop following that statement.
You can also just remove your final int SIZE, and say int[] intArray = new int[1000];. When you need to get the length/size of the array, you can just say intArray.length.
You can only use Arrays.fill(int[] a, int val) method like this -
Arrays.fill(intArray, -1);
The Arrays.fill() populates the array - intArray with the specified value val. So you don't need to initialize the intArray using the for loop.
And one more thing, in c++ it is also possible to initialize array with some value like this, without using the for loop. See here
I have a char [], and I want to set the value of every index to the same char value.
There is the obvious way to do it (iteration):
char f = '+';
char [] c = new char [50];
for(int i = 0; i < c.length; i++){
c[i] = f;
}
But I was wondering if there's a way that I can utilize System.arraycopy or something equivalent that would bypass the need to iterate. Is there a way to do that?
EDIT :
From Arrays.java
public static void fill(char[] a, int fromIndex, int toIndex, char val) {
rangeCheck(a.length, fromIndex, toIndex);
for (int i = fromIndex; i < toIndex; i++)
a[i] = val;
}
This is exactly the same process, which shows that there might not be a better way to do this.
+1 to everyone who suggested fill anyway - you're all correct and thank you.
Try Arrays.fill(c, f) : Arrays javadoc
As another option and for posterity I was looking into this recently and found a solution that allows a much shorter loop by handing some of the work off to the System class, which (if the JVM you're using is smart enough) can be turned into a memset operation:-
/*
* initialize a smaller piece of the array and use the System.arraycopy
* call to fill in the rest of the array in an expanding binary fashion
*/
public static void bytefill(byte[] array, byte value) {
int len = array.length;
if (len > 0){
array[0] = value;
}
//Value of i will be [1, 2, 4, 8, 16, 32, ..., len]
for (int i = 1; i < len; i += i) {
System.arraycopy(array, 0, array, i, ((len - i) < i) ? (len - i) : i);
}
}
This solution was taken from the IBM research paper "Java server performance: A case study of building efficient, scalable Jvms" by R. Dimpsey, R. Arora, K. Kuiper.
Simplified explanation
As the comment suggests, this sets index 0 of the destination array to your value then uses the System class to copy one object i.e. the object at index 0 to index 1 then those two objects (index 0 and 1) into 2 and 3, then those four objects (0,1,2 and 3) into 4,5,6 and 7 and so on...
Efficiency (at the point of writing)
In a quick run through, grabbing the System.nanoTime() before and after and calculating a duration I came up with:-
This method : 332,617 - 390,262 ('highest - lowest' from 10 tests)
Float[] n = new Float[array.length]; //Fill with null : 666,650
Setting via loop : 3,743,488 - 9,767,744 ('highest - lowest' from 10 tests)
Arrays.fill : 12,539,336
The JVM and JIT compilation
It should be noted that as the JVM and JIT evolves, this approach may well become obsolete as library and runtime optimisations could reach or even exceed these numbers simply using fill().
At the time of writing, this was the fastest option I had found. It has been mentioned this might not be the case now but I have not checked. This is the beauty and the curse of Java.
Use Arrays.fill
char f = '+';
char [] c = new char [50];
Arrays.fill(c, f)
Java Programmer's FAQ Part B Sect 6 suggests:
public static void bytefill(byte[] array, byte value) {
int len = array.length;
if (len > 0)
array[0] = value;
for (int i = 1; i < len; i += i)
System.arraycopy( array, 0, array, i,
((len - i) < i) ? (len - i) : i);
}
This essentially makes log2(array.length) calls to System.arraycopy which hopefully utilizes an optimized memcpy implementation.
However, is this technique still required on modern Java JITs such as the Oracle/Android JIT?
System.arraycopy is my answer. Please let me know is there any better ways. Thx
private static long[] r1 = new long[64];
private static long[][] r2 = new long[64][64];
/**Proved:
* {#link Arrays#fill(long[], long[])} makes r2 has 64 references to r1 - not the answer;
* {#link Arrays#fill(long[], long)} sometimes slower than deep 2 looping.<br/>
*/
private static void testFillPerformance() {
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
System.out.println(sdf.format(new Date()));
Arrays.fill(r1, 0l);
long stamp0 = System.nanoTime();
// Arrays.fill(r2, 0l); -- exception
long stamp1 = System.nanoTime();
// System.out.println(String.format("Arrays.fill takes %s nano-seconds.", stamp1 - stamp0));
stamp0 = System.nanoTime();
for (int i = 0; i < 64; i++) {
for (int j = 0; j < 64; j++)
r2[i][j] = 0l;
}
stamp1 = System.nanoTime();
System.out.println(String.format("Arrays' 2-looping takes %s nano-seconds.", stamp1 - stamp0));
stamp0 = System.nanoTime();
for (int i = 0; i < 64; i++) {
System.arraycopy(r1, 0, r2[i], 0, 64);
}
stamp1 = System.nanoTime();
System.out.println(String.format("System.arraycopy looping takes %s nano-seconds.", stamp1 - stamp0));
stamp0 = System.nanoTime();
Arrays.fill(r2, r1);
stamp1 = System.nanoTime();
System.out.println(String.format("One round Arrays.fill takes %s nano-seconds.", stamp1 - stamp0));
stamp0 = System.nanoTime();
for (int i = 0; i < 64; i++)
Arrays.fill(r2[i], 0l);
stamp1 = System.nanoTime();
System.out.println(String.format("Two rounds Arrays.fill takes %s nano-seconds.", stamp1 - stamp0));
}
12:33:18
Arrays' 2-looping takes 133536 nano-seconds.
System.arraycopy looping takes 22070 nano-seconds.
One round Arrays.fill takes 9777 nano-seconds.
Two rounds Arrays.fill takes 93028 nano-seconds.
12:33:38
Arrays' 2-looping takes 133816 nano-seconds.
System.arraycopy looping takes 22070 nano-seconds.
One round Arrays.fill takes 17042 nano-seconds.
Two rounds Arrays.fill takes 95263 nano-seconds.
12:33:51
Arrays' 2-looping takes 199187 nano-seconds.
System.arraycopy looping takes 44140 nano-seconds.
One round Arrays.fill takes 19555 nano-seconds.
Two rounds Arrays.fill takes 449219 nano-seconds.
12:34:16
Arrays' 2-looping takes 199467 nano-seconds.
System.arraycopy looping takes 42464 nano-seconds.
One round Arrays.fill takes 17600 nano-seconds.
Two rounds Arrays.fill takes 170971 nano-seconds.
12:34:26
Arrays' 2-looping takes 198907 nano-seconds.
System.arraycopy looping takes 24584 nano-seconds.
One round Arrays.fill takes 10616 nano-seconds.
Two rounds Arrays.fill takes 94426 nano-seconds.
As of Java-8, there are four variants of the setAll method which sets all elements of the specified array, using a provided generator function to compute each element.
Of those four overloads only three of them accept an array of primitives declared as such:
setAll(double[] array, IntToDoubleFunction generator)
setAll(int[] array, IntUnaryOperator generator)
setAll(long[] array, IntToLongFunction generator)
Examples of how to use the aforementioned methods:
// given an index, set the element at the specified index with the provided value
double [] doubles = new double[50];
Arrays.setAll(doubles, index -> 30D);
// given an index, set the element at the specified index with the provided value
int [] ints = new int[50];
Arrays.setAll(ints, index -> 60);
// given an index, set the element at the specified index with the provided value
long [] longs = new long[50];
Arrays.setAll(longs, index -> 90L);
The function provided to the setAll method receives the element index and returns a value for that index.
you may be wondering how about characters array?
This is where the fourth overload of the setAll method comes into play. As there is no overload that consumes an array of character primitives, the only option we have is to change the declaration of our character array to a type Character[].
If changing the type of the array to Character is not appropriate then you can fall back to the Arrays.fill method.
Example of using the setAll method with Character[]:
// given an index, set the element at the specified index with the provided value
Character[] character = new Character[50];
Arrays.setAll(characters, index -> '+');
Although, it's simpler to use the Arrays.fill method rather than the setAll method to set a specific value.
The setAll method has the advantage that you can either set all the elements of the array to have the same value or generate an array of even numbers, odd numbers or any other formula:
e.g.
int[] evenNumbers = new int[10];
Arrays.setAll(evenNumbers, i -> i * 2);
There's also several overloads of the parallelSetAll method which is executed in parallel, although it's important to note that the function passed to the parallelSetAll method must be side-effect free.
Conclusion
If your goal is simply to set a specific value for each element of the array then using the Arrays.fill overloads would be the most appropriate option. However, if you want to be more flexible or generate elements on demand then using the Arrays.setAll or Arrays.parallelSetAll (when appropriate) would be the option to go for.
I have a minor improvement on Ross Drew's answer.
For a small array, a simple loop is faster than the System.arraycopy approach, because of the overhead associated with setting up System.arraycopy. Therefore, it's better to fill the first few bytes of the array using a simple loop, and only move to System.arraycopy when the filled array has a certain size.
The optimal size of the initial loop will be JVM specific and system specific of course.
private static final int SMALL = 16;
public static void arrayFill(byte[] array, byte value) {
int len = array.length;
int lenB = len < SMALL ? len : SMALL;
for (int i = 0; i < lenB; i++) {
array[i] = value;
}
for (int i = SMALL; i < len; i += i) {
System.arraycopy(array, 0, array, i, len < i + i ? len - i : i);
}
}
If you have another array of char, char[] b and you want to replace c with b, you can use c=b.clone();.
See Arrays.fill method:
char f = '+';
char [] c = new char [50];
Arrays.fill(c, f);
Arrays.fill might suit your needs
Arrays.fill(myArray, 'c');
Arrays.fill
Although it is quite possible that this is doing the loop in the background and is therefore not any more efficient than what you have (other than the lines of code savings). If you really care about efficiency, try the following in comparison to the above:
int size = 50;
char[] array = new char[size];
for (int i=0; i<size; i++){
array[i] = 'c';
}
Notice that the above doesn't call array.size() for each iteration.
/**
* Assigns the specified char value to each element of the specified array
* of chars.
*
* #param a the array to be filled
* #param val the value to be stored in all elements of the array
*/
public static void fill(char[] a, char val) {
for (int i = 0, len = a.length; i < len; i++)
a[i] = val;
}
That's the way Arrays.fill does it.
(I suppose you could drop into JNI and use memset.)
You could use arraycopy but it depends on whether you can predefine the source array, - do you need a different character fill each time, or are you filling arrays repeatedly with the same char?
Clearly the length of the fill matters - either you need a source that is bigger than all possible destinations, or you need a loop to repeatedly arraycopy a chunk of data until the destination is full.
char f = '+';
char[] c = new char[50];
for (int i = 0; i < c.length; i++)
{
c[i] = f;
}
char[] d = new char[50];
System.arraycopy(c, 0, d, 0, d.length);
Arrays.fill is the best option for general purpose use.
If you need to fill large arrays though as of latest idk 1.8 u102, there is a faster way that leverages System.arraycopy.
You can take a look at this alternate Arrays.fill implementation:
According to the JMH benchmarks you can get almost 2x performance boost for large arrays (1000 +)
In any case, these implementations should be used only where needed. JDKs Arrays.fill should be the preferred choice.
If I have the following Java code:
int[][] readAPuzzle()
{
Scanner input = new Scanner(System.in);
int[][] grid = new int[9][9];
for (int i=0; i<9; i++)
for (int j=0; j<9; j++)
grid[i][j] = input.nextInt();
return grid;
}
public static void main(String[] args) {
// Read a Sudoku puzzle
int[][] grid = readAPuzzle();
}
How can I convert this to C++? I get hung up on passing the array. Here is my attempt:
#include <iostream>
using namespace std;
const int puzzle_width = 9;
const int puzzle_height = 9;
void readAPuzzle(int (&grid)[puzzle_height][puzzle_width])
{
for(int i = 0; i < 9; i++)
for(int j = 0; j < 9; j++)
grid[i][j] = cin >> grid[i][j];
return;
}
int main()
{
int[9][9] grid;
readAPuzzle(grid);
}
What am I doing wrong in general?
You need to read in the input text into your array grid and pass it on.
grid[i][j] = cin >> grid[i][j];
Doesn't do what you think it does, it tries to assign an object of type istream to grid[ i ][ j ]
cin >> grid[i][j];
however suffices.
Also, note in C++ the dimensions follow the identifier as in:
int grid[9][9];
Try
#include <iostream>
using namespace std;
const int puzzle_width = 9;
const int puzzle_height = 9;
void readAPuzzle(int grid[puzzle_height][puzzle_width])
{
for(int i = 0; i < 9; i++)
for(int j = 0; j < 9; j++)
cin >> grid[i][j];
}
int main()
{
int grid[9][9];
readAPuzzle(grid);
}
In general, arrays are automatically passed by reference, and array sizes go after the name of the array not after their type.
And if you declared constants, you should always use puzzle_width and puzzle_height (perhaps shorten their names though) and not magic numbers like 9.
The simple answer is to use vectors instead of arrays. C++'s rules for passing arrays as function parameters are esoteric and derived from C. Here are some of the issues:
You can't use arrays for long without understanding and using pointers
Array subscripting is pointer subscripting. Arrays are accessed using pointer arithmetic. Arrays as function parameters are actually pointers in disguise.
Functions don't get information about array size when taking an array argument
Consider the declaration:
void inc_all(int myarray[]); /* increments each member of the array */
Unfortunately, that array parameter is not an array parameter! It's actually a pointer parameter:
void inc_all(int *myarray); /* Exactly the same thing! */
And a pointer doesn't know how many items are in the sequence it points at. As a result this function cannot have the information necessary to know when the array stops. You either need to pass the length:
void inc_all(int *myarray, size_t len); /* size_t rather than int */
or you need to use a sentinel value to mark the end of the array. Either way, an array is not a self-contained encapsulated datatype like a vector is.
You can't pass an arbitrarily-sized two-dimensional array to a function
If you try to create a function which takes a two-dimensional array:
void inc_all(int myarray[][]); /* XXX won't compile! */
it won't compile. The problem is you have an indeterminate length array of indeterminate length arrays of ints. The outer array doesn't know how large its members (the inner arrays) are and therefore doesn't know how to step through them in memory. You need to specify the size of the inner arrays:
void inc_all(int myarray[][10]);
at which point your code is probably not as general as you were hoping it was going to be.
If you use vectors and vectors of vectorss, these problems don't arise because the vectors themselves know how many members they have and carry that information with them.
If you still want to learn more about arrays and pointers I recommend section 6 of the comp.lang.c FAQ.
I think your should to use your constants first of all. You can pass as value pointer as well as ref on pointer (both 4bytes), also it is a pointer on memory (it is valueble).
#include <iostream>
using namespace std;
const int puzzle_width = 9;
const int puzzle_height = 9;
void readAPuzzle(int grid[puzzle_height][puzzle_width])
{
for(int i = 0; i < puzzle_height; i++)
for(int j = 0; j < puzzle_width; j++)
cin >> grid[i][j];
}
int main()
{
int grid[puzzle_height][puzzle_width];//I think your need to do this
readAPuzzle(grid);
}