hello i'm new in Java and i'm having a trouble.
My program prints Strings in a Jframe. I generate a array of Strings called v. v[0] is always null. And I request an input from the user to delete one position of the array v, wich i call numberdel. If I have an array
v[0]=[null] v[1]=[hello] v[2]=[my name is] v[3]=[john] and if
numberdel=2
the final result should be
v[0]=[null] v[1]=[hello] v[2]=[john]
I wasn't making it so I created a new array called b. But it still isn't working like a wanted...
public static
(...)
String[] b = new String[v.length-1];
boolean jump = false;
for(int j=1; j<b.length; j++){
if(jump==false){
if(j != numberdel){
b[j] = v[j];
}
else jump = true;
}
else{
b[j] = v[j+1];
}
(...)//action for every cycle
}
(...)
When j == numberdel, your loop will set jump to true and skip right past the else statement.
I'd recommend not using the jump variable since it will basically be false when j < numberdel and true otherwise.
for(int j = 1; j < b.length; j++)
{
if (j < numberdel)
b[j] = v[j];
else
b[j] = v[j + 1];
}
you can do your task in the single array itself...as below...
void delet(int numberdel)
{
for(int i=numberdel ; i< v.length ;i++)
v[i] = v[i+1];
}
i suggest that if you can do the same thing in one array then why to waste space...you are doing the thing its fine,but i guess this is better...hope it works for you...
Use System.arrayCopy starting with array v. numberdel is the 0-based item to delete.
String[] b = new String[v.length-1];
System.arrayCopy(v, 0, b, 0, numberdel);
System.arrayCopy(v, numberdel + 1, b, numberdel, v.length - numberdel);
Related
I trying to find all 2s, move them to the back of the array, and turn them into 0s without loosing the order of the array. For example, [1,2,3,2,2,4,5] would become [1,3,4,5,0,0,0]. My code works fine but the IDE is telling me that the nested for loop is copying the array manually and wants me to replace it with System.arraycopy(). How would I go about that?
Code looks like this:
int[] numbers = {1,2,3,2,2,4,5};
for (int i = 0; i < numbers.length; i++){
if (numbers[i] == 2){
for (int j = i; j < numbers.length - 1; j++){
numbers[j] = numbers[j + 1];
}
numbers[numbers.length-1] = 0;
i --;
}
}
The following statement:
for (int j = i; j < numbers.length - 1; j++){
numbers[j] = numbers[j + 1];
}
Can be replaced by:
System.arraycopy(numbers, i + 1, numbers, i, numbers.length - 1 - i);
IDEs like IntelliJ should suggest that automatically when you press alt + enter (default key combination).
Now about arraycopy()
From the documentation, java.lang.System.arraycopy() will copy n elements (last argument) from the source array (1st argument) to the destination array (3rd argument) with the corresponding indexes to start from (2nd and 4th arguments).
More specifically, when calling arraycopy(numbers, i + 1, numbers, i, numbers.length - 1 - i) the arguments are:
numbers: The source array.
i + 1: The starting position in the source array.
numbers: The destination array.
i: The starting position in the destination data.
numbers.length - 1 - i: The number of array elements to be copied.
In your case, elements will be copied from your array, to itself, but the fact that source starting position is shifted from the destination starting position will induce the global shifting you're after (moving elements to the left).
About the number of elements to be moved, it should move i elements minus the first one that doesn't move and only gets overwritten. Hence the length - 1 - i.
The inner loop could be replaced with an arraycopy, however, you don't need an inner loop:
int[] numbers = {1,2,3,2,2,4,5};
int j = 0;
for (int i = 0; i < numbers.length; i++){
if (numbers[i] != 2){
numbers[j++] = numbers[i];
}
}
while (j < numbers.length) {
numbers[j++] = 0;
}
UPDATE
Or even:
int[] numbers = {1,2,3,2,2,4,5};
int j = 0;
for (int n: numbers){
if (n != 2){
numbers[j++] = n;
}
}
Arrays.fill(numbers,j,numbers.length,0);
The key thing is pretty simple: if you can reduce the lines of code you are responsible for (for example by using utility methods such as Arrays.arraycopy()) - then do that.
Keep in mind: each line that you write today, you have to read and understand tomorrow, and to probably modify in 5 weeks or months from now.
But then: I think you are over-complicating things here. I would use a temporary list, like this:
List<Integer> notTwos = new ArrayList<>();
int numberOfTwos = 0;
for (int i=0; i<source.length; i++) {
if (source[i] == 2) {
numberOfTwos++;
} else {
notTwo.append(source[i]);
}
}
... simply append `numberOfTwo` 0s to the list, and then turn it into an array
You see: you are nesting two for-loops, and you are repeatedly copying around elements. That is inefficient, hard to understand, and no matter how you do it: way too complicated. As shown: using a second list/array it is possible to "solve" this problem in a single pass.
After replacing your inner loop with System.arrayCopy the code should look like:
int[] numbers = { 1, 2, 3, 2, 2, 4, 5 };
for (int i = 0; i < numbers.length; i++) {
if (numbers[i] == 2) {
System.arraycopy(numbers, i + 1, numbers, i, numbers.length - 1 - i);
numbers[numbers.length - 1] = 0;
i--;
}
}
So, I am building a method to check a 2d array for a target value and replace each adjacent element with that target value. I have literally tried to brainstorm the solution to this for about an hour and I just want to know if anyone can help me with this, this is the code I have so far
public int[][] replaceValue(int n, int[][]y){
int [][]temp0 = new int[y.length][y[0].length];
int[]top, down ,left, right = new int[y[0].length];
for(int row = 0; row < y.length; row++){
for(int col = 0; col < y[row].length; col++){
temp0[row][col] = y[row][col];// new array so I wouldn't mess with the array passed in
}
}
for(int row = 0; row < temp0.length; row++){
for(int col = 0; col < temp0[row].length; col++){
top[row] = temp0[row-1][col];
down[row] = temp0[row+1][col];
right[row] = temp0[row][col+1];
left[row] = temp0[row] [col-1];
}
}
I got error messages such as I didn't initialize my top and left and right and down variables but I simply don't understand how the logic works for checking the adjacent elements and making sure the whole array is not replaced with the target value. Thanks
The question is a little confusing so I will try to interpret it.
What you are given is a 2-dimensional array with some integer values. Your function should scan the 2-d array, and if you find some target value,
return a 2-d array with the adjacent indices as the target value as well.
For example, if we have a 3x3 array and the target is 2...
1 1 1 1 2 1
1 2 1 ====> 2 2 2
1 1 1 1 2 1
Your problem is that you can't think of a way to change the value without changing the entire array to 2.
Solution One: You scan for the target value in the given array, but you update the values in the temporary array.
Solution Two: You scan the temporary array, and store whether or not it should be changed using a 2-d boolean array.
Solution One is much better in terms of efficiency (both memory and time), so I'll just give you my solution #2, and leave you to do Solution One on your own.
Also, please use more descriptive variable names when it matters :P (why is the input called temp??)
public static int[][] replaceValue(int target, int[][] currArray){
int[][] temp = new int[currArray.length][];
//get a boolean array of same size
//NOTE: it is initialized as false
boolean[][] needsChange = new boolean[currArray.length][currArray[0].length];
//copy the current array into temp
for(int i = 0; i < currArray.length; i++){
temp[i] = currArray[i].clone();
}
//Go through each value in the 2d array
for(int i = 0; i < temp.length; i++){
for(int j = 0; j < temp[0].length; j++){
//if it is the target value, mark it to be changed
if(temp[i][j] == target){
needsChange[i][j] = true;
}
}
}
//Go through each value in the 2d array
for(int i = 0; i < temp.length; i++){
for(int j = 0; j < temp[0].length; j++){
if(needsChange[i][j]){ //NOTE: same as "needsChange[i][j] = true;"
//Now, we will check to make sure we don't go out of bounds
//Top
if(i > 0){
temp[i-1][j] = target;
}
//Bottom
if(i + 1 < temp.length){
temp[i+1][j] = target;
}
//Left
if(j > 0){
temp[i][j-1] = target;
}
//Right
if(j + 1 < temp[0].length){
temp[i][j+1] = target;
}
}
}
}
//return the new array we made
return temp;
}
You have not initialized your local variables before first use. So you need to change your 3rd line to some thing like the below code:
int[] top = new int[temp[0].length], down = new int[temp[0].length],
left = new int[temp[0].length], right = new int[temp[0].length];
After that your code is compiled and you can check your logic.
I am not sure why I am returning false for the first test run as shown in the test table attachment. This was one of my assignments last semester and I never figured out how to solve it:/ My assignment was to:
Write the definition of a method , oddsMatchEvens, whose two parameters are arrays of integers of equal size. The size of each array is an even number. The method returns true if and only if the even-indexed elements of the first array equal the odd-indexed elements of the second, in sequence. That is if w is the first array and q the second array , w[0] equals q[1], and w[2] equals q[3], and so on.
Test table
My code was:
public boolean oddsMatchEvens(int[] w, int[] q) {
int count = 0;
for (int i = 0; i < w.length; i++) {
if (w[i] == q[i + 1])
count++;
if (count == (w.length - 1))
return true;
}
return false;
}
if (count == (w.length - 1))
return true;
This is wrong, since you have only w.length/2 indices which you have to compare.
You should just return false, if w[i] != q[i+1].
And you should increase i by 2, not by 1.
There are two problems with the code:
Firstly, it is clearly mentioned the two input arrays are of equal length and you have to compare them even index to odd index. So the corner case occurs when you are checking last item of first array with last+1 item of second array(which doesn't exist as arrays are of equal length.
Secondly, you have to check first array even with second array odd so increment should be i+=2 and not i++.
Correct code with optimization(if one check fails you can come out of loop):
public boolean oddsMatchEvens(int[] w, int[] q) {
for (int i = 0; i < w.length-1; i+=2) {
if (w[i] != q[i + 1])
return false;
else
continue;
}
return true;
}
public boolean oddsMatchEvens (int []w, int []q) {
for (int j = 0; j < w.length-1; j+=2) {
if (w [j] != q [j+1])
return false;
continue;
}
return true;
}
I want to check whether array B is permutation of array A.
I thought it can be done using 1 for-loop, however I saw different sources that most of them told me to use 2 for-loops.
for (int i = 0; i < A.length; i++) {
boolean found = false;
for (int j = 0; j < B.length; j++)
if (B[j] == A[i]) {
found = true;
break;
}
assert(found);
}
for (int i = 0; i < B.length; i++) {
boolean found = false;
for (int j = 0; j < A.length; j++)
if (A[j] == B[i]) {
found = true;
break;
}
assert(found);
}
Is this a correct implementation with 2 for-loops?
By the way, why I had to perform 2 for-loops where first one is comparing B with A, then the second one A with B?
Your code splits the permutation check into two operations:
for each element A[i] check if A[i] appears in B
for each element B[j] check if B[j] appears in A
As noted by #Tom, this doesn't work in the general case, because it ignores duplicate elements.
It is also inefficient. The second part can be omitted, if one checks A.length == B.length before anything else, but the remainder is still O(n²). And it's still wrong, because it returns false positives when considering duplicate elements.
The --more or less-- canonical method is to simply sort both arrays and compare them for equality:
Arrays.sort(A);
Arrays.sort(B);
assert(Arrays.equals(A, B));
Sorting is generally know to be O(n ln n), so the whole operation is now more efficient than before. It also makes things a whole lot more readable.
I've a slight problem. I'm taking every element in a sparse matrix and putting it into a 1d array named 'b[]'. For example:
00070
00400
02000
00050
10000
Becomes: 0007000400020000005010000
The code below works in that at a given point within the inner-most loop b[] has the correct value as shown below. My problem is that outside of the inner-most loop b[] has a value of:
b[] = 0000000000000000000000000
I cannot understand what I'm missing. It should also be noted that b[] is globally defined, and instantiated within the constructor of this class. The problem is that I'm trying to use this 1d array in another function, and every element within the array is set to 0.
public void return1dSequence() {
// Create paired objects (Pair class).
for (int i = 0; i < a.length; i++) {
for(int j = 0; j < a[i].length; j++) {
this.b[i] = a[i][j];
// System.out.print(b[i]);
if (this.b[i] == 0) {
pos += 1;
} else {
value = this.b[i];
ml.add(new Pair(pos, value));
pos += 1;
}
}
}
}
Thanks in advance for any replies,
Andre.
You're filling in b[i] for indexes i of your outer loop...
Each time in the inner loop, you overwrite b[i] with value a[i][j].
Last value of a[i] array is always zero.
That's why your b array is zero.
What you want is probably:
int counter = 0;
for (int i = 0; i < a.length; i++) {
for(int j = 0; j < a[i].length; j++) {
b[counter] = a[i][j];
counter++;
}
}
The first thing i want to mention is that u shouldn't declare your variables (a, b....) static. Maybe u got hit by a mean side effect after creating two instances of Sparse. Try to define them as non static and report if it still wont work.
Best regards
Thomas
Try removing this from each call to b[] if you want to access b[] as static.
Also, are you sure you are not overwritting b[] anywhere else in the code? This is most likely the issue because of the public static declaration. Try making it private and removing static and see if you still have the issue.