Java - Adding Rows is there a more efficient way? - java

Below is the code, I am just wondering if others are coding it differently. Maybe I can make small changes. Thanks in advance!
public class addRow {
public static int[][] insert(int [][] a, int [] row, int index){
int [][] x = new int[a.length+1][a.length];
int [] temp;
for(int i=0; i<x.length-1; i++)
{
x[i] = a[i];
if(i == index)
{
temp = a[i];
x[i] = row;
x[i+1] = temp;
}
}
return x;
}
public static void main(String[] args){
int[][] a = {{1,2,3},{4,5,6},{10,11,12}};
int[] row = {7,8,9};
int [][] b = insert(a,row ,2);
for(int r=0; r < b.length; r++){
for(int c=0;c< b[r].length; c++){
System.out.print(b[r][c] + " ");
}System.out.println();
}
}
}

System.arraycopy is your answer.
http://docs.oracle.com/javase/6/docs/api/java/lang/System.html#arraycopy%28java.lang.Object,%20int,%20java.lang.Object,%20int,%20int%29
It uses native code to copy arrays in memory directly, making it much more efficient.

Your loop doesn't do what you think it does. When you swap rows i and i+1 in x, the next iteration of the loop will overwrite the element you put in x[i+1] on the previous iteration. You need to keep an extra index (or split your loop) to keep track of the difference in positions between a and x after hitting index. A better approach, though, is to use System.arraycopy.
Also, there's no reason to allocate space for the rows of x in its initializer, since you are assigning elements of a (or row) to them anyway. My version of your method is:
public static int[][] insert(int [][] a, int [] row, int index){
int[][] x = new int[a.length + 1][]; // no second dimension
System.arraycopy(a, 0, x, 0, index);
x[index] = row;
System.arraycopy(a, index, x, index + 1, a.length - index);
return x;
}

Just because your code seems to be working for 1 case, it doesn't mean it proper. You'd have tried out the other cases as well.
You need to make the following changes in your method for it to work properly.
public static int[][] insert(int [][] a, int [] row, int index){
int [][] x = new int[a.length+1][a.length];
int j = 0; // New counter for array `a`
// Also `temp` array removed. Not required at all.
for (int i = 0; i < x.length; i++) {
x[i] = a[j];
if (i == index) {
x[i] = row;
x[i + 1] = a[j];
} else {
j++;
}
}
return x;
}
This is the maximum you can optimize your code as such, without changing the base of your code.
Now regarding optimizing it big time, as others suggested, you could use the System#arrayCopy.

Related

create a reverse method where elements are reversed in array

Here list is the name of the array. I have a swap method so trying to use it to make a reverse method of an array string. so if the elements in an array are 1,2,3,4 they should become 4,3,2,1. I don;t understand where the flaw is in my logic as with my current code only the first and last elements are getting swapped.
private void swap(int i, int j)
{
int temp;
temp = list[i];
list[i] = list[j];
list[j] = temp;
}
public void reverse()
{
int y=1;
for(int x =0; x<list.length-1; x++)
{
swap(x,list.length-y);
++y;
}
}
int y=1;
// add and/or modify code to complete the method
for(int x =0; x<list.length-1; x++) //wrong, should only loop to len/2
{
swap(x,list.length-y);
++y;
}
the right code should be:
int mid = (list.length - 1) / 2;
int len = list.length;
for (int i = 0; i <= mid; i++) {
swap(i, len - 1 - i);
}

How to place a condition in a different method that compares elements that will decide to do a task or not?

I have an array that consists of numbers that are in an order that is not decided by me. For example: 1,2,3,4,5,6,7,8,9,10
I have written this code in different methods, and I want to add code that would now take pos1 and pos2 and compare them, and only switch position if the statement that pos2 is less than pos1. comparing it through from pos1 to pos2; pos2 to pos3; pos3 to pos4; etc.
Code:
static void nameSwitch( int[] array, int pos1, int pos2 ) {
int temp = array[pos1];
array[pos1] = array[pos2];
array[pos2] = temp;
}
static void firstNameToLast() {
int [] values = {1,2,3,4,5,6,7,8,9,10};
int i;
for(i = 0; i < values.length; i+=2) {
swap(values, i, i+1);
}
System.out.println( + Arrays.toString(values));
}
static void goingThrough( int[] nums) {
//comparing pos1 and pos2, etc area of confusion
System.out.println( + Arrays.toString( nums ) );
}
after going through the last loop, I want the output to be, 1,2,3,4,5,6,7,8,,9,10 to stay the same, but if i had numbers such as, 2,4,1,6,8,1,3. i want pos1 to be compared to pos2, and if pos2 is less than pos1, then switch there position.
This is not too difficult. Start by writing a loop that circles the array, checks the current object and the one next to it, and swaps them if the first position is larger, like this:
for(int i = 0; i < myArray.length - 1; i++){
if(myArray[i] > myArray[i + 1]{
myArray = swapElements(myArray, i, i + 1);
}
}
And then your swap elements might look like this:
private int[] swapElements(int[] arr, int first, int second){
int temp = arr[first];
arr[first] = arr[second];
arr[second] = temp;
return arr;
}
Now, if you want to sort the entire array, there are easier ways to do it. If you are simply doing just this, swapping elements, I would try the above.
EDIT
I think the reason your code will not work is because while you call the swap method, it does not change the value of the array itself, it only changes it within the method. Notice how in my solution, I set the array equal to what is returned from the method. Am I correct in assuming that the output you were actually receiving was the original array itself?
To sort your arrays, you the following code in your swap method
for (int i = 0; i<array.length; i++) {
for (int j = 0; j < array.length; j++){
if (array[i] < array[j]) {
int temp = array[i];
array[i] = array[j];
array[j] = temp;
}
}
}
Hope it helps

How do I shift array elements up one position in java?

I am working on a java assignment where I need to delete an integer element in an array and shift the below elements up on space to keep them in order. The array is currently random integers in descending order. I am not allowed to use array.copy because I will need to collect array usage information as part of the assignment. I have tried a ton of different ways of doing this but cannot seem to get it working.
public static void deletionArray(int anArray[], int positionToDelete) {
for (int j = anArray[positionToDelete] - 1; j < anArray.length; j++) {
System.out.println("j is " + j);
anArray[j] = anArray[j + 1];
}
displayArray(anArray);
}
You're iterating until anArray.length (exclusive), but inside the loop, you're accessing anArray[j + 1], which will thus be equal to anArray[anArray.length] at the last iteration, which will cause an ArrayIndexOutOfBoundsException.
Iterate until anArray.length - 1 (exclusive), and decide what should be stored in the last element of the array instead of its previous value.
You're also starting at anArray[positionToDelete] - 1, instead of starting at positionToDelete.
You have two bugs there.
Since this is an assignment, I won't give a complete answer - just a hint. Your loop definition is wrong. Think about this: what happens on the first and on the last iteration of the loop? Imagine a 5-element array (numbered 0 to 4, as per Java rules), and work out the values of variables over iterations of the loop when you're erasing element number, say, 2.
Use System.arraycopy faster than a loop:
public static void deletionArray( int anArray[], int positionToDelete) {
System.arraycopy(anArray, positionToDelete + 1, anArray,
positionToDelete, anArray.length - positionToDelete - 1);
//anArray[length-1]=0; //you may clear the last element
}
public static int[] deletionArray(int anArray[], int positionToDelete) {
if (anArray.length == 0) {
throw new IlligalArgumentException("Error");
}
int[] ret = new int[anArray.length - 1];
int j = 0;
for (int i = 0; i < anArray.length; ++i) {
if (i != positionToDelete) {
ret[j] = anArray[i];
++j;
}
}
return ret;
}
Why do we reserve a new array?
Because if don't, we would use C\C++-style array: an array and a "used length" of it.
public static int deletionArray(int anArray[], int positionToDelete, int n) {
if (n == 0) {
throw new IlligalArgumentException("Error");
}
for (int i = positionToDelete; i < n - 1; ++i) {
anArray[i] = anArray[i + 1];
}
return n - 1; // the new length
}
How's this ? Please note the comment, I don't think you can delete an element in an array, just replace it with something else, this may be useful : Removing an element from an Array (Java)
Updated with 'JB Nizet' comment :
public class Driver {
public static void main (String args []){
int intArray[] = { 1,3,5,6,7,8};
int updatedArray[] = deletionArray(intArray , 3);
for (int j = 0; j < updatedArray.length; j++) {
System.out.println(updatedArray[j]);
}
}
public static int[] deletionArray(int anArray[], int positionToDelete) {
boolean isTrue = false;
for (int j = positionToDelete; j < anArray.length - 1; j++) {
if(j == positionToDelete || isTrue){
isTrue = true;
anArray[j] = anArray[j + 1];
}
}
anArray[anArray.length-1] = 0; //decide what value this should be or create a new array with just the array elements of length -> anArray.length-2
return anArray;
}
}

2-D Array (row and column)

The program below (thanks to Sundial) computes the area of a rectangle
public class ComputeTheArea {
public static int areaOfTheRectangle (char[][] table, char ch) {
int[] first = new int[2];
int[] last = new int[2];
for (int i=0; i<3; i++) {
for (int j=0; j<4; j++) {
if(grid[i][j]==ch) {
first[0] = i;
first[1] = j;
}
}
}
for (int i=2; i>=0; i--) {
for (int j=3; j>=0; j--) {
if(grid[i][j]==ch) {
last[0] = i;
last[1] = j;
}
}
}
int answer = ((Math.max(first[0]+1,last[0]+1) - Math.min(first[0]+1,last[0]+1)) *
(Math.max(first[1]+1,last[1]+1) - Math.min(first[1]+1,last[1]+1)));
return answer;
}
However, when it is run, it outputs the wrong answer. I know there is something wrong with the for loop. I'm new in Java and I need your help for me to fix the method. Please and thank you very much!
EDIT: I edited the code to conform to Michael's answer.
First of all, you don't search all the elements in the matrix with your first loop.
Secondly, you don't break when you found a match.
Also, this approach is a bit flawed. For example, see this matrix:
a b c b
a _ c d
x z b a
Here you wouldn't know which b to stop at at the first row to get the entire b square.
If you instead just loop through the entire matrix once and saves the maximum and minimum (first and last) x and y coordinates, the area can be calculated very easily. See this code:
public static int charArea (char[][] grid, char ch) {
int[] first = new int[] {100, 100};
int[] last = new int[] {-1, -1};
for (int i=0; i<3; i++) {
for (int j=0; j<4; j++) {
if(grid[i][j]==ch) {
first[0] = Math.min(i, first[0]);
first[1] = Math.min(j, first[1]);
last[0] = Math.max(i, last[0]);
last[1] = Math.max(j, last[1]);
}
}
}
int answer = (last[0] - first[0] + 1) * (last[1] - first[1] + 1);
return answer;
}
The for loops should probably break once they find the character.
The first for loop sets j=i. That should probably be j=0 instead.
I don't think the length calculation is correct. A 1 should be added to both terms. I.e. the length of something with first=0 and last=3 should be last+1-first=4, not 3 as it would be now.

Creating a New Reverse Java Array

CodingBat > Java > Array-1 > reverse3:
Given an array of ints length 3, return a new array with the elements in reverse order, so {1, 2, 3} becomes {3, 2, 1}.
public int[] reverse3(int[] nums) {
int[] values = new int[3];
for (int i = 0; i <= nums.length - 1; i++) {
for (int j = nums.length-1; j >= 0; j--) {
values[i] = nums[j];
}
}
return values;
}
I can't get this to work properly, usually the last int in the array, becomes every single int in the new array
You don't want a two-level loop. Just have one loop:
for(int i = 0, j = nums.length - 1; i < nums.length; i++,j--) {
values[i] = nums[j];
}
or, alternately, just don't track j sepearately, and do this:
for(int i = 0; i < nums.length; i++) {
values[i] = nums[nums.length - 1 - i];
}
Unless this is a homework, why not just use Apache ArrayUtils'
ArrayUtils.reverse(nums)
Never re-invent the wheel :)
The length of the input int[] is fixed at 3? Then it doesn't get any simpler than this.
public int[] reverse3(int[] nums) {
return new int[] { nums[2], nums[1], nums[0] };
}
See also:
CodingBat/Java/Array-1/reverse3
Note that Array-1 is "Basic array problems -- no loops." You can use a loop if you want, but it's designed NOT to be solved using loops.
Firstly, while creating new array give it size of old array.
Next, when you're reversing an array, you don't need two loops, just one:
int length = oldArray.length
for(int i = 0; i < length; i++)
{
newArray[length-i-1] = oldArray[i]
}
You only want a single loop, but with indices going both ways:
public int[] reverse(int[] nums) {
int[] back = new int[nums.length];
int i,j;
for (i=0,j=nums.length-1 ; i<nums.length ; i++,j--)
back[i] = nums[j];
return back;
}
public int[] reverse3(int[] nums) {
int rotate[]={nums[2],nums[1],nums[0]};
return rotate;
}
This code gives correct output:-
public int[] reverse3(int[] nums) {
int[] myArray=new int[3];
myArray[0]=nums[2];
myArray[1]=nums[1];
myArray[2]=nums[0];
return myArray;
}
I got this with Python.. So you can get the idea behind it
def reverse3(nums):
num = []
for i in range(len(nums)):
num.append(nums[len(nums) - i - 1])
return num
In your code, for each value of i, you are setting target array elements at i to value in "nums" at j. That is how you end up with same value for all the elements at the end of all iterations.
First of all, very bad logic to have two loops for a simple swap algorithm such as :
public static void reverse(int[] b) {
int left = 0; // index of leftmost element
int right = b.length-1; // index of rightmost element
while (left < right) {
// exchange the left and right elements
int temp = b[left];
b[left] = b[right];
b[right] = temp;
// move the bounds toward the center
left++;
right--;
}
}//endmethod reverse
or simplified:
for (int left=0, int right=b.length-1; left<right; left++, right--) {
// exchange the first and last
int temp = b[left]; b[left] = b[right]; b[right] = temp;
}
Why go through all this pain, why dont you trust Java's built-in APIs and do something like
public static Object[] reverse(Object[] array)
{
List<Object> list = Arrays.asList(array);
Collections.reverse(list);
return list.toArray();
}
public int[] reverse3(int[] nums) {
int[] values = new int[nums.length];
for(int i=0; i<nums.length; i++) {
values[nums.length - (i + 1)]=nums[i];
}
return values;
}

Categories

Resources