Finding occurrences of element before and after the element in Array - java

I am writing a algorithm:
In this algorithm, if an array contains the element 3, the element 3 cannot be between two 1 elements, like this:
int array={5, 2, 10, '3', 15, '1', 2, 2} //the ' symbols are just for highlighting the elements in question.
The above array contains the element 3, and note that before 3 there is no element 1.
But after element 3 there is one element 1, and in this case it should return True.
It should return true because the element 3 is not "surrounded" by two elements 1.
int array={'3',2,18, >'1' ,0,# 3 #,-11, '1'< ,'3'} //',<,# symbols are just highlighting caracteres.
In this array after first element of 3 there is two elements 1, surrounding an element 3, so it should return False.
I have tried following code:
public class Third
{
public static void main(String[] args)
{
int[] array = {1, 2, 4, 3, 1}; //should return false, '3' contained in '1' elements.
for(int i=0; i<array.length; i++)
{
if(array[i]==3)
{
for(int j=0;j<array[i];j++)
{
if(array[j]==1)
{
System.out.println("I foud One before "+array[j]);
}else
{
break;
}
System.out.println("yes i found the array:"+array[i]);
}
for(int z=0;z>array[i];z++)
{
if(array[z]==1)
{
System.out.println("I found after 3 is :"+array[z]);
}
break;
}
}
}
}
}
I am not getting exact result from my above code which i want.

According to your question, if you are just solely trying to check whether 3 is surrounded by 1s, you can do this. This is according to your question of assuming that you will have no multiple 3s in your array.
public static void main(String[] args)
{
int[] array = {3,1,2,4,3,1,3,1};
int posOfThree = 0;
int posOfFirstThree = 0;
boolean noLeft = true;
boolean noRight = true;
boolean firstThreeFound = false;
//Get position of 3
for (int x=0; x<array.length; x++)
{
if (array[x] == 3)
{
if (firstThreeFound == false)
{
posOfFirstThree = x; //Position of the first occurred 3
firstThreeFound = true;
}
posOfThree = x; //Position of the last occurred 3
}
}
//Check if there is 1 on left hand side of first 3
int left = 0;
while (posOfFirstThree - left > 0)
{
left ++;
if (array[posOfFirstThree-left] == 1)
noLeft = false;
}
//Check if there is 1 on right hand side of last 3
int right = 0;
while (posOfThree + right < array.length-1)
{
right ++;
if (array[posOfThree + right] == 1)
noRight = false;
}
System.out.println("Outcome: " + (noLeft || noRight));
}
Program Output: Outcome: True
Since you can only use normal loops and simple array to do this. This is simple enough to suit your requirements. Certainly, I believe this solution can be further improved, however, this code can get exactly what you need (even if you increase or decrease the array size).
EDIT: The edited version can handle multiple 3s in the array and check whether all 3s are surrounded by 1s.

How about simply iterating over the array?:
List<Integer> nums = new ArrayList<>();
List<Integer> target = new ArrayList<>(Arrays.asList(new int[]{1, 3, 1}));
for (int i : array) {
if (i == 3 || i == 1) {
nums.add(i);
}
}
return Collections.indexOfSubList(nums, target) >= 0;
Alternatively, with regex:
int test[] = {1, 5, 3, 2, 5, 67, 8, 1};
return Arrays.toString(test).matches(".*1.*3.*1.*"); //greedy search

public class Third {
public static void main(String[] args){
int[] array = {1,2,4,3, 1};
for(int i=0;i<array.length;i++)
{
if(array[i]==3)
{
for(int j=0;j<=i;j++)
{
if(array[j]==1)
{
System.out.println("I foud One before "+array[j]);
}else
{
break;
}
System.out.println("yes i found the array:"+array[i]);
}
for(int z=i;z>array.length;z++)
{
if(array[z]==1)
{
System.out.println("I found after 3 is :"+array[z]);
}
break;
}
}
}

Related

Boolean assignment not catching, need to understand more

public class MyClass {
public static void main(String args[]) {
int[] nums = {1, 2, 9, 3, 4};
boolean results = false;
int end = nums.length;
if (end>4)end=4;
for (int x=0;x<end;x++)
{
System.out.println(nums[x]);
results = (nums[x] == 9);
}
System.out.println(results);
}
}
The following code checks to see if a 9 is present in the first 4 elements of an array, yet using the boolean operator in this fashion seems to always fail if there are not more than 1 "9" in the first 4 elements of the array.
Why is this? Logically it seems that this should work, and it really helps me to understand better when I understand why something doesn't work.
The reason is that you have itetate all the elements,the result will be the result of the last element,
So you need to stop for when you find the match result
for (int x=0;x<end;x++)
{
System.out.println(nums[x]);
if(nums[x] == 9){
result = true;
break;
}
}
You overwrite results every time. As written, this'll tell you whether the last item in the array equals 9 (which it doesn't), not whether any item in the array equals 9.
You should assign true to result if num[x] == 9; otherwise, don't assign anything.
#lucumt's answer shows an example of how to do that. One other example, just replace
results = (nums[x] == 9);
with
results |= (nums[x] == 9);
where the |= assignment is equivalent to results = results || (num[x] == 9); - in other words, if any value is true, the entire expression will be true. (Note that #lucumt's answer is slightly more efficient because it's O(n) whereas this is Theta(n) - i.e. this will always run exactly n times, where n is the length of the list, but #lucumt's can end the loop early if it finds any 9).
In your for loop you are over writing the value each time. This means you are testing if the 4th value is equal to 9.
you can solve your problem like so:
boolean results = false;
for (int x = 0; x < end; x++) {
System.out.println(nums[x]);
if(nums[x] == 9) {
results = true;
break;
}
}
Try this:
boolean isPresent(int[] nums, int val)
{
for (int x : nums )
{
if (nums[x] == val)
return true;
}
return false;
}
Otherwise you rewrite a value every time you're checking
I wrote you a class. The method nignPresentInFirst4Elements(int[] arr) returns true if the given array contains a 9 in one or more of it's first 4 elements:
public class Test {
private static boolean nignPresentInFirst4Elements(int[] arr) {
if(arr == null)
return false;
for(int i = 0; i < Math.min(arr.length, 4); i++) {
if(arr[i] == 9)
return true;
}
return false;
}
public static void main(String[] args) {
int[][] arrs = new int[][] {
{5, 8, 9, 3},
{5, 8, 9, 3, 8, 26},
{5, 8, 9, 9},
{5, 8, 23, 0}
};
for(int i = 0; i < arrs.length; i++) {
System.out.println(toString(arrs[i]) + " | " + nignPresentInFirst4Elements(arrs[i]));
}
}
private static String toString(int[] arr) {
if(arr == null)
return "null";
String s = "[";
if(arr.length > 0)
s += arr[0];
for(int i = 1; i < arr.length; i++) {
s += ", " + arr[i];
}
s += "]";
return s;
}
}

JAVA specific loop over Array 2D

I have this array :
int[][] multi = new int[][]{
{ 3, 4, 2},
{ 2, 2, 5 },
{ 1, 2 }
};
I would like to print the produce of each cells. It's pretty hard to explain so lets see some example :
For my table i need to print :
6 //(3*2*1)
12 //(3*2*2)
6 //(3*2*1)
12 //(3*2*2)
15 //(3*5*1)
30 //(3*5*2)
8 //(4*2*1)
16 //(4*2*2)
8 //(4*2*1)
16 //(4*2*2)
20 //(4*5*1)
40 //(4*5*2)
...
Size of table can change, i need a generic things.
Here is my start but it's not doing what i need. This is looping line by line...
for (int i = 0; i<multi[0].length; i++) {
for (int k = 0; k < multi.length; k++) {
for (int l = 0; l < multi[k].length; l++ ) {
System.err.println(multi[k][l]);
}
}
}
I thing you have to do that recursively if your dimensions of array is not fixed..
I came up the code for dynamic dimension of 2D array
public class HelloWorld{
static int[][] multi = new int[][]{
{ 3, 4, 2},
{ 2, 2, 5 },
{ 1, 2 }
};
static public void pattern(int row,int multip) {
if(row >= multi.length) {
System.out.println(multip);
return ;
}
for(int i = 0; i<multi[row].length;i++) {
multip*=multi[row][i];
row+=1;
pattern(row,multip);
row-=1;
multip/=multi[row][i];
}
}
public static void main(String []args){
pattern(0,1);
}
}
If your dimensions are fixed then you can also do that using above logic but for that if you want to do iterative then you have to repeatedly create loops inside loop.
It's not hard to explain if you use mathematics terms and what you need is simply a Cartesian product of the sets (i.e. each row) in your bidimensional array.
It could be a bit longer to explain here the theory about Cartesian product (X is the operator) but in practice you have to calculate the result of:
((multi[0] X multi[1]) X ...) X multi[n]
And you ends with a bidimensional array with a number of rows which is the product of all the cardinality of each set and each row has a number of elements which is the number of the sets (because each tupla has an element from each set).
Another thing is that the tuple are ordered i.e. the element of a set will be in the same position in all the tuples e.g. each tupla in position 0 will have an element of multi[0].
Knowing these properties is possible to create the product with a construction algorithm which puts the elements of the first set in the first column of the resulting set repeating them the necessary amount of time and then go on with the next set/next column.
At the end when you have your Cartesian product you can do anything you want e.g. calculate the product of the elements of each row.
public class CartesianProductProduct {
public int[][] product(int[][] sets) {
int cardinality = 1;
for (int is = 0; is < sets.length; is++) cardinality *= sets[is].length;
int[][] cartesianProduct = new int[cardinality][sets.length];
int curCardinality = 1;
for (int is = 0; is < sets.length; is++) {
curCardinality *= sets[is].length;
int repetition = cardinality / curCardinality;
int ie = 0;
for (int ic = 0; ic < cardinality; ic++) {
cartesianProduct[ic][is] = sets[is][ie];
if (repetition == 1) {
ie++;
} else if ((ic + 1) % repetition == 0) {
ie++;
}
ie = ie == sets[is].length ? 0 : ie;
}
}
return cartesianProduct;
}
public static void main(String[] args) {
int[][] multi = new int[][]{
{3, 4, 2},
{2, 2, 5},
{1, 2}
};
int[][] cartesianProduct = new CartesianProductProduct().product(multi);
for (int i = 0; i < cartesianProduct.length; i++) {
int prod = 1;
String s = "";
String sep = "";
for (int k = 0; k < cartesianProduct[i].length; k++) {
prod *= cartesianProduct[i][k];
s = s + sep + cartesianProduct[i][k];
sep = "*";
}
System.out.printf("%s //(%s)\n", prod, s);
}
}
}

How to check if the sequence of elements of an array appear in another given array? [duplicate]

I'm in my schools ap computer science class and I'm stuck on this one problem. and cant really even really come up with an idea on how to solve it.
Here it is word for word:
Write a static method named contains that accepts two arrays of integers a1 and a2 as parameters and that returns a boolean value indicating whether or not a2's sequence of elements appears in a1 (true for yes, false for no). The sequence of elements in a2 may appear anywhere in a1 but must appear consecutively and in the same order. For example, if variables called list1 and list2 store the following values:
int[] list1 = {1, 6, 2, 1, 4, 1, 2, 1, 8};
int[] list2 = {1, 2, 1};
Then the call of contains(list1, list2) should return true because list2's sequence of values {1, 2, 1} is contained in list1 starting at index 5. If list2 had stored the values {2, 1, 2}, the call of contains(list1, list2) would return false because list1 does not contain that sequence of values. Any two lists with identical elements are considered to contain each other, so a call such as contains(list1, list1) should return true.
You may assume that both arrays passed to your method will have lengths of at least 1. You may not use any Strings to help you solve this problem, nor methods that produce Strings such as Arrays.toString.
If someone could point me in the right direction that would be great.
also here's one attempt i came up with but it doesn't have a sufficient number of tests
public static boolean contains(int[] set1, int[] set2) {
boolean contains = false;
for (int i = 0; i < set1.length; i++) {
for (int a = 0; a < set2.length - 1; a++) {
if (set1[i] == set2[a] && set1[i + 1] == set2[a + 1]) {
contains = true;
} else {
contains = false;
}
}
}
return contains;
}
Here's a recursive way to do this:
public static boolean contains(int[] set1, int[] set2) {
//System.out.println(Arrays.toString(set1) + " " + Arrays.toString(set2));
//set 2 cannot be contained within set 1 because there aren't
//enough elements. This either means that we recursed too deep
//within the first set that there are not enough elements, or
//there were not enough elements to begin with.
if (set1.length < set2.length) return false;
//from the start of each set, count the number of matches in order
int numMatched = 0;
while (numMatched < set2.length && set1[numMatched] == set2[numMatched]) {
numMatched++;
}
if (numMatched == set2.length)
//the number of matches found equals the length of the set to
//search for, so we have found a match. Return true to unravel
//the recursion.
return true;
else {
//we didn't find a match, so shift the array by 1 and then
//recursively call this function to compare again.
int[] subset = Arrays.copyOfRange(set1, 1, set1.length);
return contains(subset, set2);
}
}
Each time we fail to find the matching sequence, we create a subset of the array, excluding the first element, and pass that back to contains to continue the checks.Here is an output of each iteration:
First time: set1 =
[1, 6, 2, 1, 4, 1, 2, 1, 8] and set2 = [1, 2, 1]
No match is found at the beginning of the array (we break out when comparing 6 and 2. The next recursive call is this:
set1=
[6, 2, 1, 4, 1, 2, 1, 8], [1, 2, 1]
the next recursion compares [2, 1, 4, 1, 2, 1, 8] [1, 2, 1]
and so on until the final recursion compares:
[1, 2, 1, 8] [1, 2, 1] and finds the match in order.
For consecutive
public static boolean contains(int[] set1, int[] set2) {
OUTER:
for (int i = 0; i < set1.length - set2.length; i++) {
for (int j = 0; j < set2.length; j++) {
if (set1[i + j] != set2[j])
continue OUTER;
}
return true;
}
return false;
}
To avoid a label you can use a method which might be clearer
public static boolean contains(int[] set1, int[] set2) {
for (int i = 0; i < set1.length - set2.length; i++)
if (!matches(set1, i, set2))
return false;
return true;
}
public static boolean matches(int[] set1, int off, int[] set2) {
for (int j = 0; j < set2.length; j++)
if (set1[off + j] != set2[j])
return false;
return true;
}
If it only needs to be in order
public static boolean contains(int[] set1, int[] set2) {
for (int i = 0, j = 0; i < set1.length; i++)
if (set1[i] == set2[j])
if (++j >= set2.length)
return true;
return false;
}
I would say that as far as the mentality, you should think "work the first element against the array until a match".
public static boolean contains(int[] set1, int[] set2) {
for (int i = 0; i < set1.length; i++) {
int count = 0;
for (int w = 0; w < set2.length; w++) {
if (set2[w] == set1[i + w]) {
count++;
} else {
count = 0;
continue;
}
}
if (count == set2.length) {
return true;
}
}
return false;
In this sense, you will only advance as far down your second array for comparison as needed. If, after going through all the elements in set2, you end up with the same length, then it's contained within set1. And of course, ask if you have questions :)
Start with int first=list2[0]; then find that number in list1. Next, loop over all values in list2 and simultaneously loop through list1 from the previously-found position until either the entire list2 is verified present in list1 or a discrepancy is found. Restart with first after the previously-found location if a discrepancy is found.
Shamelessly copying another answer with a tweak:
public static boolean contains(int[] set1, int[] set2) {
for (int i = 0, j = 0; i < set1.length; i++) {
if (set1[i] == set2[j]) {
if (++j >= set2.length)
return true;
}
else {
i -= j;
j = 0;
}
}
return false;
}
This consecutive-version mechanism also ensures that no overruns occur without any extra checks.
Demo of this answer at IDEOne.com
I came up with the following function. Read the comments to understand the logic behind it:
public static boolean contains(int[] a, int[] b) {
//Loop until there aren't enough elements left in a to match b.
for (int i = 0; i < a.length - b.length + 1; i++) {
for (int j = 0; j < b.length; j++) {
//If the jth element of b doesn't match
//the corresponding element of a, then move
//to the next step in the sequence.
if (a[i + j] != b[j])
break;
//If we are at the end of the loop, return
//true because that means we found a consecutive match.
if (j == b.length - 1)
return true;
}
}
return false; //If we got here, there are no matches.
}
I thought about it and came up with this solution:
static boolean contains(final int[] list1, final int[] list2) {
final int limit = list1.length - list2.length + 1; // we do not need to check an index >= limit, because list2 wouldn't fit anymore at this point
for (int indexL1 = 0, indexL2 = 0; indexL1 < limit; ++indexL1) {
while (list1[indexL1 + indexL2] == list2[indexL2]) { // check all matches from here
++indexL2;
if (indexL2 == list2.length) { // if all of list2 matched so far, we found it
return true;
}
}
indexL2 = 0; // we did not find it, start from beginning of list2 again
}
return false; // no match found
}
I call it the Lawrey-Solution.

How to find if any values in array add up to n

I have an array of random values, and a target value.
#!/bin/bash
objective='50'
declare -a values=(1 2 2 6 8 14.5 15 28.7 .. 42)
I need to find a way to extract any combination of numbers in the array 'values' that add up to 50
The array has duplicates, and floating point integers.
A solution set might look like:
50 = 42 + 8
50 = 42 + 6 + 2
Initially I started in bash with some nested for loops, however I'm quickly realizing that this will grow exponentially with my array length.
I took a couple of java classes in college, but I'm still inexperienced in programming. I'm starting to think this may require recursion.
Can anyone with more programming experience point me in the right direction?
Besides nested for loops, how else could you approach this problem?
Here is an algorithm that has time complexity O(M*N) whereas M is Target and N is total size of set. Use analogy with knapsack problem as follows :-
Knapsack capacity = Target
Items are elements in the set with weight & value same as itself
Calculate maximum profit using dynamic programming
maxprofit = Target then there is/are subset which sum up to target.
Retrace the solution.
Java Solution for the same :-
public class SubSetSum {
static int[][] costs;
public static void calSets(int target,int[] arr) {
costs = new int[arr.length][target+1];
for(int j=0;j<=target;j++) {
if(arr[0]<=j) {
costs[0][j] = arr[0];
}
}
for(int i=1;i<arr.length;i++) {
for(int j=0;j<=target;j++) {
costs[i][j] = costs[i-1][j];
if(arr[i]<=j) {
costs[i][j] = Math.max(costs[i][j],costs[i-1][j-arr[i]]+arr[i]);
}
}
}
System.out.println(costs[arr.length-1][target]);
if(costs[arr.length-1][target]==target) {
System.out.println("Sets :");
printSets(arr,arr.length-1,target,"");
}
else System.out.println("No such Set found");
}
public static void printSets(int[] arr,int n,int w,String result) {
if(w==0) {
System.out.println(result);
return;
}
if(n==0) {
System.out.println(result+","+arr[0]);
return;
}
if(costs[n-1][w]==costs[n][w]) {
printSets(arr,n-1,w,new String(result));
}
if(arr[n]<=w&&(costs[n-1][w-arr[n]]+arr[n])==costs[n][w]) {
printSets(arr,n-1,w-arr[n],result+","+arr[n]);
}
}
public static void main(String[] args) {
int[] arr = {1,2,3,8,9,7};
calSets(10,arr);
}
}
I would do it like this:
1.some init
const int N=array size;
int val[N]; // input data
bool flag[N]; // is val used ?
for (int i=0;i<N;i++) flag[i]=false;
sort val[] descending
2.create function bool find_sum(int s);
if it found solution returns true else false
set flag to true for all used values
{
for (int i=0;i<N;i++) // find first usable big number (could be faster with binary search or with tailing last used i index into recursion)
if ((val[i]<=s)&&(!flag[i]))
{
flag[i]=true; // flag it as used
if (val[i]==s) return true; // try to find reminder
if (find_sum(s-val[i])) return true; // if found return true
flag[i]=false; // else unflag val[i] and continue winth next number
}
return false; // if sum not found then return false
}
3.after find_sum(s) your sum consists of all val[i] where flag[i]!=false
[edit1] functional source tested even for your case [6,5,5] and sum=10 it is OK
//---------------------------------------------------------------------------
int find_sum(int *val,int *use,int N,int sum,bool init=true)
{
int i;
if (init)
{
for (i=0;i<N;i++) use[i]=0; // nothibg used yet
for (int e=1;e;) // bubble sort
for (e=0,i=1;i<N;i++)
if (val[i-1]<val[i])
{ e=val[i-1]; val[i-1]=val[i]; val[i]=e; e=1; }
}
for (i=0;i<N;i++) // find first usable big number (could be faster with binary search or with tailing last used i index into recursion)
if ((val[i]<=sum)&&(!use[i]))
{
use[i]=1; // val[i] is used
if (val[i]==sum) return 1; // try to find reminder
if (find_sum(val,use,N,sum-val[i],false)) return 1; // if found return true
use[i]=0; // else val[i] is unused and continue winth next number
}
return 0; // if sum not found then return false
}
//---------------------------------------------------------------------------
void main()
{
int in[]={6,5,5}; // input data
const int N=sizeof(in)/sizeof(int);
int ret,out[N];
if (find_sum(in,out,N,10))
for (int i=0;i<N;i++)
if (out[i])
{
cout << in[i] << " ";
}
}
//---------------------------------------------------------------------------
PS. in your question in the input array are also floating point values
so you have to change int val[],sum to float/double
and add some accuracy for sum comparison to work with floats
if (val[i]==sum) return 1;
change to
if (fabs(val[i]-sum)<1e-10) return 1;
or use any other accuracy instead of 1e-10
You can use recursion yes, you can break the array into sub-parts (I use List).
Start from 0th index of the Parent list and a blank list
Iterate over to subList your Parent from i+1 to the end and thereby increasing your working list from 0 to i
Check for the sum (calculated) equals your objective
Code:
static Integer[] array = { 1, 2, 2, 6, 8, 14, 15, 28, 30, 32, 12, 48, 6, 42 };
static int objective = 50;
public static void main(String args[]) {
add(new ArrayList<Integer>(Arrays.asList(array)),
new ArrayList<Integer>());
}
public static void add(List<Integer> digits, List<Integer> workingList) {
for (int i = 0; i < digits.size(); i++) {
// New sublist to store values from 0 to i
List<Integer> list = new ArrayList<Integer>(workingList);
list.add(digits.get(i));
// Here you call this recursively with your Parent list from i+1
// index and working list from 0 to i
add(digits.subList(i + 1, digits.size()), list);
}
int sum = 0;
for (int element : workingList) {
sum += element;
}
if (sum == objective) {
System.out.println(objective + " = "
+ Arrays.toString(workingList.toArray()));
}
}
Output:
50 = [1, 2, 2, 15, 30]
50 = [1, 2, 6, 8, 15, 12, 6]
50 = [1, 2, 6, 14, 15, 12]
50 = [1, 2, 14, 15, 12, 6]
50 = [1, 2, 15, 32]
50 = [1, 2, 6, 8, 15, 12, 6]
...

Removing duplicates from array without using Util classes

Please read the question before marking it as duplicate
I have written following code to remove duplicates from array without using Util classes but now I am stuck
public class RemoveDups{
public static void main(String[] args) {
int[] a = { 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 3, 1, 4, 52, 1, 45, };
int temp;
for (int i : a) {
for (int j = 0; j < a.length - 1; j++) {
if (a[j] > a[j + 1]) {
temp = a[j];
a[j] = a[j + 1];
a[j + 1] = temp;
}
}
}
a = removeDups(a);
for (int i : a) {
System.out.println(i);
}
}
private static int[] removeDups(int[] a) {
int[] result = new int[a.length];
int j = 0;
for (int i : a) {
if (!isExist(result, i)) {
result[j++] = i;
}
}
return result;
}
private static boolean isExist(int[] result, int i) {
for (int j : result) {
if (j == i) {
return true;
}
}
return false;
}
}
and now the output is
1
2
3
4
5
6
45
52
0
0
0
0
0
0
0
0
0
0
Here my problem is
My code is not working in case of 0s
I am not able to understand how sorting an array can reduce time of execution
Is there any way to remove elements from array without using Util classes I know one way to remove convert array into list and then remove but for that also we need Util classes is there any way to implement by myself.
Since the numbers you deal with are limited to a small range you can remove duplicates by a simple "counting sort": mark the numbers you have found in a set-like data structure and then go over the data structure. An array of boolean works just fine, for less memory usage you could create a basic bitset or hash table. If n is the number of elements in the array and m is the size of the range, this algorithm will have O(n+m) complexity.
private static int[] removeDups(int[] a, int maxA) {
boolean[] present = new boolean[maxA+1];
int countUnique = 0;
for (int i : a) {
if (!present[i]) {
countUnique++;
present[i] = true;
}
}
int[] result = new int[countUnique];
int j = 0;
for (int i=0; i<present.length; i++) {
if (present[i]) result[j++] = i;
}
return result;
}
I am not able to understand how sorting an array can reduce time of execution
In a sorted array you can detect duplicates in a single scan, taking O(n) time. Since sorting is faster than checking each pair - O(n log n) compared to O(n²) time complexity - it would be faster to sort the array instead of using the naive algorithm.
As you are making the result array of the same length as array a
so even if you put only unique items in it, rest of the blank items will have the duplicate values in them which is 0 for int array.
Sorting will not help you much, as you code is searching the whole array again and again for the duplicates. You need to change your logic for it.
You can put some negative value like -1 for all the array items first in result array and then you can easily create a new result array say finalResult array from it by removing all the negative values from it, It will also help you to remove all the zeroes.
In java , arrays are of fixed length. Once created, their size can't be changed.
So you created an array of size18.
Then after you applied your logic , some elements got deleted. But array size won't change. So even though there are only 8 elements after the duplicate removal, the rest 10 elements will be auto-filled with 0 to keep the size at 18.
Solution ?
Store the new list in another array whose size is 8 ( or whatever, calculate how big the new array should be)
Keep a new variable to point to the end of the last valid element, in this case the index of 52. Mind you the array will still have the 0 values, you just won't use them.
I am not able to understand how sorting an array can reduce time of execution
What ? You sort an array if you need it to be sorted. Nothing else. Some algorithm may require the array to be sorted or may work better if the array is sorted. Depends on where you are using the array. In your case, the sorting will not help.
As for your final question , you can definitely implement your own duplicate removal by searching if an element exists more than once and then deleting all the duplicates.
My code is not working in case of 0
There were no zeroes to begin with in your array. But because its an int[], after the duplicates are removed the remaining of the indexes are filled with 0. That's why you can see a lot of zeroes in your array. To get rid of those 0s, you need to create another array with a lesser size(size should be equal to the no. of unique numbers you've in your array, excluding 0).
If you can sort your array(I see that its already sorted), then you could either bring all the zeroes to the front or push them to the last. Based on that, you can iterate the array and get the index from where the actual values start in the array. And, then you could use Arrays.copyOfRange(array, from, to) to create a copy of the array only with the required elements.
try this
package naveed.workingfiles;
public class RemoveDups {
public static void main(String[] args) {
int[] a = { 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 3, 1, 4, 52, 1, 45, };
removeDups(a);
}
private static void removeDups(int[] a) {
int[] result = new int[a.length];
int j = 0;
int count = 0;
for (int i : a) {
if (!isExist(result, i)) {
result[j++] = i;
count++;
}
}
System.out.println(count + "_____________");
for (int i=0;i<count;i++) {
System.out.println(result[i]);
}
// return result;
}
private static boolean isExist(int[] result, int i) {
for (int j : result) {
if (j == i) {
return true;
}
}
return false;
}
}
public class RemoveDups {
public static void main(String[] args) {
int[] a = { 1, 2, 0, 3, 1,0, 3, 6, 2};
removeDups(a);
}
private static void removeDups(int[] a) {
int[] result = new int[a.length];
int j = 0;
int count = 0;
boolean zeroExist = false;
for (int i : a) {
if(i==0 && !zeroExist){
result[j++] = i;
zeroExist = true;
count++;
}
if (!isExist(result, i)) {
result[j++] = i;
count++;
}
}
System.out.println(count + "_____________");
for (int i=0;i<count;i++) {
System.out.println(result[i]);
}
// return result;
}
private static boolean isExist(int[] result, int i) {
for (int j : result) {
if (j == i) {
return true;
}
}
return false;
}
}
// It works even Array contains 'Zero'
class Lab2 {
public static void main(String[] args) {
int[] a = { 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 3, 1, 4, 52, 1, 45 };
removeDups(a);
}
private static void removeDups(int[] a) {
int[] result = new int[a.length];
int j = 0;
int count = 0;
for (int i : a) {
if (!isExist(result, i)) {
result[j++] = i;
count++;
}
}
System.out.println(count + "_____________");
for (int i = 0; i < count; i++) {
System.out.println(result[i]);
}
}
private static boolean isExist(int[] result, int i) {
for (int j : result) {
if (j == i) {
return true;
}
}
return false;
}
}

Categories