I need some help from the experts. I've got a task to find 2 duplicate elements in a 2d array and print out their indexes. Here's the code i've made. It creates a 2d array, then fill it manually from the keyboard. But now i have some problems with the method that finds and prints the duplicates. It prints FALSE if there are no duplicates, and TRUE if there are some. But I can't make it print out ALL the duplicates and its indexes. Please help me with this. Best regards
import java.io.*;
import java.util.HashSet;
import java.util.Set;
import static java.lang.System.out;
public class Main {
public static void main(String[] args)
throws NumberFormatException, IOException {
BufferedReader reader = new BufferedReader
(new InputStreamReader (System.in));
out.println("Введите размерность массива n:");
int n = Integer.parseInt(reader.readLine());
out.println("Введите размерность массива m:");
int m = Integer.parseInt(reader.readLine());
int [][] a = new int [n][m];
out.println("Введите числа массива :");
int i,j;
for (i = 0; i < a.length; i++) {
for (j = 0; j < a[i].length; j++) {
a[i][j] = Integer.parseInt(reader.readLine());
}
}
out.println("Введенный массив : ");
for (i = 0; i < a.length; i++, out.println()) {
for (j = 0; j < a[i].length; j++) {
out.printf(" %4d", a[i][j]);
}
}
out.println(extra(a));
}
private static boolean extra(int[][] data) {
Set<Integer> set = new HashSet<Integer>();
for (int i = 0; i < data.length; i++) {
for (int j = 0; j < data[i].length; j++) {
if (set.contains(data[i][j])) {
out.printf("[%d][%d] - %d\n", i, j, data[i][j]);
return true;
} else {
set.add(data[i][j]);
}
}
}
return false;
}
}
A general method for determining if any item in a collection satisfies a condition, while also processing every item, is:
boolean conditionSatisfied = false;
for each item in collection {
if item satisfies condition {
process item;
conditionSatisfied = true;
}
}
return conditionSatisfied;
I changed your method and used one boolean variable found..This will work
private static boolean extra(int[][] data) {
boolean found = false;
Set<Integer> set = new HashSet<Integer>();
for (int i = 0; i < data.length; i++) {
for (int j = 0; j < data[i].length; j++) {
if (set.contains(data[i][j])) {
out.printf("[%d][%d] - %d\n", i, j, data[i][j]);
found = true;
} else {
set.add(data[i][j]);
}
}
}
return found;
}
Related
I am not sure why I need to declare count and correct inside the first for loop here. I originally declared them as global variable but I am modifying them inside for loop. If I don't declare them inside for loop they remain the same value I think. My logic is the value gets changed inside for loop. Am I approaching this thoughts wrong?
public static double[] gradeAllStudents(char[][] response, char[] soln) {
// int count = 0;
int len = soln.length;
// int correct = 0;
double[] result = new double[response.length];
int index = 0;
for(int i = 0; i < response.length; i++) {
int count = 0;
double correct = 0;
// System.out.println(response[i].length);
for(int j = 0; j < response[i].length; j++) {
if (soln[j] == response[i][j]) {
correct= correct+1;
}
count ++;
}
// System.out.println(correct);
result[index] = 100*(correct)/(response[i].length);
index++;
if(count != len) {
throw new IllegalArgumentException("wrong exam");
}
}
return result;
}
}
I'm not sure that i got your problem
but
you can declare variable outside for loop and changing them inside.
in your example the code will look like this
public static double[] gradeAllStudents(char[][] response, char[] soln) {
int count;
int len = soln.length;
int correct;
double[] result = new double[response.length];
int index = 0;
for(int i = 0; i < response.length; i++) {
count = 0; // restart value of count
correct = 0; // restart value of correct
// System.out.println(response[i].length);
for(int j = 0; j < response[i].length; j++) {
if (soln[j] == response[i][j]) {
correct= correct+1;
}
count ++;
}
// System.out.println(correct);
result[index] = 100*(correct)/(response[i].length);
index++;
if(count != len) {
throw new IllegalArgumentException("wrong exam");
}
}
return result;
}
}
PS : you can improve your code
this still simple but better
public static double[] gradeAllStudents(char[][] response, char[] soln) {
final int len = soln.length; // this is a constant
int correct;
double[] result = new double[response.length];
for (int i = 0; i < response.length; i++) {
correct = 0;
if (len != response[i].length) {
throw new IllegalArgumentException("wrong exam");
}
for (int j = 0; j < response[i].length; j++) {
if (soln[j] == response[i][j]) {
correct ++;
}
}
result[i] = (double)(100 * correct) / response[i].length; // casting after math operation improve the performance
}
return result;
}
finally welcome to java :D
I'm trying to develop an algorithm in Java, which, given two matrices (let's say a and b), returns true if at least one row is identical in a and b.
Here's my attempt of method:
public static boolean check_row(int a[][], int b[][]){
boolean check = false;
for(int i = 0; i < a.length; i++){
for(int j = 0; j < b[0].length; j++){
if(a[i][j] == b[i][j])
check = true;
}
}
return check;
}
And here's a simple main:
public static void main(String[] args){
int a[][] = {{1,2}, {3,4}};
int b[][] = {{1,2}, {7,8}};
System.out.println(check_row(a, b));
}
Here I get true because first row of both matrices is the same.
But if I change the matrices initialization to this:
int a[][] = {{1,2}, {3,4}};
int b[][] = {{5,6}, {1,2}};
I get false, even though the first row of a and the second row of b are identical.
How should I modify the method in order to get true in both cases?
Your condition is too simple... High level idea is, that for each row from a and b pick a row and then identify whether it is the same, so you need 3 loops...
code:
public class SameRowFinder {
public static void main(String[] args){
int a[][] = {{1,2},{3,4}};
int b[][] = {{1,2}, {7,8}};
System.out.println(hasSameRow(a, b));
int aa[][] = {{1,2},{3,4}};
int bb[][] = {{5,6}, {1,2}};
System.out.println(hasSameRow(aa, bb));
}
private static boolean hasSameRow(int[][] a, int[][] b) {
for (int i = 0; i < a.length; i++) {
for (int j = 0; j < b.length; j++) {
if (isSameRow(a[i], b[j])) {
System.out.printf("Same rows are %d and %d (0-based).%n", i, j);
return true;
}
}
}
return false;
}
private static boolean isSameRow(int[] row1, int[] row2) {
if (row1.length != row2.length) {
throw new IllegalArgumentException("rows with different length");
}
for (int i = 0; i < row2.length; i++) {
if (row1[i] != row2[i]) {
return false;
}
}
return true;
}
}
Also you do not need to write your own function for array compare, but use Arrays.equal(int[], int[]), but it will just hide 3rd loop. Method above throws runtime exception in case of different length of arrays. It's definitelly worth look at Arrays.equal(int[], int[]) implementation for some tips (check for equality + null checks).
You have an error in your 2nd loop.
Change:
for(int j = 0; j < b[0].length; j++)
to
for(int j = 0; j < b.length; j++){
Further, the issue is that you cannot compare the rows like you do it.
You have to check that the rows have the same length and finally compare the rows. You will need an additional for loop for comparing the rows.
This one will do the trick:
public static boolean check_row(int a[][], int b[][]){
boolean check = false;
for(int i = 0; i < a.length; i++){
for(int j = 0; j < b.length; j++){
if (compareRows(a[i], b[j]))
check = true;
}
}
return check;
}
private static boolean compareRows(int[] row1, int[] row2) {
if (row1.length == row2.length) {
for (int i = 0; i < row2.length; i++) {
if (row1[i] != row2[i]) {
return false;
}
}
return true;
}
return false;
}
public static void main(String[] args){
int a[][] = {{1,2},{3,4}};
int b[][] = {{5,6}, {1,2}};
System.out.println(check_row(a, b));
}
In the example provided by OP, the loop over rows in b matrix was missing.
When learning, the algorithm can be written as follows:
public static boolean check_row(int a[][], int b[][]) {
int row_size = a[0].length;
for (int i = 0; i < a.length; i++) {
b: for (int j = 0; j < b.length; j++) {
for (int k = 0; k < row_size; k++) {
if (a[i][k] != b[j][k])
continue b; // move to next row in 'b' matrix
}
return true; // all elements in row were equal if we reached this point
}
}
return false;
}
In real life it would probably look like this:
public static boolean check_row(int[][] a, int[][] b) {
return Arrays.stream(b)
.anyMatch(rowB -> Arrays.stream(a).anyMatch(rowA -> Arrays.equals(rowA, rowB)));
}
i hope this code can help you
public static boolean check_row(int a[][], int b[][])
{
boolean check = false;
for(int i = 0; i < a.length; i++)
{
for(int k = 0 ; k< b.length ; k++)
{
for(int j = 0 ; j<b[0].length ; j++)
{
if(a[i][j]!=b[k][j])
{
break;
}//if even one cell were not similar in both a and b break
else
{
if(j==b[0].length-1)
{
check = true;
}//if you haven't broken the loop yet and if j went till the end
}//else if they are equal
}//j to go through columns
if(check == true)
{
break;
}//for bringing down the time complexity
}//k to go through b rows
if(check == true)
{
break;
}//for bringing down the time complexity
}//i
return check;
}
Hello I create a 2D array and i want to find the position from the first 2 in the array. And after to add the index in a new ArrayList. But this code doesn't work. Any idea for the problem?
import java.util.ArrayList;
class Test {
public static void main(String[] args) {
ArrayList<Integer> tableau = new ArrayList<Integer>();
int[][] tab = {
{1,1,1,1,1,1,2,1,1,2,1,1,1,2,1,2,1,1,1,1,1},
{1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,1,1},
};
for (int i = 0; i < tab.length; i++) {
int j = tab[i].indexOf(2);
for (int k = j ; k < tab[i].length; k++) {
if (tab[i][j] == 2){
tableau.add(j);
}
}
}
for (Integer row : tableau) {
System.out.println("row = "+ Arrays.toString(tableau));
}
}
}
As others have mentioned, regular arrays do not have an indexOf method, meaning that you will get an error when you compile.
However, you can easily create your own method to use as a substitute.
private static int indexOf(int value, int[] array)
{
for (int i=0; i<array.length; i++)
{
if (array[i] == value)
return i;
}
return -1;
}
Then you can just replace this line:
int j = tab[i].indexOf(2);
With this one:
int j = indexOf(2, tab[i]);
i have an array of integers like this one :
A={1,1,4,4,4,1,1}
i want to count the each number once , for this example the awnser is 2 becuase i want to count 1 once and 4 once
i dont want to use sorting methods
i am unable to find a way to solve it using java.
i did this but it gives me 0
public static void main(String args[]) {
int a[] = { 1,1,4,4,4,4,1,1};
System.out.print(new Test4().uniques(a));
}
public int uniques(int[] a) {
int unique = 0;
int tempcount = 0;
for (int i = 0; i < a.length; i++) {
for (int j = 0; j < a.length; j++) {
if (a[i] == a[j]) {
tempcount++;
}
}
if (tempcount <= 2) {
unique=a[i];
}
tempcount = 0;
}
return unique;
}
the purpose of the question is to understand the logic of it but not solving it using ready methods or classes
This one should work. I guess this might be not the most elegant way, but it is pretty straightforward and uses only simple arrays. Method returns number of digits from array, but without counting duplicates - and this I believe is your goal.
public int uniques(int[] a) {
int tempArray[] = new int[a.length];
boolean duplicate = false;
int index = 0;
int digitsAdded = 0;
for (int i = 0; i < a.length; i++) {
for (int j = 0; j < tempArray.length; j++) {
if (a[i] == tempArray[j]) {
duplicate = true;
}
}
if(!duplicate) {
tempArray[index] = a[i];
index++;
digitsAdded++;
}
duplicate = false;
}
//this loop is needed if you have '0' in your input array - when creating temp
//array it is filled with 0s and then any 0 in input is treated as a duplicate
//again - not most elegant solution, maybe I will find better later...
for(int i = 0; i < a.length; i++) {
if(a[i] == 0) {
digitsAdded++;
break;
}
}
return digitsAdded;
}
Okay first of all in your solution you are returning the int unique, that you are setting as the value that is unique a[i]. So it would only return 1 or 4 in your example.
Next, about an actual solution. You need to check if you have already seen that number. What you need to check is that for every number in the array is only appears in front of your position and not before. You can do this using this code below.
public int uniques(int[] a) {
int unique = 1;
boolean seen = false;
for (int i = 1; i < a.length; i++) {
for (int j = 0; j < i; j++) {
if (a[i] == a[j]) {
seen = true;
}
}
if (!seen) {
unique++;
}
seen = false;
}
return unique;
}
In this code you are iterating over the number you have seen and comparing to the number you are checking (a[i]). You know that for it to be unique you cant have seen it before.
I see two possible solutions:
using set
public int unique(int[] a) {
Set<Integer> set = new HashSet<>();
for (int i : a) {
set.add(i);
}
return set.size();
}
using quick sort
public int unique(int[] a) {
Arrays.sort(a);
int cnt = 1;
int example = a[0];
for (int i = 1; i < a.length; i++) {
if (example != a[i]) {
cnt++;
example = a[i];
}
}
return cnt;
}
My performance tests say that second solution is faster ~ 30%.
if restricted to only arrays, consider trying this:
Lets Take a temporary array of the same size of orignal array, where we store each unique letter and suppose a is your orignal array,
int[] tempArray= new int[a.length];
int tempArraycounter = 0;
bool isUnique = true;
for (int i = 0; i < a.length; i++)
{
isUnique = true;
for (int j = 0; j < tempArray.length; j++)
{
if(tempArray[j] == a[i])
isUnique = false;
}
if(isUnique)
{
tempArray[tempArraycounter] = a[i];
tempArraycounter++;
isUnique = false;
}
}
now tempArraycounter will be your answer ;)
Try Following code:
int test[]={1,1,4,4,4,1,1};
Set<Integer> set=new LinkedHashSet<Integer>();
for(int i=0;i<test.length;i++){
set.add(test[i]);
}
System.out.println(set);
Output :
[1, 4]
At the end set would contain unique integers.
I need to sort in ascending order as I add object to my generic class (I'm using strings).
I'm using selection sort, but it is not working.
I don't know if it is the correct way of doing this, so would appreciate the input.
OrderSet class
public class OrderSet<T extends Comparable> implements Set<T> {
private T[] items;
private int size;
public OrderSet()
{
items = (T[]) new Comparable[5];
}
#Override
public void add(T s)
{
if(size >= items.length)
{
items = grow(items);
}
for(int i = 0; i < items.length; i++)
{
if(items[i] == null)
{
items[i] = s;
size++;
break;
}
}
if(size > 1)
{
for (int i = 0; i < size-1; i++)
{
for(int j = 1; j < size; j++)
{
T tmp;
if (items[i].compareTo(items[j]) > 0)
{
tmp = items[i];
items[i] = items[j];
items[j] = tmp;
}
}
}
}
}
#Override
public void show()
{
for(T a : items)
{
if(a != null)
System.out.print(a+", ");
}
}
public T[] grow(T[] a)
{
T[] newA = (T[]) new Comparable[a.length+5];
System.arraycopy(a, 0, newA, 0, a.length);
return newA;
}
}
main
public class Main {
public static void main(String[] args) throws IOException
{
OrderSet<String> s1 = new OrderSet<>();
WordCount s2 = new WordCount();
Scanner input = new Scanner("the boy plays in the park with dog");
while (input.hasNext())
{
String w = input.next();
s1.add(w);
}
s1.show();
System.out.println();
}
}
I think it's your Sort Algorithm that is wrong. Ardentsonata is right, you use a Bubblesort algorithm but there is a mistake:
for (int i = 0; i < size-1; i++) {
for(int j = 1; j < size; j++){
T tmp;
if (items[i].compareTo(items[j]) > 0) {
tmp = items[i];
items[i] = items[j];
items[j] = tmp;
}
}
}
The Problem is the start value of the second loop, you want to check if any other element - except the ones you already sorted is bigger than the element you want to sort at the moment.
So your second loop needs this head:
for(int j = (i+1); j < size; j++)
so you really sort the array.
Otherwise you were uncontrollable switching your values aroung, because after you switched something to the second slot you switch it back in the next iteration.
Hope that helps !
What you seem to be doing is a bubble sort as you add in items, the generic form of a selection sort is as follows:
for(int i = 0; i<arr.length - 1; i++)
{
int smallest = i;
for(int j = i + 1; j< arr.length; j++)
{
if(arr[j].compareTo(arr[smallest]) > 0)
smallest = j;
}
if(smallest < arr.length && smallest != i)
swap(arr[i], arr[smallest]);
}
You could do it swapping the largest into the last index, but this should work as well. Note, swap is just a placeholder psuedocode for the actual swapping.
Use java.util.TreeSet< T >, which implements SortedSet< T >.
It's better to use String compare concept in this case
class City {
public static void main (String args[])
{
int i,j;
String temp;
String s[] = new String[6];
for(i=0; i<6; i++)
s[i]=args[i];
for(i=0;i<6;i++){
for(j=0;j<6-i-1;j++){
if(s[j].compareTo(s[j+1])>0)
{
temp=s[j];
s[j]=s[j+1];
s[j+1]=temp;
}
}
}
for(i=0; i<6; i++)
{
System.out.println(s[i]);
}
}}