copy element of array - java

I can't figure out why isn't the code copying the unique elements to another array. Here is my code. I though that the == is to copy the element, but I got an error, so I used the = instead.
public static void main(String[] args) {
// TODO Auto-generated method stub
int[] B = new int[15];
B[2] = 2;
B[3] = 3;
B[4] = 4;
B[5] = 5;
B[6] = 6;
B[7] = 7;
B[8] = 8;
B[9] = 9;
B[10] = 10;
int[] check = new int[B.length];
for (int i = 0; i < B.length; i++) {
for (int x = 0; x < check.length; x++) {
if (B[i] != check[x]) {
check[x] = B[i];
}
}
}
for (int i = 0; i < check.length; i++) {
System.out.println(check[i]);
}
}

You're looping over everything twice, when it should just be once.
Currently it looks like this:
for (int i = 0; i < B.length; i++) {
for (int x = 0; x < B.length; x++) {
if (B[i] != check[x]) {
check[x] = B[i];
}
}
}
This means that when i = 0 , then x=0, 1, 2, 3, 4, etc.. . Then when i = 1, x=0,1,2,3.... , etc.
So the last run will be i=14, where B[i] = 0.
So for every check[x], it won't be equal to 0.
What you want to do is handle it in a line. So instead of 2 variables i and x you can just use i and the outer loop, like this. This means that you're only comparing B[1] to check[1] and B[2] to check[2], and so on.
Like this:
for (int i = 0; i < B.length; i++) {
if (B[i] != check[i]) {
check[i] = B[i];
}
}

== is for test of equalation,= is for assignment,
by the way ,use System.arraycopy(xxx) to copy arrays.
public int[] findUnique(int[] data) {
int[] unique = new int[data.length];
int x = 0;
for (int i = 0; i < data.length; i++) {
boolean uni = true;
for (int j = i + 1; j < data.length; j++) {
if (data[i] == data[j]) {
uni = false;
break;
}
}
if (uni) {
unique[x++] = data[i];
}
}
return unique;
}

System.arrayCopy() is much faster

Related

Non-repeating numbers in 2D array

I have problem with my code, I want to find not repeated numbers in array but I don't know how!
1 2
3 4
1 4
For example in this case, I wan the output to be number 3 and 2:
I used this code for getting array, it's like a matrix
for (int i = 1; i <= 3; i++) {
for (int j = 1; j <= 2; j++) {
cam[i][j] = in.nextInt();
}
}
And something like this one for comparing for each one:
for (int i = 1; i <= 3; i++) {
if (cam[i][2] != cam[i+1][2]) {
y = cam[i+1][2];
break;
}
}
Update: whole code is down below
int x=0,y=0;
int[][] cam = new int[10][10];
for (int i = 1; i <= 3; i++) {
for (int j = 1; j <= 2; j++) {
cam[i][j] = in.nextInt();
}
}
for (int i = 1; i <= 3; i++) {
if (cam[i][1] != cam[i+1][1]) {
x = cam[i+1][1];
break;
}
for (int i = 1; i <= 3; i++) {
if (cam[i][2] != cam[i+1][2]) {
y = cam[i+1][2];
break;
}
}
System.out.println(x+" "+y);
Array indices are 0, 1, 2, ..., length-1.
for (int i = 0; i < cam.length; i++) {
for (int j = 0; j <= cam[i].length; j++) {
cam[i][j] = in.nextInt();
}
}
The search code:
for (int i = 0; i < cam.length; i++) {
for (int j = 0; j <= cam[i].length; j++) {
int valueAtIJ = cam[i][j];
boolean found = false;
... walk here through cam using valueAtIJ, set found, skip i, j.
if (!found) {
...
}
}
}
If alread Set/Map is treated in your course there are smarter solutions. But also this kind of for-i2-for-j2 loop can be optimized.
Assuming from your code that you are looking only in column 1 and 2 (do you have other data in column 0?):
for (int i = 1; i <= 3; i++) {
found = false;
for (int i1 = i + 1; i1 <= 3; i1++) {
if (cam[i][1] == cam[i1][1]) {
found = true;
break;
}
}
if (!found) {
x = cam[i][1];
}
}
for (int i = 1; i <= 3; i++) {
found = false;
for (int i1 = i + 1; i1 <= 3; i1++) {
if (cam[i][2] == cam[i1][2]) {
found = true;
break;
}
}
if (!found) {
y = cam[i][2];
}
}
You can collect a map of duplicates from this 2d array, then iterate over this map and apply filter for non-repeating elements:
int[][] arr = {
{1, 2},
{3, 4},
{1, 4}};
Map<Integer, Long> map = Arrays.stream(arr)
.flatMapToInt(Arrays::stream).boxed()
.collect(Collectors.groupingBy(
Integer::intValue, Collectors.counting()));
System.out.println(map); // {1=2, 2=1, 3=1, 4=2}
int[] arr2 = map.entrySet().stream()
.filter(e -> e.getValue() == 1)
.mapToInt(Map.Entry::getKey)
.toArray();
System.out.println(Arrays.toString(arr2)); // [2, 3]
See also: How to find duplicate elements in array in effective way?

Exchange values of two arrays, make another array without repeats and sort from highest to lowest

I know I have to do it with a while or do while loop, but I can't get it working. I also tried with a for loop, but it always gives me an error because I don't know the exact length of the vectors because they are random.
int a = (int)(Math.random() * 3 + 1);
int b = (int)(Math.random() * 3 + 1);
int c = a + b;
int[] arrA = new int[a];
int[] arrB = new int[b];
int[] arrC = new int[c];
for (int i = 0; i < a; i ++) {
arrA[i] = (int)(Math.random() * 10 + 1);
for (int j = 0; j < b; j ++) {
arrB[j] = (int)(Math.random() * 10 + 1);
}
}
Arrays.sort(arrA);
Arrays.sort(arrB);
System.out.println(Arrays.toString(arrA));
System.out.println(Arrays.toString(arrB));
System.out.println(Arrays.toString(arrC));
Take values from arrays arrA and arrB, and insert to arrC
int index = arrA.length;
for (int i = 0; i < arrA.length; i++) {
arrC[i] = arrA[i];
}
for (int i = 0; i < arrB.length; i++) {
arrC[i + index] = arrB[i];
}
Sort arrC
Arrays.sort(arrC);
Reverse the order and store in arrD
for(int l = 0; l < arrC.length; l++) {
arrD[l] = arrC[arrC.length - (l+1)];
}
Remove duplicate (simplified)
Set<Integer> remove=new LinkedHashSet<Integer>();
for(int i = 0;i < arrD.length;i++){
remove.add(arrD[i]);
}
Remove duplicate (usual)
int index2 = 0;
for (int i = 0; i < arrD.length; i++) {
for (int k = 0; k < arrD.length; k++) {
if (arrD[i] != arrD[k]) {
arrE[index2] = arrD[i];
index2++;
}
}
}

Finding the mode of an array Java

I've got to find the mode of an array. I am a bit embarrassed to admit that I've been stuck on this for a day. I think I've overthought it a bit - my method just gets longer and longer. The real issue that I keep running into is that when there isn't one mode (two numbers appear with the same frequency) I need to return Double.NaN.
Here's what I've tried:
private double[] data = {1, 1, 2, 2, 2, 3, 4, 5, 5, 5, 5, 5, 6, 7, 7, 8, 8, 8, 8, 8, 9, 9, 9};
if(data.length != 0){
double maxValue = -1;
int maxCount = 0;
for(int i = 0; i < data.length; i++) {
int count = 0;
for(int j = 0; j < data.length; j++) {
if(data[j] == data[i]) {
count++;
}
}
if(count > maxCount) {
maxValue = (int) data[i];
maxCount = count;
}
}
return maxValue;
}else{
return Double.NaN;
}
This actually returns the mode, but it can't deal with two modes. Here's my most recent attempt, but it's only half complete:
private double[] data = {1, 1, 2, 2, 2, 3, 4, 5, 5, 5, 5, 5, 6, 7, 7, 8, 8, 8, 8, 8, 9, 9, 9};
public void mode(){
int[] frequency = new int[data.length];
double[] vals = new double[data.length];
for(int i = 0; i < data.length; i++){
frequency[i] = occursNumberOfTimes(data[i]);
}
boolean uniform = false;
for(int g = 0; g < frequency.length && !uniform; g++){
if(frequency[0] != frequency[g]){
uniform = false;
}
int[] arr = new int[frequency.length-1];
for(int j = 1; j < frequency.length; j++){
if(frequency[j] > frequency[j-1]){
int mod = 0;
for(int k = 0; k < arr.length; k++){
if(k == j){
mod += 1;
arr[k] = frequency[k + mod];
}else{
arr[k] = frequency[k + mod];
}
}
}
}
frequency = arr;
}
}
private int occursNumberOfTimes(double value){
int count = 0;
for(int i = 0; i < data.length; i++){
if(data[i] == value){
count++;
}
}
return count;
}
I sorta got lost in the second try, I just can't sort out how to deal with multiple modes. I've written out my thoughts, but I just don't know how. I can't use anything from the Arrays class, which is why I'm lost.
Does it have to be efficient? If not:
double maxValue = -1.0d;
int maxCount = 0;
for (int i = 0; i < data.length; ++i) {
double currentValue = data[i];
int currentCount = 1;
for (int j = i + 1; j < data.length; ++j) {
if (Math.abs(data[j] - currentValue) < epsilon) {
++currentCount;
}
}
if (currentCount > maxCount) {
maxCount = currentCount;
maxValue = currentValue;
} else if (currentCount == maxCount) {
maxValue = Double.NaN;
}
}
System.out.println("mode: " + maxValue);
You could track the two most common elements as was suggested in the comments, but another approach is to keep a boolean flag that indicates if the current most common element is unique. Then:
For each array element e, obtain its count as you're currently doing.
If that count is greater than the current max, set the the most common element (seen so far) to e and set the "unique" flag to true.
Otherwise, if that count is equal to the current max, set the "unique" flag to false.
At the end, just return the mode if "unique" is true, otherwise return NaN.
Here's my long, dumb solution. It works! It's a very roundabout way of getting the mode, but I'm really happy it works. I used the advice I got from some comments and looked at it differently. It was a frustrating few hours, but here it is:
public double mode2(){
if(data.length != 0){
int[] counts = new int[data.length];
double[] vals = new double[data.length];
for(int l = 0; l < data.length; l++){
counts[l] = 1;
}
for(int i = 0; i < data.length; i++){
for(int j = 0; j < data.length; j++){
if((data[i] == data[j]) && (i != j)){
vals[i] = data[i];
counts[i] += 1;
}
}
}
for(int i = 0; i < data.length; i++){
for(int j = 0; j < data.length; j++){
if((vals[i] == vals[j]) && (i != j)){
vals[i] = 0;
counts[i] = 0;
}
}
}
int counter = 0;
for(int k = 0; k < data.length; k++){
if(counts[k] != 0){
counts[counter] = counts[k];
vals[counter] = vals[k];
counter++;
}
}
int[] compactCounts = new int[counter];
double[] compactVals = new double[counter];
for(int k = 0; k < counter; k++){
if(counts[k] != 0){
compactCounts[k] = counts[k];
compactVals[k] = vals[k];
}else{
break;
}
}
for(int g = 1; g < compactVals.length; g++){
if(compactCounts[g] > compactCounts[g-1]){
compactCounts[g-1] = 0;
compactVals[g-1] = 0;
}
}
for(int g = 0; g < compactVals.length-1; g++){
if(compactCounts[g] > compactCounts[g+1]){
compactCounts[g+1] = 0;
compactVals[g+1] = 0;
}
}
int counterTwo = 0;
for(int k = 0; k < compactCounts.length; k++){
if(compactCounts[k] != 0){
compactCounts[counterTwo] = compactCounts[k];
compactVals[counterTwo] = vals[k];
counterTwo++;
}
}
int[] compactCountsTwo = new int[counterTwo];
double[] compactValsTwo = new double[counterTwo];
for(int k = 0; k < counterTwo; k++){
if(counts[k] != 0){
compactCountsTwo[k] = compactCounts[k];
compactValsTwo[k] = compactVals[k];
}else{
break;
}
}
//now populated compactTwos
//We're now setting some lesser values to 0
for(int g = 1; g < compactValsTwo.length; g++){
if(compactCountsTwo[g] > compactCountsTwo[g-1]){
compactCountsTwo[g-1] = 0;
compactValsTwo[g-1] = 0;
}
}
//now setting other lesser values to 0
for(int g = 0; g < compactValsTwo.length-1; g++){
if(compactCountsTwo[g] > compactCountsTwo[g+1]){
compactCountsTwo[g+1] = 0;
compactValsTwo[g+1] = 0;
}
}
//calling methods to shorten our arrays by dropping indexes populated by zeroes
compactValsTwo = doubleTruncator(compactValsTwo);
compactCountsTwo = intTruncator(compactCountsTwo);
//now setting some lesser values to 0
for(int g = 1; g < compactValsTwo.length; g++){
if(compactCountsTwo[g] > compactCountsTwo[g-1]){
compactCountsTwo[g-1] = 0;
compactValsTwo[g-1] = 0;
}
}
//now setting other lesser values to 0
for(int g = 0; g < compactValsTwo.length-1; g++){
if(compactCountsTwo[g] > compactCountsTwo[g+1]){
compactCountsTwo[g+1] = 0;
compactValsTwo[g+1] = 0;
}
}
//calling methods to shorten our arrays by dropping indexes populated by zeroes
compactValsTwo = doubleTruncator(compactValsTwo);
compactCountsTwo = intTruncator(compactCountsTwo);
if(compactValsTwo.length > 1){
return Double.NaN;
}else{
return compactValsTwo[0];
}
}else{
System.out.println("ISSUE");
return Double.NaN;
}
}
public double[] doubleTruncator(double[] a){
int counter = 0;
for(int k = 0; k < a.length; k++){
if(a[k] != 0){
a[counter] = a[k];
counter++;
}
}
double[] b = new double[counter];
for(int i= 0; i < counter; i++){
if(a[i] != 0){
b[i] = a[i];
}else{
break;
}
}
return b;
}
public int[] intTruncator(int[] a){
int counter = 0;
for(int k = 0; k < a.length; k++){
if(a[k] != 0){
a[counter] = a[k];
counter++;
}
}
int[] b = new int[counter];
for(int i= 0; i < counter; i++){
if(a[i] != 0){
b[i] = a[i];
}else{
break;
}
}
return b;
}
Big thanks to everybody who helped. I know it's not great (certainly not as good as the answer from #Perdi Estaquel), but I'm happy that I managed to do it.

Removing N duplicates from integer array

problem statement: I have to remove n duplicates from array.
Here is the full problem statement : https://pastebin.com/EJgKUGe3
and my solution is :
public class minion_labour_shift_2ndTry {
static int[] data = {1,2, 2, 3, 3, 3, 4, 5, 5};
public static void main(String[] args) {
Scanner reader = new Scanner(System.in);
int n = reader.nextInt();
data = answer(data, n);
for (int i = 0; i < data.length; i++) {
System.out.print(data[i] + " ");
}
}
public static int[] answer(int[] data, int n) {
if (data.length>99){
System.exit(0);
}
int[] result = new int[99];
ArrayList<Integer> temp = new ArrayList<>();
int counter = 0, count ,maxCount = 0;
for (int i = 0; i < data.length; i++) {
boolean isDistinct = false;
for (int j = 0; j < i; j++) {
if (data[i] == data[j]) {
isDistinct = true;
break;
}
}
if (!isDistinct) {
result[counter++] = data[i];
}
}
for (int i = 0; i < counter; i++) {
count = 0;
for (int j = 0; j < data.length; j++) {
if (result[i] == data[j]) {
count++;
}
}
System.out.println("....... count"+count);
if (maxCount <= count){
maxCount = count;
}
if (count <= n){
temp.add(result[i]);
}
}
if (maxCount-1 < n){
return data;
}
data = new int[temp.size()];
for (int i = 0; i <temp.size() ; i++) {
data[i] = temp.get(i);
}
return data;
}
}
Now, my question is, what I am missing and what should I do to pass all the 10 cases.
Thanks In Advance :)
NB:It will be compiled in java 7 , and Map,hashset or third-party libraries, input/output operations, spawning threads or processes and changes to the execution environment are not allowed.
I misread the requirements initially, this does what is asked:
public static int[] answer(int[] data, int n) {
Map<Integer, Integer> counts = new HashMap<>();
int elementsNeeded = 0;
for (int i = 0; i < data.length; i++) {
Integer currentCount = counts.get(data[i]);
currentCount = currentCount == null ? 1 : ++currentCount;
counts.put(data[i], currentCount);
if (currentCount <= n + 1) {
elementsNeeded += currentCount > n ? -n : 1;
}
}
int[] resultArray = new int[elementsNeeded];
int j = 0;
for (int i = 0; i < data.length; i++) {
if (counts.get(data[i]) <= n) {
resultArray[j++] = data[i];
}
}
return resultArray;
}
...and also your own code, slightly altered:
public static int[] answer2(int[] data, int n) {
if (data.length>99){
System.exit(0);
}
ArrayList<Integer> temp = new ArrayList<>();
int count;
for (int i = 0; i < data.length; i++) {
count = 0;
for (int j = 0; j < data.length; j++) {
if (data[i] == data[j]) {
count++;
}
}
if (count <= n){
temp.add(data[i]);
}
}
data = new int[temp.size()];
for (int i = 0; i <temp.size() ; i++) {
data[i] = temp.get(i);
}
return data;
}
Not going to provide a full solution but suggesting a reworking of the algorithm because it's not clear what you're doing, you never explained your actual thoughts of the algorithm. For example, what are you using isDistinct for?
1) Loop through once and compute the frequency of every number. You can just use an array of length 100 since that's all the data inputs will be. As you loop through, keep track of two things: The total number of entries that occur more than n times, as well as which those numbers are
2) Create a resulting array of the appropriate size (calculated from above) and loop through the list again and fill in the elements that didn't cross the threshold.

How to make while loop work properly to correct given 2D array

I'm trying to write a method that will take a two-dimensional array as an input, and return a new 2D array in which all the zeroes are removed from the array.
Also, if there is an element in the first array that has a value equal to the length of the second array, then it should be removed and all elements in the second array will be subtracted by 1.
The above process should be repeated for the second array also.
This is what I've written for the code implementation so far, but the code gets stuck in a loop and I don't think it's doing what it's supposed to do.
Note: When ArrayUtils is called, the Apache Lang library is being used, and this is the 2D array I inputted:
[[0, 0, 2, 2, 3, 4], [0, 0, 2, 2, 3, 4]]
Code:
public static int[][] removeTrivialCases(int[][] startingSums) {
int[][] correctedSums = startingSums;
int counter = 0;
int numRows = correctedSums[0].length;
int numCols = correctedSums[1].length;
boolean zeroesExist = true;
boolean valueEqualsDimension = true;
boolean trivialCasesRemain = true;
while(trivialCasesRemain) {
for (int i = 0; i < correctedSums.length; i++) {
for (int j = 0; j < correctedSums[i].length; j++) {
if (correctedSums[i][j] == 0) {
trivialCasesRemain = true;
correctedSums[i] = ArrayUtils.removeElement(correctedSums[i], j);
}
for (int h = 0; h < correctedSums[i].length; h++) {
if (correctedSums[i][h] == 0) {
zeroesExist = true;
}
}
}
}
for (int i = 0; i < correctedSums[0].length; i++) {
if (correctedSums[0][i] == numCols) {
trivialCasesRemain = true;
correctedSums[0] = ArrayUtils.removeElement(correctedSums[0], i);
for (int j = 0; j < correctedSums[0].length; j++) {
correctedSums[0][j]--;
}
valueEqualsDimension = false;
for (int h = 0; h < correctedSums[0].length; h++) {
if (correctedSums[0][h] == numCols) {
valueEqualsDimension = true;
}
}
}
}
for (int i = 0; i < correctedSums[1].length; i++) {
if (correctedSums[1][i] == numRows) {
trivialCasesRemain = true;
correctedSums[1] = ArrayUtils.removeElement(correctedSums[1], i);
for (int j = 0; j < correctedSums[1].length; j++) {
correctedSums[1][j]--;
}
}
valueEqualsDimension = false;
for (int h = 0; h < correctedSums[1].length; i++) {
if (correctedSums[1][h] == numRows) {
valueEqualsDimension = true;
}
}
}
if (!zeroesExist || !valueEqualsDimension) {
trivialCasesRemain = false;
}
}
return correctedSums;
}
Regarding,
but the code gets stuck in a loop and I don't think it's doing what it's supposed to do.
Here:
for (int h = 0; h < correctedSums[1].length; i++) {
This loop will never end since h never changes within the loop. It should be:
for (int h = 0; h < correctedSums[1].length; h++) {
If you ran the code in a debugger, or used println's, you'd know what loop the code is stuck in, and this would allow you to inspect it immediately and correct it.

Categories

Resources