Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
So i have a column of data which consists of numbers where i have to find 5 instances of the same number.
So ,for example, 8,8,8,8,8,8,8,8,8,9,9,9,5,6,4,7,,6,2,3, etc. In this 8 has occurred 9 times. So i want to increment the count only once because even though there are nine 8's what my code is doing is taking the first 8 and getting the 5 consecutive numbers are incrementing. Then it takes the next 8 and increments the count and so on where the count becomes 5 but i want it to be 1. What i want is the first occurrence of any number to be the base value and take 5 consecutive numbers and increment the count. Then then take the 6th 8 and count if there are 5 consecutive 8's or that specific number or not. So, for example, 8,8,8,8,8,8,9,9,9,9,9,9,9,9,5,5,5,5,5,1,1,2,2,5,4,3,6,7,9,3,4,2,2,2,2,2,1,2,1. In this the count should be 4.
**count=0;
count1=0;
for i=1:length(data)-4
for j=i+1:i+4
if data(i)~=data(j)
count1=0;
break;
else
count1=count1+1;
end
if count1==5 % line 0
count=count+1;
%data(i,1)=data(i+5,1); //line 1 <=comment
%data(i)=data(i+5); //line 2 <=comment
else
continue;
end
end**
If(count_consecutive==5){
count_main=count_main+1; ...
a[i]=a[i+5];// continue for the base value. It should skip all the numbers that were counted in the consecutive count one and take the next number as the base for counting the consecutive numbers}
The logic in any language would be fine as my error is in the logic
Thanks for any help. It would be greatly appreciated :).
Extra Elaboration
So the first one only has 5 consecutive 8's in the manner i specified. Hence the first one will have an output count =1 . In the second one, there are 4 of the 5 consecutive numbers of the same starting number. Hence the output would be 4, Another example i can give is 8,8,8,8,8,8,8,8,8,8(ten 8's),9,9,9,9,4,5,6,4,6,6,6,6,6. In this , the count should be 3 as it has 10 8's which increments the count to 2 and another 5 consecutive 6 which increments count one more time. Total count would be 3.
Now the error is i can't jump the array index from a[i] to a[i+5]. So the first one only has 5 consecutive 8's in the manner i specified. Hence the first one will have an output count =1 . In the second one, there are 4 of the 5 consecutive numbers of the same starting number. Hence the output would be 4, Another example i can give is 8,8,8,8,8,8,8,8,8,8(ten 8's),9,9,9,9,4,5,6,4,6,6,6,6,6. In this , the count should be 3 as it has 10 8's which increments the count to 2 and another 5 consecutive 6 which increments count one more time. Total count would be 3. My problem is that i'm not able to skip/jump the array index from x to x+5 in the for loop when my condition gets satisfied.
I attach the code in Matlab (also works in Octave):
vector = [8,8,8,8,8,8,9,9,9,9,9,9,9,9,5,5,5,5,5,1,1,2,2,5,4,3,6,7,9,3,4,2,2,2,2,2,1,2,1]
count = 1;
result = 0;
for i = 2:length(vector)
if vector(i-1) == vector(i)
count = count+1;
else
count = 1;
end
if count == 5
result = result+1;
count = 1;
end
end
Mainly, you have to count the number of times that a value appears and increase the result if this number of times arrises 5.
It would be simpler to count the length of the subsequence containing the same elements consecutive and as soon as the subsequence is finished, to increment the resulting counter by the number of groups consisting of N elements in the subsequence: result += consecutive / n:
public static int countConsecutiveN(int n, int ... arr) {
if (null == arr || arr.length < n) {
return 0;
}
int result = 0;
int previous = arr[0];
int consecutive = 1;
for (int i = 1; i < arr.length; i++) {
if (arr[i] == previous) {
consecutive++;
} else { // consecutive sequence ended
result += consecutive / n; // increment by the count of N elements in the subsequence
consecutive = 1;
}
previous = arr[i];
}
// check the trailing subsequence
result += consecutive / n;
return result;
}
Test
System.out.println(countConsecutiveN(5,
8,8,8,8,8,8, // six 8s
9,9,9,9,9,9,9,9,9,9, // ten 9s - 2 groups
5,5,5,5,5, // five 5s
1,1,2,2,5,4,3,6,7,9,3,4,
2,2,2,2,2,2,2, // seven 2s
1,2,
1,1,1,1,1,1 // six 1s
));
Output
6
If you want to count runs of equal values with a minimum length N, in Matlab this can be done very easily with diff (consecutive differences) and find (indices of nonzero entries):
N = 5; % mininum desired run length
x = [8,8,8,8,8,8,9,9,9,9,9,9,9,9,5,5,5,5,5,1,1,2,2,5,4,3,6,7,9,3,4,2,2,2,2,2,1,2,1];
result = sum(diff(find([true diff(x)]))>=N);
If a run ends immediately when reaching length N (so for example 11 consecutive equal values count as two runs of length N=5):
result = sum(floor(diff(find([true diff(x)]))/N));
This question already has answers here:
Bitwise Multiply and Add in Java
(4 answers)
Closed 4 years ago.
So I have the following code to multiply two variables x and y using left and right shifts.
class Multiply {
public static long multiply(long x,long y) {
long sum = 0;
while(x != 0) {
if((x & 1) != 0) {
sum = sum+y;
}
x >>>= 1;
y <<= 1;
}
return sum;
}
public static void main(String args[]) {
long x = 7;
long y = 5;
long z = multiply(x,y);
}
}
But I dont understand the logic behind it, I understand that when you do
y<<=1
You are doubling y, but what does it mean that the number of iterations of the while loop depends on the number of bits x has?
while(x != 0)
Also why do I only sum if the rightmost bit of x is a 1?
if((x & 1) != 0) {
sum = sum+y;
}
I've really tried to understand the code but I haven't been able to get my head around the algorithm.
Those of us who remember from school how to multiply two numbers, each with two or more digits, will remember the algorithm:
23
x45
---
115
92x
----
1035
For every digit in the bottom factor, multiply it by the top factor and add the partial sums together. Note how we "shift" the partial sums (multiply them by 10) with each digit of the bottom factor.
This could apply to binary numbers as well. The thing to remember here is that no multiplication (by a factor's digit) is necessary, because it's either a 0 (don't add) or a 1 (add).
101
x110
-----
000
101
101
-----
11110
That's essentially what this algorithm does. Check the least significant bit; if it's a 1, add in the other factor (shifted), else don't add.
The line x >>>= 1; shifts right so that the next bit down becomes the least significant bit, so that the next bit can be tested during the next loop iteration. The number of loops depends on where the most significant bit 1 in x is. After the last 1 bit is shifted out of x, x is 0 and the loop terminates.
The line y <<= 1; shifts the other factor (multiplies by 2) in preparation for it be possibly added during the next loop iteration.
Overall, for every 1 bit in x at position n, it adds 2^n times y to the sum.
It does this without keeping track of n, but rather shuffling the bits x of 1 place right (dividing by 2) every iteration and shuffling the bits of y left (multiplying by 2).
Every time the 0 bit is set, which is tested by (x & 1) != 0, the amount to add is the current value of y.
Another reason this works are these equivalences:
(a + b) * y == a*y + b*y
x * y == (x/2) * (y*2)
which is the essence of what’s going on. The first equivalence allows bit-by-bit addition, and the second allows the opposite shuffling.
The >>> is an unsigned right shift which basically fills 0 irrespective of the sign of the number.
So for value x in the example 7 (in binary 111) the first time you do x >>>= 1; You are making the left most bit a zero so it changes from 111 to 011 giving you 3.
You do it again now you have 011 to 001 giving you 1
Once again and you have 001 to 000 giving you 0
So basically is giving you how many iterations before your number becomes zero. (Basically is diving your number in half and it is Integer division)
Now for the y value (5) you are adding it to your sum and then doubling the value of y
so you get:
y = 5 sum = 5
y = 10 sum = 15
y = 20 sum = 35
Only 3 iterations since x only needed to shift 3 times.
Now you have your result! 35
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 6 years ago.
Improve this question
I received this question during an interview, the question is
Given two integers, return the number of digits that they share.
For example 129 and 431 would return 1 - as they both share the digit 1, but no other digit. 95 and 780 would return 0, since none of the integers overlap.
My thoughts are just iterate through the digits, store them into a hashtable and check .containsKey.
My Java solution:
public int commonDigits(int x, int y) {
int count = 0;
HashTable<Integer, String> ht = new HashTable<Integer, String>();
while (x != 0) {
ht.put(x % 10, "x");
x /= 10;
}
while (y != 0) {
if ((ht.containsKey(y % 10)) {
count++;
}
y /= 10;
}
return count;
}
But this takes up O(n) space and O(n + m) time, anyways I can improve this?
Why not just use some simple bit fiddling?
public int commonDigits(int x, int y) {
int dX = 0;
while (x != 0) {
dX |= 1 << (x % 10);
x /= 10;
}
int count = 0;
while (y != 0) {
int mask = 1 << (y % 10);
if ((dX & mask) != 0) {
count ++;
dX &= ~mask;
}
y /= 10;
}
return count;
}
This just sets a corresponding bit in dX for each digit in x. In the second loop, for each digit in x, the code checks whether it has an entry in dX. If so, it's counted and the bit is reset to avoid double-counting (note that this is missing in your code, consider 123 and 141). Obviously doesn't use any additional storage (dX and count could just be bytes if that matters).
Note that you don't need a HashTable in your solution -- you could just use a HasSet or a BitSet..
Your code translated to using a BitSet with the double-counting problem fixed:
public int commonDigits(int x, int y) {
int count = 0;
BitSet ht = new BitSet();
while (x != 0) {
ht.set(x % 10, true);
x /= 10;
}
while (y != 0) {
if ((ht.get(y % 10)) {
count++;
ht.set(y % 10, false);
}
y /= 10;
}
return count;
}
Both snippets work exactly the same way, the latter just has some more overhead for the BitSet (and embedded array) instance.
This article shows why a BitSet is better than a boolean array in the general case: http://chrononsystems.com/blog/hidden-evils-of-javas-byte-array-byte
Edit:
If counting the same digit multiple times is actually desired (was not clear from the examples in the question), use an int array to store the counts:
public int commonDigits(int x, int y) {
int count = 0;
int[] digits = new int[10];
while (x != 0) {
digits[x % 10]++;
x /= 10;
}
while (y != 0) {
if (digits[x % 10] > 0) {
count++;
digits[x % 10]--;
}
y /= 10;
}
return count;
}
This is your solution with the minimum storage (an array of 10 bytes instead of a hash table):
public int commonDigits(int x, int y) {
int count = 0;
byte[] digits=new byte[10];
while (x != 0) {
digits[x%10] ++;
x /= 10;
}
while (y != 0) {
if (digits[y % 10] > 0) {
count++;
digits[y % 10] --;
}
y /= 10;
}
return count;
}
The solution is optimum in running time O(n+m), where n is the number of digits in x and m is the number of digits in y. You cannot do less than enumerating the digits of x then the digits of y.
Since there are only 10 possible digits, why not just store an integer array? Indexed from 0-9, one for each digit. Loop through each digit and increment the corresponding array element. The space complexity of this depends on what you define to be "constant" - this will always take up 10 units of space (would be 10 bytes in C/C++, not sure how JVM does it)
By conservation of information, you have to loop through each digit of both numbers (they are independent so you can't just infer one from the other), so your time complexity will remain at O(m + n). Also I think by O(n) you really mean O(log n), as this is the number of digits in any representation of the number.
There is at maximum 10 digits that can be shared. This means you don't need a complicated data structure like Hashtable, an array or bitmask will suffice!
You would simply iterate over the first number, and every digit you hit is marked as "true" (in your bitmask or array). You can even short-circuit this and return early if you have found every digit once (which is easy and cheap with a bitmask). Then go over the second number. Every time you hit a digit that is also marked as true, increase the counter. If the bitmask contains every digit, short-circuit by returning the length of the number (its highest exponent), otherwise return the counter at the end.
This doesn't reduce O-complexity, but it reduces memory footprint and adds some short-circuits for large numbers.
For example, if the first number is 1234567890, then it will always share as many digits with the second number as the second number has decimal places.
A hash table is overkill, just use an array of ten flags (whether you pack them in a single integer with bitwise operations or keep independent variables is up to you).
Scan the first integer and raise the relevant flag for every digit.
Scan the second integer and reset the relevant flag for every digit.
Return the number of true resets (from 1 to 0).
Update: to deal with duplicates, the flags need to be replaced by counters.
If both numbers have M digits, they must all be looked at so that the time complexity is at certainly Ω(M).
The case of the space complexity is less clear. All solutions presented here are O(N), where N is the number of possible digits (10 in the decimal base). But O(1) space is possible: take every digit of the first number in turn, check if it is the first such digit in the first number (to avoid counting duplicates), then check if it exists in the second number. This is an O(M²)-time process, but O(1)-space only.
Update: to deal with duplicates, every time you process a digit, count the number of identical predecessors in the first number; when looking for a match in the second number, also match the number of predecessors.
So one may wonder if a O(M)-time, O(1)-space solution is possible.
My solution is O(M+N)-time, O(N)-space. The +N in the time complexity is only required for the initialization of all N flags. If you accept not to count the initialization, you can write the algorithm in such a way that it clears all the flags it has set (so that the algorithm can be played again) and this yields a O(M)-time, O(N)-space solution.
There is an easy O(M Log M)-time, O(M)-space solution, by sorting the two strings of digits and counting the identical digits in a merge-like step. Can be of use if M is very small compared to N.
Your solution doesn't account for duplicates.
# 11, 211 -> 2
You're right to use a hash, it's faster than an array. Gonna do this in python because it's faster to type...
# Returns an array containing the shared digits
def getShared(num1, num2):
shared = []
digits1 = getDigits(num1)
digits2 = getDigits(num2)
for digit in digits1:
if digit in digits2:
while digits2[digit] > 1 and digits1[digit] > 1:
digits2[digit] = digits2[digit] - 1
digits1[digit] = digits1[digit] - 1
shared += [digit]
del digits2[digit]
del digits1[digit]
return shared
# Given an integer, returns a dictionary with the keys as the digits,
# and the value as the number of times the digit appears
def getDigits(num)
dict = {}
while num > 0:
newDigit = num % 10
if newDigit not in dict:
dict[newDigit] = 1
else:
dict[newDigit] = dict[newDigit] + 1
return dict