I want to increment (+1) the last digit of an int array that has N values and represents a whole number. Each value is a single digit between 0-9.
The logic is like this: if the digit that has to be incremented is 9, it has to become 0 and the next one (from right to left) has to be incremented by 1. If you reach the first digit of the array and it is a 9, this will become a 10. Examples:
[3,4,5,6] -> [3,4,5,7]
[3,9,2,9] -> [3,9,3,0]
[3,4,9,9] -> [3,5,0,0]
[9,9,9,9] -> [10,0,0,0]
I had the same exercise but with only 4 digits, so the logic was simple:
int[] incrementArrayDigits(int[] fourDigits) {
if (fourDigits[3] != 9) {
fourDigits[3]++;
} else if (fourDigits[2] != 9) {
fourDigits[3] = 0;
fourDigits[2]++;
} else if (fourDigits[1] != 9) {
fourDigits[3] = 0;
fourDigits[2] = 0;
fourDigits[1]++;
} else if (fourDigits[0] != 9) {
fourDigits[3] = 0;
fourDigits[2] = 0;
fourDigits[1] = 0;
fourDigits[0]++;
}
if (fourDigits[0] == 9 && fourDigits[1] == 9 && fourDigits[2] == 9 &&
fourDigits[3] == 9) {
fourDigits[1] = fourDigits[2] = fourDigits[3] = 0;
fourDigits[0] = 10;
}
System.out.println(Arrays.toString(fourDigits));
return fourDigits;
}
I tried to solve the problem for N numbers taking the length of the array and then using a for loop but I cannot reach the expected result.
One way to solve this is to use recursion.
The idea is to keep track of which element of the array you are incrementing. You start with the element at index array.length - 1, increment it, if it reaches 10, set it to 0, then do the same thing to the element at index array.length - 2, and so on.
Also note that since you are changing the array in the method, you don't have to return the array.
private static void incrementArrayDigits(int[] array, int position) {
if (position >= array.length || position < 0) {
return;
}
array[position]++;
if (array[position] == 10 && position != 0) {
array[position] = 0;
incrementArrayDigits(array, position - 1);
}
}
// usage:
int[] array = {9,9,9};
incrementArrayDigits(array, array.length - 1);
System.out.println(Arrays.toString(array));
In fact, what you really want to achieve is the "PLUS 1". If your N <= 10, use int directly. if your N <=10, use long.
Of course, if you N really need very large. Try implement a class for the digit?
One possible solution is to iterate backwards over your array and increment if needed:
private static int[] incrementArrayDigits(int[] fourDigits) {
for (int i = fourDigits.length - 1; i >= 0; i--) {
fourDigits[i]++; // increment
if (i > 0) { // cut result to 0-9, if not the first value
fourDigits[i] %= 10;
}
if (fourDigits[i] > 0) { // if no carry is passed break
break;
}
}
return fourDigits;
}
This is a solution I came up with. Hope it helps!
public void incrementArrayDigits(int[] arr) {
if(arr == null)
return;
int currIndex = arr.length - 1;
while(currIndex > -1){
arr[currIndex]++;
if(arr[currIndex] < 10)
return;
else if (currIndex < 1)
return;
else
arr[currIndex--] = 0;
}
}
Related
I have to write a method which returns true if three 3s are present in an integer array(provided they are not consecutive).
I have written this code here: However, it is returning true (which it should not do). Can someone point out my mistake?
arr[]={{4,3,5,2,3,3};
Also, this is a linear algorithm. Can it be done better?
public static boolean consecutiveThree(int[] arr) {
int x=0;
for(int i=0;i<arr.length-1;i++) {
if((arr[i]!=3 && arr[i+1]==3) || (arr[i]==3 && arr[i+1]!=3)) {
x++;
//continue;
}
if(x==3)
return true;
}
return false;
}
You said:
returns true if three 3s are present in an integer array(provided they are not consecutive)
I interpret that as having at least three 3s, and no two 3s are adjacent.
public static boolean hasThreeNonconsecutiveThrees(int... values) {
int count = 0, streak = 0;
for (int value : values) {
if (value != 3)
streak = 0;
else if (++streak == 2)
return false; // Found two consecutive (adjacent) 3s
else
count++;
}
return (count >= 3);
}
Test
System.out.println(hasThreeNonconsecutiveThrees(4,3,5,2,3,3)); // false
System.out.println(hasThreeNonconsecutiveThrees(4,3,5,3,2,3)); // true
System.out.println(hasThreeNonconsecutiveThrees(1,2,3,4,3)); // false
System.out.println(hasThreeNonconsecutiveThrees(4,3,5,3,3,3)); // false
Output
false
true
false
false
At worst case the correct array will end with ... 3 3 X 3. Unless the array is somewhat sorted or somewhat special you will have to look at every single element to reach the last three 3s. If the array is random, you need linear complexity since you have to review every single element in the array.
Your algorithm is not checking the whether arr[i-1] is '3'. That is your algorithm's mistake.
Try this:-
public static boolean consecutiveThree(int[] arr) {
int x = 0;
for (int i = 0; i < arr.length; i++) {
if (arr[i] == 3) {
if (i == 0) { // zero 'th element do not have arr[i-1].
if(arr[i + 1] != 3) {
x++;
}
} else if (i == arr.length - 1) { // last element do not have arr[i+1].
if((arr[i - 1] != 3)) {
x++;
}
} else if ((arr[i + 1] != 3) && (arr[i - 1] != 3)) {
x++;
}
}
if (x == 3) // may be x >= 3
return true;
}
return false;
}
in the following code what does this line translates to?
while (n-- != 0){}? if i am not mistaking n is 18 when length of searchMe is deducted form length of substring, so does this line says while 18 decremented (17) is not equal to 0 do the search?
class ContinueWithLabelDemo {
public static void main(String[] args) {
String searchMe = "Look for a substring in me";
String substring = "sub";
boolean foundIt = false;
int max = searchMe.length() -
substring.length();
test:
for (int i = 0; i <= max; i++) {
int n = substring.length();
int j = i;
int k = 0;
while (n-- != 0) {
if (searchMe.charAt(j++) != substring.charAt(k++)) {
continue test;
}
}
foundIt = true;
break test;
}
System.out.println(foundIt ? "Found it" : "Didn't find it");
}
}
while (n-- != 0) { // checks (n != 0) then n = n-1;
if (searchMe.charAt(j++) != substring.charAt(k++)) {
continue test;
}
}
this n-- will do post decrement, first it will check the condition then it will decrease the value of n by 1.
Suppose value of n is 10. then first it will check the condition,
if(10 != 0) and after this it will decrease to 9.
The condition n-- != 0 means "Check that n is not equal to zero before decrementing it; set n to n-1 after the check."
This means that when n is equal to some number K before the loop, then the loop would repeat exactly K times.
In your code you have written:
while (n-- != 0) {
if (searchMe.charAt(j++) != substring.charAt(k++)) {
continue test;
}
}
So if you replace your code with below code:
while (n != 0) {
n = n-1;
if (searchMe.charAt(j++) != substring.charAt(k++)) {
continue test;
}
}
These two codes would work exectly same, so I think by comparison you can understand it's meaning.
n-- is actually a method that behind the scenes changes the value of n to n-1, but returns the actual value of n currently because it is a postfix operation in this case.
If it was a prefix operation (--n) then yes the value returned would be 17 first as you said.
Basically, n-- means take the current value of n and use that for this line, but after this current line, decrement the value by one. In this case, the first value of n would be the length of the string
I am trying to figure out how to count all numbers between two ints(a and b), where all of the digits are divisible with another int(k) and 0 counts as divisible.Here is what I've made so far, but it is looping forever.
for (int i = a; i<=b; i++){
while (i < 10) {
digit = i % 10;
if(digit % k == 0 || digit == 0){
count ++;
}
i = i / 10;
}
}
Also I was thinking about comparing if all of the digits were divisible by counting them and comparing with number of digits int length = (int)Math.Log10(Math.Abs(number)) + 1;
Any help would be appreciated. Thank you!
Once you get in to your while block you're never going to get out of it. The while condition is when i less than 10. You're dividing i by 10 at the end of the whole block. i will never have a chance of getting above 10.
Try this one
public class Calculator {
public static void main(String[] args) {
int a = 2;
int b = 150;
int k = 3;
int count = 0;
for (int i = a; i <= b; i++) {
boolean isDivisible = true;
int num = i;
while (num != 0) {
int digit = num % 10;
if (digit % k != 0) {
isDivisible = false;
break;
}
num /= 10;
}
if (isDivisible) {
count++;
System.out.println(i+" is one such number.");
}
}
System.out.println("Total " + count + " numbers are divisible by " + k);
}
}
Ok, so there are quite a few things going on here, so we'll take this a piece at a time.
for (int i = a; i <= b; i++){
// This line is part of the biggest problem. This will cause the
// loop to skip entirely when you start with a >= 10. I'm assuming
// this is not the case, as you are seeing an infinite loop - which
// will happen when a < 10, for reasons I'll show below.
while (i < 10) {
digit = i % 10;
if(digit % k == 0 || digit == 0){
count ++;
// A missing line here will cause you to get incorrect
// results. You don't terminate the loop, so what you are
// actually counting is every digit that is divisible by k
// in every number between a and b.
}
// This is the other part of the biggest problem. This line
// causes the infinite loop because you are modifying the
// variable you are using as the loop counter. Mutable state is
// tricky like that.
i = i / 10;
}
}
It's possible to re-write this with minimal changes, but there are some improvements you can make that will provide a more readable result. This code is untested, but does compile, and should get you most of the way there.
// Extracting this out into a function is often a good idea.
private int countOfNumbersWithAllDigitsDivisibleByN(final int modBy, final int start, final int end) {
int count = 0;
// I prefer += to ++, as each statement should do only one thing,
// it's easier to reason about
for (int i = start; i <= end; i += 1) {
// Pulling this into a separate function prevents leaking
// state, which was the bulk of the issue in the original.
// Ternary if adds 1 or 0, depending on the result of the
// method call. When the methods are named sensibly, I find
// this can be more readable than a regular if construct.
count += ifAllDigitsDivisibleByN(modBy, i) ? 1 : 0;
}
return count;
}
private boolean ifAllDigitsDivisibleByN(final int modBy, final int i) {
// For smaller numbers, this won't make much of a difference, but
// in principle, there's no real reason to check every instance of
// a particular digit.
for(Integer digit : uniqueDigitsInN(i)) {
if ( !isDigitDivisibleBy(modBy, digit) ) {
return false;
}
}
return true;
}
// The switch to Integer is to avoid Java's auto-boxing, which
// can get expensive inside of a tight loop.
private boolean isDigitDivisibleBy(final Integer modBy, final Integer digit) {
// Always include parens to group sub-expressions, forgetting the
// precedence rules between && and || is a good way to introduce
// bugs.
return digit == 0 || (digit % modBy == 0);
}
private Set<Integer> uniqueDigitsInN(final int number) {
// Sets are an easy and efficient way to cull duplicates.
Set<Integer> digitsInN = new HashSet<>();
for (int n = number; n != 0; n /= 10) {
digitsInN.add(n % 10);
}
return digitsInN;
}
I need to write a method that takes an array of integers and checks for every element if all its divisors (except the number itself and 1) are present in this array. If yes, the method will return true.
For example, the following array will return true:
4,5,10,2
I can't think of something efficient enough to be implemented. Could you guys help me out here?
I've been thinking to iterate through every element in the array, search for all of its divisors, put them on array, return the array and then compare to the elements in the original array.
This is a possible solution and it could work but I want to know of other possible solutions.
EDIT: Here is a code I've came up with but it is super slow. Could you guys help me optimise it a little bit?:
import java.util.Arrays;
public class Divisors {
public static void main(String[] args) {
int[] numbers = { 4, 5, 10, 2 };
boolean flag = true;
for (int num : numbers) {
if (num % 2 != 0) {
for (int subNum = 1; subNum < num / 2; num += 2) {
if(num%subNum == 0 && subNum != 1) {
if(!Arrays.asList(numbers).contains(subNum)) {
flag = false;
}
}
}
} else {
for (int subNum = 1; subNum < num / 2; num++) {
if(num%subNum == 0 && subNum != 1) {
if(!Arrays.asList(numbers).contains(subNum)) {
flag = false;
}
}
}
}
}
System.out.println("Result is: "+flag);
}
}
I think the following alogorithm solves your need. I have tested it on a few cases and it seems to work.
For example the array:
int[] set = {2, 3, 4, 5, 7, 10, 11, 15, 18, 35};
executes instantly giving the answer "true". Try removing the 7 which will give the answer "false".
You call it thus:
reduce(set, 0, 0)
The principle used is to iterative recursively through the array, reducing the array through factorization of the array by each element. If you find an element which is smaller than the last factor, it means it can't be factored. This only works if the array is sorted. Once you reach the end of the array, you know all elements have been factored.
private static boolean reduce (int[] set, int index, int factor) {
// NOTE: set must be a sorted set of integers
if (index == set.length) {
return true;
} else {
int divisor = set[index];
if (divisor != 1) {
if (divisor < factor) return false;
for (int i = index; i < set.length; i++) {
while ((set[i]%divisor) == 0) {
set[i] = set[i]/divisor;
}
}
return reduce(set, index+1, divisor);
} else {
return reduce(set, index+1, factor);
}
}
}
See if it works, let me know if you run into any problems.
1.Iterate through every element in the array
2. Find in for loop its divisor
3. While doing 2), check for every divisor if it is contained in the array. If false - return false.
I want to tell if an array of integers is alternating.
in JAVA.
For example:
a[]={1,-1,1,-1,1,-1} --> true
a[]={-1,1,-1,1,-1} --> true
a[]={1,-4,1-6,1} --> true
a[]={1,1,1,14,5,3,2} --> false
I have started to write some code that uses flags. For example if the current_is_positive=0 and else = 1, but I'm not getting anywhere. What is a good way to achieve this effect?
I think you mean alternating in sign, i.e. positive number, negative number, positive number, etc.?
You could use the following strategy:
Skip the first element.
For every other element, compare its sign with the sign of the previous element:
If they're different, the sequence is still alternating upto now - you should continue.
If they're the same sign, the sequence is not alternating. You can stop processing at this point.
As this sounds like a homework assignment, I'll leave it upto you to write the appropriate code in Java.
Here my solution:
This checks that element n+1 is the inverse of the element n.
public static void main(String[] args) {
int[] ints = {1, -1, 2, -1};
System.out.println(new Example().isArrayAlternating(ints));
}
public boolean isArrayAlternating(int[] ints) {
if (ints == null || ints.length % 2 != 0) {
return false;
}
for (int i = 0; i < ints.length - 1; i++) {
if (ints[i] != ints[i + 1]*(-1)) {
return false;
}
}
return true;
}
If you only wanted to check for positive number, negative number...n times, without paying attention to value:
public static void main(String[] args) {
int[] ints = {1, -1, 2, -1};
System.out.println(new Example().isArrayAlternating(ints));
}
public boolean isArrayAlternating(int[] ints) {
if (ints == null || ints.length % 2 != 0) {
return false;
}
for (int i = 0; i < ints.length - 1; i++) {
if (ints[i] >= 0 && ints[i + 1] >= 0 || ints[i] <= 0 && ints[i + 1] <= 0) {
return false;
}
}
return true;
}
You can simply check if all items are equal to the item two steps back. I don't know what language you are using, but for example using C# you could do it like this:
bool alternating = a.Skip(2).Where((n, i) => a[i] == n).Count() == a.Length - 2;
Edit:
So you want to check if the sign of the values are alternating, not the values?
Then just check the sign against the previous item:
bool alternating = a.Skip(1).Where((n,i) => Math.Sign(n) == -Math.Sign(a[i])).Count() == a.Length-1;
boolean prevPositive = arr[0] > 0, error = false;
for (int i = 1; i < arr.length; ++i) {
boolean current = arr[i] > 0;
if (current != prevPositive) {
current = prevPositive;
} else {
error = true;
break;
}
}
if (error)
System.out.println("No");
else
System.out.println("Yes");
private enum SIGN {
POSITIVE, NEGATIVE
};
public static boolean isAlternating(int... ints) {
SIGN last = null;
for (int i : ints) {
if (i >= 0) {
if (last == null) {
last = SIGN.POSITIVE;
} else {
if (last == SIGN.POSITIVE) {
return false;
} else {
last = SIGN.POSITIVE;
}
}
} else {
if (last == null) {
last = SIGN.NEGATIVE;
} else {
if (last == SIGN.NEGATIVE) {
return false;
} else {
last = SIGN.NEGATIVE;
}
}
}
}
return true;
}
Run through the array from index 1 till the end.
At each index, evaluate (a[i] > 0) == (a[i-1] > 0). If this is true, then your array is not alternating.
If you make it till the end without concluding it is not alternating, then it is alternating :)
Run a loop, from first index to maximum possible with a step of 2, to check for same sign.
Then again a loop, from 2nd index to maximum possible with a step of 2, to check for opposite sign, but all same.
So, loop from index - 0, 2, 4, 6, ...
then loop from index - 1, 3, 5, 7, ...
Then check that the multiplication of every number in both loop with the first number in that iteration should be positive.
int a[]={1,-1,1,-1,1,-1};
boolean alternating = true;
for (int i = 0; i < a.length; i = i + 2) {
if (a[i] * a[0] > 0) {
} else {
alternating = false;
}
}
for (int i = 1; i < a.length; i = i + 2) {
if (a[i] * a[1] > 0) {
} else {
alternating = false;
}
}
if (alternating) {
System.out.println("Array is alternating");
} else
System.out.println("Array is not alternating");
}
For i = 2 to n
check whether A[i-1] && A[i] are with diff sign..
in C++; return ((A[i-1] ^ A[i]) < 0).
Same explained here : http://www.youtube.com/watch?v=Z59REm2YKX0
EDIT
If an integer is negative, then the high order bit is 1. Otherwise, it's 0. You can check if two integers have different signs by XORing them together. If the signs are different, then the high order bit of the result will be 1. If they're the same, then the high order bit will be 0. Thus,
A XOR B < 0 is equivalent to "A and B have different signs"
Peter Ruderman