Check if one array is a permutated version of another array - java

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.

Related

How to make nested for loops not increase frequency of actions within the for loop

I am currently using nested for loops to see if two rectangles have intersected or not.
for(int i = 0; i < enemies.size(); i++) {
for(int j = 0; j < enemies.size(); j++) {
if(!enemies.get(i).pureHitbox.intersects(enemies.get(j).pureHitbox) && i != j) {
enemies.get(i).action();
}
}
}
Problem is, the action the objects do increase in frequency by the amount of objects in the ArrayList. The current action is to move 3 in any direction, but if there are 2 in the ArrayList, it will move 6, if there are 3, it will move 9, etc.
I can't think of any way to make this work effectively.
Your problem is when you search intersection and e.g. A and B have intersection, you make an action twice (A intersects B and B intersects A). All you need, is just check whether given action was executed for given A and B or not.
for(int i = 0, total = enemies.size(); i < total - 1; i++)
for(int j = i + 1; j < total; j++)
if(!enemies.get(i).pureHitbox.intersects(enemies.get(j).pureHitbox))
enemies.get(i).action();
So, I figured it out. It was very simple, all I had to do was add a break after it moved once.

Printing unique elements repeated more than once

How do you print a unique array consisting of elements only repeated more than once in an original array in Java? For example, there is an array a = {1,2,2,2,3,4,5,5}, the output should be {2,5}. It should be using only arrays.
I have attempted the question and this is what I've done so far:
for (int i = 0; i < a.length; i++) {
int j;
for (j = 0; j < i; j++) {
if (a[i] == a[j]) break;
}
if (i == j) System.out.print(a[i]+" ");
}
The output is all the unique elements in the array, but I am trying to print the ones that are specifically repeated more than once.
Assuming the input array contains elements that are Comparable or otherwise primitive types, you can follow these steps. The goal is essentially to find the last element of all chains of length > 1.
Sort the array using Arrays.sort (if necessary).
Iterate over the array, starting at the second element. For each element:
If the preceding element is equal to the current element,
and the succeeding element is not equal to the current element (or if there is no succeeding element)...
Then print the current element.
Note: If you had access to a HashMap, there would be an O(n) version of this O(n log(n)) algorithm.
Here it is in code:
public static void printDuplicates(int[] a) {
Arrays.sort(a);
for (int i = 1; i < a.length; i++) {
boolean precIsEqual = (a[i-1] == a[i]);
boolean succIsEqual = (i+1 != a.length) && (a[i+1] == a[i]);
if (precIsEqual && !succIsEqual) {
System.out.print(a[i] + " ");
}
}
}
Ideone Demo
Output: 2 5

about insertion sort improvement in Robert Sedgewick

I am reading about algorithms by Robert Sedgewick book.
public static void sort(Comparable[] a)
{ // Sort a[] into increasing order.
int N = a.length;
for (int i = 1; i < N; i++)
{ // Insert a[i] among a[i-1], a[i-2], a[i-3]... ..
for (int j = i; j > 0 && less(a[j], a[j-1]); j--)
exch(a, j, j-1);
}
}
Above is insertion sort implementation in java. Here author mentiones as improvment as below.
It is not difficult to speed up insertion sort substantially, by shortening its inner loop to move the larger entries to the right one position rather than doing full exchanges (thus cutting the number of array accesses in half)
I am having difficutly in understanding above improvement. What does author mean by
Move large entries to the right one postion rather than full exchanges and how this will reduce array access to half.
Request to example with simple example for better understanding.
I think that he is referring to the fact that you don't need to keep on actually swapping elements, because you will end up repeatedly moving the same element.
For instance, you can cache the value of the i-th element initially, and refer just to this in the inner loop:
public static <C extends Comparable<C>> void insertionSort(C[] a) {
for (int i = 1; i < a.length; i++) {
C ithElement = a[i];
int j = i;
for (j = i; j > 0 && ithElement.compareTo(a[j - 1]) < 0; --j) {
// This is "moving the larger entry to the right 1 position"
a[j] = a[j - 1];
}
a[j] = ithElement;
}
}
Demo

How does this bubblesort variation effectively carry out a sort?

// A strange variation on a bubblesort I created inadvertently. I omitted the usual if a[j] >a[j+1] by mistake yet the code was still able to function perfectly. Would there be any advantage to using a bubblesort of this kind over a normal bubblesort.
public int[] bubbleSort(int[] a)
{
for (int i = 0; i < a.length - 1; i++)
{
for (int j = i + 1; j < a.length - 1; j++)
{
if (a[i] > a[j])
{
int temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}
}
return a;
}
Notice that at the end of the first iteration of the outer loop, the first value in the array will necessarily be the minimum value in the array (do you see why?) After the second iteration, the second value will be the second-smallest value, and after the third iteration the third value will be the third-smallest value, etc.
(That said, I think there's a bug in your logic. The upper bound on j should be a.length rather than a.length - 1, since otherwise the last value in the array is never compared to anything else or moved.)
You might want to look into selection sort, which works by moving the smallest value in the array to the front, then the second-smallest, etc. The algorithm you've come up with is (essentially) a modified version of selection sort rather than a modified bubble sort.
Hope this helps!

delete position in array of string

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);

Categories

Resources