I have a problem with removig duplicate elements from an array in Java. I made two extra functions, one which counts how many unique elements there are and one which checks if the integer is already in the result array. Everything seems to work, but I fail a test where 0 is supposed to be 2nd in the array, but it's always moved to the end in my code. What can I do to fix this mistake?
Tester is showing this error:
Expected :is [<100>, <0>, <3>, <4>, <562>]
Actual :[<100>, <3>, <4>, <562>, <0>]
This is my code so far:
public static int[] removeDuplicates(int[] integers) {
int count = countUniques(integers);
int counter = 0;
int[] result = new int[count];
for (int integer : integers) {
Boolean isInArray = isInArray(result, integer);
if (!isInArray) {
result[counter] = integer;
counter++;
}
}
return result;
}
public static int countUniques(int[] integers) {
int i, j;
int count = 0;
for (i = 0; i < integers.length; ++i) {
for (j = 0; j < i; j++)
if (integers[i] == integers[j])
break;
if (i == j)
count++;
}
return count;
}
public static Boolean isInArray(int[] integers, int targetInteger) {
for (int integer : integers) {
if (targetInteger == integer) {
return true;
}
}
return false;
}
When you create a primitive int array it is by default filled with 0s. You can change your code to use an Integer object array. That way the default value for each element will be null.
You would then need to null check each element inside your isInArray():
public static Boolean isInArray(Integer[] integers, int targetInteger) {
for (Integer integer : integers) {
if (integer != null && targetInteger == integer) {
return true;
}
}
return false;
}
And change your result array to Integer[] result = new Integer[count]; and return Integer[] instead of int[].
If you want to return primitive array you can use streams and map Integer to int.
something like
return Arrays.stream(result).mapToInt(i-> i).toArray();
You haven't filled up the result array yet, so the end of it will be filled with zeros. You only want to loop over the part that you have filled. One way to achieve this is to pass the value of counter to your isInArray method.
public static int[] removeDuplicates(int[] integers) {
int count = countUniques(integers);
int counter = 0;
int[] result = new int[count];
for (int integer : integers) {
Boolean isInArray = isInArray(result, counter, integer);
if (!isInArray) {
result[counter] = integer;
counter++;
}
}
return result;
}
public static int countUniques(int[] integers) {
int i, j;
int count = 0;
for (i = 0; i < integers.length; ++i) {
for (j = 0; j < i; j++)
if (integers[i] == integers[j])
break;
if (i == j)
count++;
}
return count;
}
public static Boolean isInArray(int[] integers, int integersLength, int targetInteger) {
for (int i = 0; i < integersLength; i++) {
if (targetInteger == integers[i]) {
return true;
}
}
return false;
}
If you need to remove duplicates from an array, probably the simplest thing to do is to convert the array to a java.util.Set and then convert the set back to an array.
public int[] removeDups(int[] arr) {
Set<Integer> noDups = new HashSet<>(Arrays.stream(arr).boxed().collect(Collectors.toList()));
int[] newArr = noDups.stream().mapToInt(Integer::intValue).toArray();
return newArr;
}
This simplifies the process and eliminates additional issues like the one you are having with creating an array padded with zeros for the unused array index locations.
To count "unique", call this method and then return the created collection's size:
public int countUnique(int[] arr) {
return removeDups(arr).length;
}
This solution does not require the method isInArray; which by the way, should not be a public method. In my opinion, public methods should not invoke other public methods. The reason being is that requirement's change might cause the method with the dependency to break.
Related
I've array of N integers in not-decreasing order. Need to find any specific element in array, if found then return the position of that array otherwise returns -1
public static int find(int[] v, int bb) {
int N = v.length;
if (N == 0) {
return -1;
}
int l = 0;
int r = N - 1;
while (l < r) {
int m = (l + r) / 2;
if (v[m] > bb) {
r = m - 1;
} else {
l = m;
}
}
if (v[l] == bb) {
return l;
}
return -1;
}
there's one bug I need to find out, which is about that this will not work for some inputs. I gave up.
Any suggestions ?
If you want to locate the index of the first specific numerical element within the array then you can do something like this:
public static int find(int[] v, int bb) {
int found = -1;
for (int i = 0; i < v.length; i++) {
if (v[i] == bb) {
found = i;
break;
}
}
return found;
}
If there are multiple values in the array that are the same as bb then the method above will only provide the first one found. If you want to return the index values for all values of bb found in the array then you would want to return an array of index values, for example:
public static int[] find(int[] v, int bb) {
List<Integer> list = new ArrayList<>();
int found = -1;
for (int i = 0; i < v.length; i++) {
if (v[i] == bb) {
found = i;
list.add(found);
}
}
if (found == -1) {
list.add(found);
}
return list.stream().mapToInt(d -> d).toArray();
}
The List Interface is used in the above example because it can grow dynamically since we have no idea how many values of bb are actually going to be contained within the Array. The List is converted to an int[] array before it is returned.
First of all, I think you should name your variables with a proper name, and not just with a single characters, it'll make your code easier to understand.
Second, you are using a binary serach algorithm for increasing ordered arrays, if you want that code to work correctly you have to use an increasing ordered array. Here you have a binary search method that should work with increasing ordered arrays:
public static int binarySeacrh(int [] list, int numSearched) {
boolean found = false;
int start = 0;
int end = list.length - 1;
int pos = -1;
while(start <= end && !found){
int middle=((start + end) / 2);
if (numSearched == list[middle]){
found = true;
pos = middle;
}
else if (list[middle] < numSearched){
start = middle + 1;
}else{
end = middle - 1;
}
}
return pos;
}
If you want to search for the position in a unordered array, you must use another type of serach algorithm or order the array first.
I have this function and I need to optimise it so that it takes less time running:
public static int recherche(int cherche, int[] t) {
int srch = 0;
int tmp=0;
boolean result = false;
for (int i=0; i<t.length ; i++) {
if (t[i]== cherche && result == false) {
tmp++;
srch = i;
result=true;
}
}
if (tmp!=0) {
return srch ;
}
else {
return -1;
}
}
Also I can't use any library tools.
If I understand your method correctly you are searching for the index of the first occurrence of cherche in your array t, or -1 if not found.
The problem with your code is, that you keep looping even if you already found the entry. It is better to break the loop immediately. You also do not need the extra variables.
public static int recherche(int cherche, int[] t) {
int srch = -1;
for (int i = 0; i < t.length; i++) {
if (t[i] == cherche) {
srch = i;
break;
}
}
return srch;
}
If this is still too slow, you could try to store the data sorted or create some kind of index.
If you had a List instead of an Array, you could use the indexOf method, but I do not think it can be any faster for unsorted data.
It will be always O(n), because you have to check all array values in the worst case.
P.S: Please consider to use better variable names. I have no idea what t and cherche are.
There is no real optimization that can be done with this function in Java. If you know that the array t is sorted, you could use binary sort.
I cleaned your code up a bit though
public static int recherche(int cherche, int[] t) {
for (int i = 0; i < t.length; i++) {
if (t[i] == cherche) {
return i;
}
}
return -1;
}
The optimizations you can do are returning the result right after you found it and removing redundant variables.
public static int research(int searched, int[] t) {
for (int i=0; i < t.length ; i++) {
if (t[i] == searched) {
return i;
}
}
return -1;
}
I have a problem and the title actually sums it up perfectly. So i'll just go ahead and show you the code snippet.
So the methode generate, is generating an array, that is filled with numbers between 1 and 1000, including both. The length of the array is user input.
The next method, isPrime, is gonna conclude if its a prime number, so i can use those numbers with the true condition in another method. The generate method works but in isPrime i always get errors. If u can think of a better way, let me know please.
static int[] generate(int n) {
int[] arr = new int[n+1];
for(int x = 0; x <= n; x ++) {
int number = (int) (Math.random()* 999)+1;
arr[x] = number;
}
return arr;
}
static int isPrime(int p, final int q[]) {
boolean itIs = true;
//final int[] arr;
for(int r = 0; r <= p; r++) { // here it somehow states r is deadCode
for(int j = 2; j < q[r]; j++) {
if(q[r]%j == 0) {
itIs = false;
}
}
return q[r];
}
}
First, create a method to check a value is prime:
public boolean isPrime(int value) {
for (int i = 0; i < value / 2; i++) { // value / 2 is enough, doesn't need to check all values
if (value % i == 0) {
return false;
}
}
return true;
}
Then you check each value of array and put prime value to new array:
public int[] filterArray(int[] array) {
List<Integer> intList = new ArrayList<>();
for (int i = 0; i < array.length; i++) {
if (isPrime(array[i])) {
intList.add(array[i]);
}
}
Integer[] integerArray = intList.toArray(new Integer[intList.size()]);
int[] intArray = ArrayUtils.toPrimitive(integerArray);
return intArray;
}
Then you get the filtered prime array.
I have to create a method that takes in an array and value as arguments and returns a new array with the specified value removed.
Here's my attempt:
public static int[] remove(int[] nums,int value){
int[] after = new int[nums.length-1];
for (int i = 0; i < nums.length; i++) {
if (!(nums[i] == value)) {
after[i] = nums[i];
}
}
nums = after;
return nums;
}
The code throws
ArrayIndexOutOfBoundsException
bur I don't know why.
First you need to find how big the new array is, after you can populate the new array without the value to remove. There are better ways to do this, but this is to get you started.
public static int[] remove (int[] nums, int value)
{
int[] after;
//find out the length of the array
int count = 0;
for (int num : nums)
{
if (num != value)
{
count++;
}
}
after = new int[count];
//add all the elements except the remove value
int i = 0;
for (int num : nums)
{
if(num != value)
{
after[i] = num;
i++;
}
}
return after;
}
KISS. It's a 1-liner:
public static int[] remove(int[] nums, int value){
return IntStream.stream(nums).filter(i -> i != value).toArray();
}
Code is trying to copy values from original array to new array leaving a blank or space(value 0) in place of targeted value. The error ArrayIndexOutOfBoundsException is showing because you are initialising the after with nums.lenth-1 int[] after = new int[nums.length-1];
You can change that or swap the targeted element with the last element and copy entire array except the last.
public static int[] remove (int[] nums,int value){
int[] after = new int[nums.length-1];
for(int i = 0; i < nums.length; i++) {
if((nums[i] == value)) {
//changing the target value with the last value of nums array
nums[i]=nums[nums.length-1];
nums[nums.length-1]=value;
}
}
//Copying the entire array except the last
for(int i=0;i<nums.length-1;i++){
after[i]=nums[i];
}
return after;
}
And I am assuming that there is only one target element
Ths is a question from a past paper. I have been asked to create a static method arrayMin to find the smallest value in the array arr.
I have to use a while loop and on each iteration, the variable min will return the smallest number from the first i elements.
Is there a way to do this without calling another method/for loop and strictly using the while loop, as the question is only worth 4%(including writing loop invariants and javadoc). Not sure if I am overcomplicating the problem.
public class Revision {
public static int arr[] = new int[] { 5, 8, 4, 3, 6, 2 };
public static int min = 1;
public static int arrayMin() {
int i = 0;
if (arr == null) {
return 0;
} else {
while (i < arr.length) {
// some function/method call to find smallest number of arr[i]
i++;
return min;
}
}
return min;
}
public static void main(String[] args) {
System.out.println(arrayMin());
}
}
A couple of things:
The array shouldn't be static, you should pass it as a parameter to the arrayMin method;
min should be a local arrayMin variable, not static;
min should be initialized to Integer.MAX_VALUE. If you initialize it with 1, and 2 happens to be the min value of the array, you'll never return it;
You can't return multiple times from a method. As soon as you do return min, the method ends. There's probably some confusion over the the variable min will return the smallest number from the first i elements phrase. It probably means that in each iteration, the variable min will have (not return) the smallest number from the first i elements.
Here's a refactor:
public static int arrayMin(int[] arr) {
int i = 0;
int min = Integer.MAX_VALUE;
if (arr == null) {
return 0; // What if 0 is the minimum value? What do you want to do in this case?
} else {
while (i < arr.length) {
if (arr[i] < min) {
min = arr[i];
}
i++;
}
}
return min;
}
You need to have a variable outside of the loop called min. You will use the loop to find the minimum of the array, and return min when the loop is complete.
} else {
int min = Integer.MAX_VALUE;
while(i < arr.length) {
// is arr[i] < min? If so, it's the new minimum
i++;
}
return min;
}
multiple ways to do it, but here is one.
public static int arrayMin(int[] arr) {
boolean isFirstElement = true;
int smallestNumber= 0;
int index = 0;
while(index < arr.length) {
int temp= arr[index];
index++;
if (isFirstElement) {
smallestNumber = temp;
isFirstElement = false;
} else if (smallestNumber > temp) {
smallestNumber = temp;
}
}
}
You can use a index variable to keep in track of the number of positive hits and if the corresponding numbers index value is one lesser the array size, that number is the smallest
class testtt{
static int small=0;
public static void main(String[] args) {
int arr[] = {9,2,3,4,5,6,7,8};
int i,index=0;
for(int q:arr)
{
for(i=0;i<arr.length;i++)
{
if(q<arr[i])
{
small=q;
index++;
}
}
if(index==arr.length-1)
System.out.println(small);
}
}
}