Related
Trying to figure the error with this code. This works for small samples but fails for huge numbers (I don't have a large sample in my hand though).
The solution worked for the following tests.
private static final int[] A = {9,3,9,3,9,7,9};
private static final int[] A2 = {9,3,9};
private static final int[] A3 = {9,3,9,3,9,7,7,2,2,11,9};
#Test
public void test(){
OddOccurance oddOccurance =new OddOccurance();
int odd=oddOccurance.solution(A);
assertEquals(7,odd);
}
#Test
public void test2(){
OddOccurance oddOccurance =new OddOccurance();
int odd=oddOccurance.solution(A2);
assertEquals(3,odd);
}
#Test
public void test3(){
OddOccurance oddOccurance =new OddOccurance();
int odd=oddOccurance.solution(A3);
assertEquals(11,odd);
}
when an array is given with an odd number of integers (except one integer other integers can be repeated). The solution is to find the non-repeating integer. Any other better ideas (Time and space optimized) to implement this as well, welcome.
public int solution(int[] A) {
// write your code in Java SE 8
Map<Integer, List<Integer>> map = new HashMap<>();
int value = 0;
//iterate throught the list and for each array value( key in the map)
// set how often it appears as the value of the map
for (int key : A) {
if (map.containsKey(key)) {
map.get(key).add(value);
} else {
List<Integer> valueList = new ArrayList<>();
valueList.add(value);
map.put(key, valueList);
}
}
Set<Map.Entry<Integer, List<Integer>>> entrySet = map.entrySet();
// en
for (Map.Entry<Integer, List<Integer>> entry : entrySet) {
if (entry.getValue().size() == 1) {
return entry.getKey();
}
}
return 0;
}
Update
Looking at failed outputs
WRONG ANSWER, got 0 expected 42
WRONG ANSWER, got 0 expected 700
It seems it didn't even go to the for loop but just return 0
It's a standard problem, if the actual statement is the following:
each number except one appears even number of times; the remaining number appears once.
The solution is to take xor of all numbers. Since every repeating number occures even number of times, it will cancel itself. The reason is that xor is commutative:
a xor b xor c = a xor c xor b = c xor b xor a = etc.
For example, in case of 1, 2, 3, 1, 2
1 xor 2 xor 3 xor 1 xor 2 =
(1 xor 1) xor (2 xor 2) xor 3 =
0 xor 0 xor 3 =
3
One approach would be to create a new array containing the frequency of each value. You could start by looping through your initial array to calculate the maximum value in it.
For example, the array {9,3,9,3,9,7,7,2,2,11,9} would have a maximum value of 11. With this information, create a new array that can store the frequency of every possible value in your initial array. Then, assuming there is only one integer that repeats once, return the index of the new array that has a frequency of 1. This method should run in O(n) where n is the size of the input array.
Here's an implementation:
public int solution(int[] inp)
{
int max = inp[0];
for(int i = 1; i < inp.length; i++)
{
if(inp[i] > max)
max = inp[i];
}
int[] histogram = new int[max + 1]; //We add 1 so we have an index for our max value
for(int i = 0; i < inp.length; i++)
histogram[inp[i]]++; //Update the frequency
for(int i = 0; i < histogram.length; i++)
{
if(histogram[i] == 1)
return i;
}
return -1; //Hopefully this doesn't happen
}
Hope this helps
It's hard to know why yours failed without the actual error message. Regardless, as your array input gets very large, your internal data structure grows accordingly, but doesn't need to. Instead an array of Integer as the value, we can just use one Integer:
public int solution(int[] a) {
Integer ONE = 1;
Map<Integer, Integer> map = new HashMap<>();
for (int key : a) {
Integer value = (map.containsKey(key)) ? map.get(key) + ONE : ONE;
map.put(key, value);
}
for (Map.Entry<Integer, Integer> entry : map.entrySet()) {
if (entry.getValue().equals(ONE)) {
return entry.getKey();
}
}
return -1;
}
I'm assuming the odd array length requirement is to avoid an array of length of two, where the items would both be unduplicated or duplicated.
Since we don't need the actual total, we can simplify this further and just consider parity. Here's a rework that does and uses the evolving new rules of this question, looking for the odd man out:
public int solution(int[] a) {
Map<Integer, Boolean> odd = new HashMap<>();
for (int key : a) {
odd.put(key, (odd.containsKey(key)) ? ! odd.get(key) : Boolean.TRUE);
}
for (Map.Entry<Integer, Boolean> entry : odd.entrySet()) {
if (entry.getValue()) {
return entry.getKey();
}
}
return 0;
}
Returns zero on failure as we now know:
A is an integer within the range [1..1,000,000,000]
How might I approach solving the following problem:
Create an array of integers that are contained in at least two of the given arrays.
For example:
int[] a1 = new int[] { 1, 2, 3, 4, 5 };
int[] a2 = new int[] { 5, 10, 11, 8 };
int[] a3 = new int[] { 1, 7, 6, 4, 5, 3, 11 };
must give a result array
int[] result = new int[] {1, 3, 4, 5, 11}
P.S. i'm interested in suggestions on how I might approach this ("algorithm"), not what Java utils might give me the answer
put a1 numbers in a Map<Integer,Integer> count, using the value as the key, and setting the count to 1
Put a2 numbers into the same map. If an item does not exist, assign the count of 1, otherwise assign it the existing count + 1
Put a3 numbers into the same map. If an item does not exist, assign the count of 1, otherwise assign it the existing count + 1
Go through the entries in a map, and output all keys where the value is greater than one.
This algorithm is amortized linear time in the combined number of elements in the three arrays.
If the numbers in the three arrays are limited to, say, 1000 or another relatively small number, you could avoid using collections at all, but use a potentially more expensive algorithm based on the upper limit of your numbers: replace the map with an array counts[MAX_NUM+1], and then run the same algorithm, like this:
int[] counts = new int[MAX_NUM+1];
for (int a : a1) counts[a]++;
for (int a : a2) counts[a]++;
for (int a : a3) counts[a]++;
for (int i = 0 ; i != MAX_NUM+1 ; i++) {
if (counts[i] > 1) {
System.out.println(i);
}
}
You can look at the 3 arrays as sets and find each element that is in the intersection of some pair of sets.
basically, you are looking for (set1 [intersection] set2) [union] (set2 [intersection] set3) [union] (set1 [intersection] set2)
I agree that it might not be the easiest way to achieve what you are after, but being able to reduce one problem to another is a technique every programmer should master, and this solution should be very educating.
The only way to do this without collections would be to take an element from an array, iterate over the remaining two arrays to see if a duplicate is found (and then break and move to the next element). You need to do this for two out of the three arrays as by the time you move to the third one, you would already have your answer.
Mathematically this can be solved as follows:
You can construct three sets using each of the three arrays, so duplicated entries in each array will only occur once in each set. And then the entries that appear at least in two of the three sets are solutions. So they are given by
(S_1 intersect S_2) union (S_2 intersect S_3) union (S_3 intersect S_1)
Think about the question and the different strategies you might use:
Go through each entry in each array, if that entry is NOT already in the "duplicates" result, then see if that entry is in each of the remaining arrays. Add to duplicates if it is and return to next integer
Create an array of non-duplicates by adding an entry from each array (and if it is already there, putting it in the duplicates array).
Use another creative strategy of your own
I like drawing Venn diagramms. You know that diagram with three intersecting circles, e.g. see here.
You then see that the complement is easier to describe:
Those elements which only exist in one array, are not interesting.
So you could build a frequency list (i.e. key = element, value = count of in how many arrays you found it [for the first time]) in a hash map, and then in a final pass pick all elements which occured more than once.
For simplicity I used sets. If your arrays contain multiple entries of the same value, you have to ignore those extra occurences when you build the frequency list.
An approach could be like this:
1.Sort all the arrays.
2.For each combination of arrays do this
Let us consider the first two arrays A,B. Let a be A's size.
Also take a third array or vector to store our result
for i=0-->a-1 {
Search for A[i] in B using binarySearch.
if A[i] exists in B then insert A[i] into our result vector
}
Repeat the same process for (B,C) and (C,A).
Now sort & Traverse the result vector from the end, remove the elements which have the property
result[i] = result[i-1]
The final vector is the required result.
Time Complexity Analysis:
T(n) = O(nlog(n)) for Sorting where n is the highest array size among the given three
For searching each element of an array in other sorted array T(n) = n * O(log n)
T(n) = O(n (log n)) for sorting the result and O(n) for traversing
So overall time complexity is O(n log(n)); and space complexity is O(n)
Please correct me of I am wrong
In Java:
Will write one without using java.utils shortly.
Meantime a solution using java.utils:
public static void twice(int[] a, int[] b, int[] c) {
//Used Set to remove duplicates
Set<Integer> setA = new HashSet<Integer>();
for (int i = 0; i < a.length; i++) {
setA.add(a[i]);
}
Set<Integer> setB = new HashSet<Integer>();
for (int i = 0; i < b.length; i++) {
setB.add(b[i]);
}
Set<Integer> setC = new HashSet<Integer>();
for (int i = 0; i < c.length; i++) {
setC.add(c[i]);
}
//Logic to fill data into a Map
Map<Integer, Integer> map = new HashMap<Integer, Integer>();
for (Integer val : setA) {
map.put(val, 1);
}
for (Integer val : setB) {
if (map.get(val) != null) {
int count = map.get(val);
count++;
map.put(val, count);
} else {
map.put(val, 1);
}
}
for (Integer val : setC) {
if (map.get(val) != null) {
int count = map.get(val);
count++;
map.put(val, count);
} else {
map.put(val, 1);
}
}
for (Map.Entry<Integer, Integer> entry2 : map.entrySet()) {
//if (entry2.getValue() == 2) { //Return the elements that are present in two out of three arrays.
if(entry2.getValue() >= 2) { //Return elements that are present **at least** twice in the three arrays.
System.out.print(" " + entry2.getKey());
}
}
}
Change condition in last for loop in case one need to return the elements that are present in two out of three arrays. Say:
int[] a = { 2, 3, 8, 4, 1, 9, 8 };
int[] b = { 6, 5, 3, 7, 9, 2, 1 };
int[] c = { 5, 1, 8, 2, 4, 0, 5 };
Output: { 3, 8, 4, 5, 9 }
Here goes without any java.util library:
public static void twice(int[] a, int[] b, int[] c) {
int[] a1 = removeDuplicates(a);
int[] b1 = removeDuplicates(b);
int[] c1 = removeDuplicates(c);
int totalLen = a1.length + b1.length +c1.length;
int[][] keyValue = new int[totalLen][2];
int index = 0;
for(int i=0; i<a1.length; i++, index++)
{
keyValue[index][0] = a1[i]; //Key
keyValue[index][1] = 1; //Value
}
for(int i=0; i<b1.length; i++)
{
boolean found = false;
int tempIndex = -1;
for(int j=0; j<index; j++)
{
if (keyValue[j][0] == b1[i]) {
found = true;
tempIndex = j;
break;
}
}
if(found){
keyValue[tempIndex][1]++;
} else {
keyValue[index][0] = b1[i]; //Key
keyValue[index][1] = 1; //Value
index++;
}
}
for(int i=0; i<c1.length; i++)
{
boolean found = false;
int tempIndex = -1;
for(int j=0; j<index; j++)
{
if (keyValue[j][0] == c1[i]) {
found = true;
tempIndex = j;
break;
}
}
if(found){
keyValue[tempIndex][1]++;
} else {
keyValue[index][0] = c1[i]; //Key
keyValue[index][1] = 1; //Value
index++;
}
}
for(int i=0; i<index; i++)
{
//if(keyValue[i][1] == 2)
if(keyValue[i][1] >= 2)
{
System.out.print(keyValue[i][0]+" ");
}
}
}
public static int[] removeDuplicates(int[] input) {
boolean[] dupInfo = new boolean[500];//Array should not have any value greater than 499.
int totalItems = 0;
for( int i = 0; i < input.length; ++i ) {
if( dupInfo[input[i]] == false ) {
dupInfo[input[i]] = true;
totalItems++;
}
}
int[] output = new int[totalItems];
int j = 0;
for( int i = 0; i < dupInfo.length; ++i ) {
if( dupInfo[i] == true ) {
output[j++] = i;
}
}
return output;
}
It's very simple and could be done for n different arrays the same way:
public static void compute(int[] a1, int[] a2, int[] a3) {
HashMap<Integer, Integer> map = new HashMap<>();
fillMap(map, a1);
fillMap(map, a2);
fillMap(map, a3);
for (Integer key : map.keySet()) {
System.out.print(map.get(key) > 1 ? key + ", " : "");
}
}
public static void fillMap(HashMap<Integer, Integer> map, int[] a) {
for (int i : a) {
if (map.get(i) == null) {
map.put(i, 1);
continue;
}
int count = map.get(i);
map.put(i, ++count);
}
}
fun atLeastTwo(a: ArrayList<Int>, b: ArrayList<Int>, c: ArrayList<Int>): List<Int>{
val map = a.associateWith { 1 }.toMutableMap()
b.toSet().forEach { map[it] = map.getOrDefault(it, 0) + 1 }
c.toSet().forEach{ map[it] = map.getOrDefault(it, 0) + 1 }
return map.filter { it.value == 2 }.map { it.key }
}
In Javascript you can do it like this:
let sa = new Set(),
sb = new Set(),
sc = new Set();
A.forEach(a => sa.add(a));
B.forEach(b => sb.add(b));
C.forEach(c => sc.add(c));
let res = new Set();
sa.forEach((a) => {
if (sb.has(a) || sc.has(a)) res.add(a);
})
sb.forEach((b) => {
if (sa.has(b) || sc.has(b)) res.add(b);
})
sc.forEach((c) => {
if (sa.has(c) || sb.has(c)) res.add(c);
})
let arr = Array.from(res.values());
arr.sort((i, j) => i - j)
return arr
I've written a java prog that stores some values:
public class array05 {
public static void main(String[] args) {
//placement of value
int arryNum[] = {2,3,4,5,4,4,3};
//placement of index, to start at 0
for(int counter=0;counter<arryNum.length;counter++){
System.out.println(counter + ":" + arryNum[counter]);
}
}
}
which generate such output:
0:2
1:3
2:4
3:5
4:4
5:4
6:3
and now I need to count numbers in this output #1.
Output #2 should be this:
1: 0
2: 1
3: 2
4: 3
5: 1
It means it counts ONE 2, TWO 3, THREE 4, and only One 5.
I am not sure how to write the code for output 2.
Is a binary search needed here?
can anybody shed a light?
if you are expecting in your array values between 1-5 (i assuming this from your expected output)
int arryNum[] = { 2, 3, 4, 5, 4, 4, 3 };
int[] counter = new int[] { 0, 0, 0, 0, 0 };
for (int i = 0; i < arryNum.length; i++) {
counter[arryNum[i] - 1]++;
}
for (int i = 0; i < counter.length; i++)
System.out.println((i + 1) + ":" + counter[i]);
I advise you to use a Map:
If a number doesn't exist in it, add it with the value of 1.
If the number exists, add 1 to the its value.
Then you print the map as a key and value.
For example, for your array {2,3,4,5,4,4,3} this will work as follows:
Does the map contains the key 2? No, add it with value 1. (The same for 3, 4 and 5)
Does the map contains 4? Yes! Add 1 to its value. Now the key 4 has the value of 2.
...
If you don't want to use Map, this is how you would do it with Arrays only(if you have numbers from 1 to 9 only)
Integer[] countArray = new Integer[10]
// Firstly Initialize all elements of countArray to zero
// Then
for(i=0;i<arryNum.length();i++){
int j = arryNum[i];
countArray[j]++;
}
This countArray has number of 0's in 1st position, number of 1s in 2nd position and so on
This is a solution to this problem:
import java.util.Arrays;
public class array05 {
public static void main(String[] args) {
//placement of value
int arryNum[] = {2,3,4,5,4,4,3};
// Sort the array so counting same objects is easy
Arrays.sort(arryNum);
int index = 0; // The current index
int curnum; // The current number
int count; // The count of this number
while (index < arryNum.length) {
// Obtain the current number
curnum = arryNum[index];
// Reset the counter
count = 0;
// "while the index is smaller than the amount of items
// and the current number is equal to the number in the current index,
// increase the index position and the counter by 1"
for (; index < arryNum.length && curnum == arryNum[index]; index ++, count++);
// count should contain the appropriate amount of the current
// number now
System.out.println(curnum + ":" + count);
}
}
}
People posted good solutions using Map, so I figured I'd contribute a good solution that will always work (not just for the current values), without using a Map.
Something like this:
//numbers to count
int arryNum[] = {2,3,4,5,4,4,3};
//map to store results in
Map<Integer, Integer> counts = new HashMap<Integer, Integer>();
//Do the counting
for (int i : arryNum) {
if (counts.containsKey(i) {
counts.put(i, counts.get(i)+1);
} else {
counts.put(i, 1);
}
}
//Output the results
for (int i : counts.keySet()) {
System.out.println(i+":"+counts.get(i));
}
Use Map to store count values:
import java.util.HashMap;
import java.util.Map;
class array05{
public static void main(String[] args){
// Container for count values
Map <Integer, Integer> result = new HashMap<Integer, Integer>();
int arryNum[] = {2,3,4,5,4,4,3};
for(int i: arryNum){ //foreach more correct in this case
if (result.containsKey(i)) result.put(i, result.get(i)+1);
else result.put(i, 1);
}
for (int i: result.keySet()) System.out.println(i + ":" + result.get(i));
}
}
Result below:
2:1
3:2
4:3
5:1
One approach is to use a map. When you read the first array on each number check if it exists in the map, if it does then just increment the value assigned to the number(key), if not then create a new key in the map with value "1".
Check out http://docs.oracle.com/javase/7/docs/api/java/util/HashMap.html
You can try this way too
int arrayNum[] = {2,3,4,5,4,4,3};
Map<Integer,Integer> valMap=new HashMap<>();
for(int i:arrayNum){ // jdk version should >1.7
Integer val=valMap.get(i);
if(val==null){
val=0;
}
valMap.put(i,val+1);
}
Arrays.sort(arrayNum);
for(int i=0;i< arrayNum[arrayNum.length-1];i++){
System.out.println(i+1+" : "+((valMap.get(i+1)==null) ? 0:valMap.get(i+1)));
}
Out put
1 : 0
2 : 1
3 : 2
4 : 3
5 : 1
But following way is better
int arrayNum[] = {2,3,4,5,4,4,3};
Arrays.sort(arrayNum);
int countArray[]=new int[arrayNum[arrayNum.length-1]+1];
for(int i:arrayNum){
countArray[i]= countArray[i]+1;
}
for(int i=1;i<countArray.length;i++){
System.out.println(i+" : "+countArray[i]);
}
Out put
1 : 0
2 : 1
3 : 2
4 : 3
5 : 1
I would prefer some generic solution like this one:
public static <T> Map<T, Integer> toCountMap(List<T> itemsToCount) {
Map<T, Integer> countMap = new HashMap<>();
for (T item : itemsToCount) {
countMap.putIfAbsent(item, 0);
countMap.put(item, countMap.get(item) + 1);
}
return countMap;
}
//Count the times of numbers present in an array
private HashMap<Integer, Integer> countNumbersInArray(int[] array) {
HashMap<Integer, Integer> hashMap = new HashMap<>();
for (int item : array) {
if (hashMap.containsKey(item)) {
hashMap.put(item, hashMap.get(item) + 1);
} else {
hashMap.put(item, 1);
}
}
return hashMap;
}
So me and my friend tried to code this little game when we were children called LOVERS..
Wherein you write down the name of 2 persons,Whole name without the middle name,and count the number of L's,O's,V's,E's,R's,and S's in the name, add it together and put beside the letters.
Sample:
name 1: Hello
name 2: Care
L: 2
O: 1
V: 0
E: 2
R: 1
S: 0
afterwards you will add them in pairs.
Sample:
L: 2 > 3 > 4 > 7 > 15 > 32
O: 1 > 1 > 3 > 8 > 17
V: 0 > 2 > 5 > 9
E: 2 > 3 > 4
R: 1 > 1
S: 0
here's how it goes...first you add the values of the first 2 letters...LO then OV then VE and so on and so forth. until you get one final answer in this case 32....the 32 signifies the percentage in which the 2 people is Compatible with each other.
i know its quite stupid. haha but we just tried to program it for fun. we are 2nd year IT Students here in the philppines. anyway we were wondering if there's a way to do the calculation RECURSIVELY and if there's a way to reduce the number of Arrays used.
Here's our code:
import java.util.*;
public class LOVERS {
static Scanner console = new Scanner(System.in);
public static void main(String[] args) {
String name1="";
String name2="";
char love[] = {'L','O','V','E','R','S'};
int[] lovers = new int[6];
int[] temp= new int[6];
int[] temp2= new int[6];
boolean done = true;
while(done){
name1 = getName();
name2 = getName();
temp = getLetterCount(name1);
temp2 = getLetterCount(name2);
lovers = sumOfLetters(temp,temp2,love);
System.out.println("");
int[] firstLayer = new int[5];
int[] secondLayer = new int[4];
int[] thirdLayer = new int[3];
int[] fourthLayer = new int[2];
firstLayer = sums(lovers);
secondLayer = sums(firstLayer);
thirdLayer = sums(secondLayer);
fourthLayer = sums(thirdLayer);
int output = fourthLayer[0]+fourthLayer[1];
if(output>100){
output=100;
}
System.out.println("Result is : "+ output +"%");
System.out.println("Do you want to try again? Y/N :");
char again = ' ';
if(again == 'n')
{
done = false;
}
else done = true;
}
}
public static int[] sums (int[] y){
int[] x = new int[y.length-1];
for(int ctr=1;ctr<y.length;ctr++){
x[ctr-1]=y[ctr-1]+y[ctr];
}
return x;
}
public static String getName(){
String n="";
System.out.println("Enter name: ");
n = console.nextLine();
n = n.toUpperCase();
return n;
}
public static int[] sumOfLetters(int[] temp, int[] temp2, char[] love){
int[] lovers = new int[6];
for(int ctr=0;ctr<6;ctr++){
lovers[ctr]=temp[ctr]+temp2[ctr];
System.out.println(love[ctr]+" - "+lovers[ctr]);
}
return lovers;
}
public static int[] getLetterCount(String n){
int[] temp = new int[6];
for(int x=0;x<n.length();x++){
if(n.charAt(x)=='L'){
temp[0]++;
}
else if(n.charAt(x)=='O'){
temp[1]++;
}
else if(n.charAt(x)=='V'){
temp[2]++;
}
else if(n.charAt(x)=='E'){
temp[3]++;
}
else if(n.charAt(x)=='R'){
temp[4]++;
}
else if(n.charAt(x)=='S'){
temp[5]++;
}
}
return temp;
}
}
as you can see we used 4 arrays for the 4 layers of calculation and we used a looping statement for the calculation.
So can this be done RECURSIVELY? and How can we reduce the number of arrays used?
this can help us greatly in learning how to do proper Recursive functions since we are currently learning Data Structures. hope you guys can help me. thanks
Yes, of course you can code it recursively.
First of all, your sum-fn. Instead of going through the string byte for byte, you can pass the string to the same function over and over again, just removing one character each time. That character will be added to your result-number. Your final-check will be that the string is empty, then you return null. Evaluation will go back up the recursion, potentially adding 1 (or 0 otherwise) for each character in the string.
For clearer, more readable code you should use enums instead of byte-arrays for storing your ints.
Also, instead of static functions, make it a class in which you can access the attributes.
For the summation of the 6 chars, each level does the same operation on it. So each function call should do that addition and return the result being called in the function again. Your final-check is that only the first integer value positive. If all the other values are 0 the first one holds your sum.
Yes, you can do it recursively:
public static int L(int i) {
return (i == 0) ? LVAL : L(i - 1) + O(i - 1);
}
public static int O(int i) {
return (i == 0) ? OVAL : O(i - 1) + V(i - 1);
}
public static int V(int i) {
return (i == 0) ? VVAL : V(i - 1) + E(i - 1);
}
public static int E(int i) {
return (i == 0) ? EVAL : E(i - 1) + R(i - 1);
}
public static int R(int i) {
return (i == 0) ? RVAL : R(i - 1) + SVAL;
}
Calling L(5) gives you the answer.
Actually the problem here is one instance of a much more general class of problems/algorithms which are incidentally quite important in some fields nobody would believe from this example ;)
Basically you can regard your triangle above as a matrix. Ie the second number in the L row (the 3) would be (0,1), 3rd value in the E row would be (3,2). If you look at it you see that every value except the start values depend on exactly two other nodes, which makes this a 2-point stencil. There are some extremely intriguing algorithms out there for this kind of problem - eg a cache oblivious, parallel algorithm for higher-order stencils (LBMHD uses 13-points or something).
Anyways that stuff is completely out of your league I fear (don't ask me about details either~) - there are even more or less recent papers about this ;)
PS: And my personal small implementation. Can't get much simpler and has the typical structure
of a simple recursive program. You call it with getVal(0, 5); or more generally getVal(0, startVals.length - 1). Just think about it as working backwards from the solution to the start. We want to know what the right field in the first row has. To get this we need to know two the values of two other fields which we have to compute first in the same manner. This is done until we get to a field where we already know the result - ie our start values.
private int[] startVals; // contains start values for all 6 letters.
// for your example startVals[0] == 2; startVals[5] == 0
public int getVal(int row, int col) {
if (col == 0) return startVals[row];
return getVal(row, col-1) + getVal(row + 1, col - 1);
}
How can we find out missing elements from two arrays ?
Ex:
int []array1 ={1,2,3,4,5};
int []array2 ={3,1,2};
From the above two arrays i want to find what are the missing elements in second array?
Convert them to Sets and use removeAll.
The first problem is how to convert a primitive int[] to a collection.
With Guava you can use:
List<Integer> list1 = Ints.asList(array1);
List<Integer> list2 = Ints.asList(array2);
Apache commons (which I'm not familiar with) apparently has something similar.
Now convert to a set:
Set<Integer> set1 = new HashSet<Integer>(list1);
And compute the difference:
set1.removeAll(list2);
And convert the result back to an array:
return Ints.toArray(set1);
If you are allowed duplicates in the arrays, an efficient (O(n)) solution it to create a frequency table (Map) by iterating over the first array, and then use the map to match off any elements in the second array.
Map<Integer, Integer> freqMap = new HashMap<Integer, Integer>();
// Iterate over array1 and populate frequency map whereby
// the key is the integer and the value is the number of
// occurences.
for (int val1 : array1) {
Integer freq = freqMap.get(val1);
if (freq == null) {
freqMap.put(val1, 1);
} else {
freqMap.put(val1, freq + 1);
}
}
// Now read the second array, reducing the frequency for any value
// encountered that is also in array1.
for (int val2 : array2) {
Integer freq = freqMap.get(val2);
if (freq == null) {
freqMap.remove(val2);
} else {
if (freq == 0) {
freqMap.remove(val2);
} else {
freqMap.put(freq - 1);
}
}
}
// Finally, iterate over map and build results.
List<Integer> result = new LinkedList<Integer>();
for (Map.Entry<Integer, Integer> entry : freqMap.entrySet()) {
int remaining = entry.getValue();
for (int i=0; i<remaining; ++i) {
result.add(entry.getKey());
}
}
// TODO: Convert to int[] using the util. method of your choosing.
Simple logic for getting the unmatched numbers.
public static int getelements(int[] array1, int[] array2)
{
int count = 0;
ArrayList unMatched = new ArrayList();
int flag = 0;
for(int i=0; i<array1.length ; i++)
{ flag=0;
for(int j=0; j<array2.length ; j++)
{
if(array1[i] == array2[j]) {
flag =1;
break;
}
}
if(flag==0)
{
unMatched.add(array1[i]);
}
}
System.out.println(unMatched);
return unMatched.size();
}
public static void main(String[] args) {
// write your code here5
int array1[] = {7,3,7,2,8,3,2,5};
int array2[] = {7,4,9,5,5,10,4};
int count;
count = getelements(array1,array2);
System.out.println(count);
}
You can use Set and its methods. This operation would be a set difference.
The naive way would be to simply search one array for each of the elements of the other array (with a for loop). If you first were to SORT both arrays, it becomes much more efficient.
Consider using intersection method:
A healthy discussion is available at:
http://www.coderanch.com/t/35439/Programming-Diversions/Intersection-two-arrays
You could create two other int arrays to store the multiplicity of each value. Increment the index of the array that the value corresponds with every time it is found and then compare the arrays.
It's not the most "efficient" way perhaps, but it's a very simple concept that works.
Guava library can be helpful; you need to change Array in Set then can use API.
#finnw I believe you were thinking of commons-collections.
Need to import org.apache.commons.collections.CollectionUtils;
To get the disjunction function.
Using the disjunction method will find all objects that aren't found in an intersection.
Integer[] array1 ={1,2,3,4,5};
Integer[] array2 ={3,1,2};
List list1 = Arrays.asList(array1);
List list2 = Arrays.asList(array2);
Collection result = CollectionUtils.disjunction(list1, list2);
System.out.println(result); // displays [4, 5]
This is not the most efficient way but it's probably the simplest way that works in Java :
public static void main(final String[] args) {
final int[] a = { 1, 2, 3, 4, 5 };
final int[] b = { 3, 1, 2 };
// we have to do this just in case if there might some values that are missing in a and b
// example: a = { 1, 2, 3, 4, 5 }; b={ 2, 3, 1, 0, 5 }; missing value=4 and 0
findMissingValue(b, a);
findMissingValue(a, b);
}
private static void findMissingValue(final int[] x, final int[] y) {
// loop through the bigger array
for (final int n : x) {
// for each value in the a array call another loop method to see if it's in there
if (!findValueSmallerArray(n, y)) {
System.out.println("missing value: " + n);
// break;
}
}
}
private static boolean findValueSmallerArray(final int n, final int[] y) {
for (final int i : y) {
if (n == i) {
return true;
}
}
return false;
}