what does while (n-- != 0){} is doing in this code? - java

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

Related

Digit increment in Array

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;
}
}

Why will my for loop not read my last char of the string?

I am trying to write a basic java program to compress a java string from an input; such as aabbccdddd, into a2b2c2d4. The program does what I ask except it doesn't process the last char, I am getting an output of a2b2c2 instead of the a2b2c2d4. What am I doing wrong?
for(x = 0, y = 1; x<input.length()-1; x++)
{
if (input.charAt(x) != input.charAt(x+1) && count == 1)
{
System.out.print(input.charAt(x));
System.out.print(count);
}
else if (input.charAt(x) == input.charAt(x+y))
{
count++;
}
else if (input.charAt(x) != input.charAt(x+1) && count >= 2)
{
System.out.print(input.charAt(x));
System.out.print(count);
count = 1;
}
else
{
System.out.println("fail");
}
}
You print the count when the next character is not same as the current one. There is no next character for the last character. That is why it is not displayed in the output.
Approach 1
You should add following two lines after the loop:
System.out.print(input.charAt(input.length()-1));
System.out.println(count);
Approach 2
If you do not have problem with modifying the original input. You can add a additional character in the end of the input. This additional character must be a character which will never appear in the original string. Say it is #
Do this before beginning of the loop:
input += "#";
for(...)
The loop is incorrect, you have "-1" after input.length(). Try:
for(x = 0, y = 1; x<input.length(); x++) {
// CODE HERE...
}
Your for loop ends before you hit a condition that forces you to print out what's being buffered, ie. count of 4 for the current (last) character. You need to print out the last character and the current count after the loop.
The following should do what you want
public static void main(String[] args) throws Exception {
String input = "aabbccdddd";
int count= 1;
int x, y;
for (x = 0, y = 1; x < input.length() - 1; x++) {
char charAtX = input.charAt(x);
char charAtXPlus1 = input.charAt(x + 1);
if ( charAtX != charAtXPlus1 && count == 1) {
System.out.print(input.charAt(x));
System.out.print(count);
}
else if (charAtX == input.charAt(x + y)) {
count++;
}
else if (charAtX != charAtXPlus1 && count >= 2) {
System.out.print(input.charAt(x));
System.out.print(count);
count = 1;
} else {
System.out.println("fail");
}
}
System.out.print(input.charAt(x));
System.out.println(count);
}
You should learn how to use a proper debugger and use proper debugging techniques. For example, I've assigned the value returned by input.charAt(x) to a variable because we reuse that value in the various if-else conditions and because it's easier to see it in a debug window.
You are not able to get the desired result because of the condition
else if(input.charAt(x)!=input.charAt(x+1)&&count>=2)
that fails as there is not character at x+1 location.
So, you could add another condition to check if it's the last character and then go ahead with your code
while (input.charAt(x) != input.length()-1)

count uppercase chars in string recursively

I have to solve an exercise, counting all the uppercase chars in a String - recursively - Anyhow I thought I might have found a solution - but it won't work…
Probably you might help me? Thanks!
public static int CountCapitals(String s) {
int counter = 0;
// if (Character.isUpperCase(s.charAt(0)))counter+=1;
if (s.length() == 0)
return counter;
if (s.length() == 1 && s.charAt(0) < 65 && s.charAt(0) > 90)
return 0;
if (s.charAt(0) < 'A' && s.charAt(0) > 'Z') {
return CountCapitals(s.substring(1));
}
if (s.charAt(0) >= 'A' && s.charAt(0) <= 'Z')
counter++;
return CountCapitals(s.substring(1));
}
The problem with your code is the use of counter: each level of invocation has its own counter, initially set to zero. The ++ operator at the bottom has no effect.
You need to compute the result of this invocation based on the result of the previous invocation. Your base case (i.e. s.length() == 0) is fine; the rest of your code needs to change so that it returns whatever CountCapitals(s.substring(1)) when the first letter is non-capital; when the first letter is capital, your function should return 1 + CountCapitals(s.substring(1)).
You need to consider the case when the length of string is 1 and the only character is uppercase (in this case, you should return 1).
Also you need to pass in the counter as a parameter rather than expecting it to "carry over" into other function calls.
This recursion should do just what you want:
public static int countCapitals(String s) {
if (s.length() == 0) return 0;
int cap = Character.isUpperCase(s.charAt(0)) ? 1 : 0;
return countCapitals(s.substring(1)) + cap;
}
If this wasn't a home assignment, you could try an iterative approach which is about 5-10 times faster:
public static int countCapitals(String s) {
int count = 0;
for (int idx = 0; idx < s.length(); idx++) {
if (Character.isUpperCase(s.charAt(idx))) {
count++;
}
}
return count;
}
You don't really need to use a counter variable to keep track of the number of capitals. Instead, you can just the recursive calls, themselves, to keep track of the total:
public static int CountCapitals(String s)
{
if (s.length() == 1)
return (Character.isUpperCase(s.charAt(0)) ? 1 : 0);
else
return CountCapitals(s.substring(1)) +
(Character.isUpperCase(s.charAt(0)) ? 1 : 0);
}
If this is for an assignment and you have to use ASCII values, then fine, but if not, you really should just Character.isUpperCase(char c). In case you're not familiar with the conditional operator, it's defined as follows:
if(someExpression == true)
{
//output 1
}
else
{
//output 0
}
is represented succinctly as:
(someExpression == true) ? 1 : 0
NB:
In your example, counter is set to 0 at the beginning of each method call, so that's why it's not working. If you really want to use a counter, pass it as a parameter to the method instead, and update the parameter with each method call. When you get to the end of the String, simply return the parameter.
You try this
public class HelloWorld{
public static int isUpperCase(String str){
if(str.length()==0) return 0;
boolean check =Character.isUpperCase(str.charAt(0));
if(check){
return isUpperCase(str.substring(1))+1;
}
return isUpperCase(str.substring(1));
}
public static void main(String []args){
String n= "FSAsdsadASdcCa";
System.out.println(isUpperCase("FSAsdsadASdcCa"));
}
}

Very simple prime number test - I think I'm not understanding the for loop

I am practicing past exam papers for a basic java exam, and I am finding it difficult to make a for loop work for testing whether a number is prime. I don't want to complicate it by adding efficiency measures for larger numbers, just something that would at least work for 2 digit numbers.
At the moment it always returns false even if n IS a prime number.
I think my problem is that I am getting something wrong with the for loop itself and where to put the "return true;" and "return false;"... I'm sure it's a really basic mistake I'm making...
public boolean isPrime(int n) {
int i;
for (i = 2; i <= n; i++) {
if (n % i == 0) {
return false;
}
}
return true;
}
The reason I couldn't find help elsewhere on stackoverflow is because similar questions were asking for a more complicated implementation to have a more efficient way of doing it.
Your for loop has a little problem. It should be: -
for (i = 2; i < n; i++) // replace `i <= n` with `i < n`
Of course you don't want to check the remainder when n is divided by n. It will always give you 1.
In fact, you can even reduce the number of iterations by changing the condition to: - i <= n / 2. Since n can't be divided by a number greater than n / 2, except when we consider n, which we don't have to consider at all.
So, you can change your for loop to: -
for (i = 2; i <= n / 2; i++)
You can stop much earlier and skip through the loop faster with:
public boolean isPrime(long n) {
// fast even test.
if(n > 2 && (n & 1) == 0)
return false;
// only odd factors need to be tested up to n^0.5
for(int i = 3; i * i <= n; i += 2)
if (n % i == 0)
return false;
return true;
}
Error is i<=n
for (i = 2; i<n; i++){
You should write i < n, because the last iteration step will give you true.
public class PrimeNumberCheck {
private static int maxNumberToCheck = 100;
public PrimeNumberCheck() {
}
public static void main(String[] args) {
PrimeNumberCheck primeNumberCheck = new PrimeNumberCheck();
for(int ii=0;ii < maxNumberToCheck; ii++) {
boolean isPrimeNumber = primeNumberCheck.isPrime(ii);
System.out.println(ii + " is " + (isPrimeNumber == true ? "prime." : "not prime."));
}
}
private boolean isPrime(int numberToCheck) {
boolean isPrime = true;
if(numberToCheck < 2) {
isPrime = false;
}
for(int ii=2;ii<numberToCheck;ii++) {
if(numberToCheck%ii == 0) {
isPrime = false;
break;
}
}
return isPrime;
}
}
With this code number divisible by 3 will be skipped the for loop code initialization.
For loop iteration will also skip multiples of 3.
private static boolean isPrime(int n) {
if ((n > 2 && (n & 1) == 0) // check is it even
|| n <= 1 //check for -ve
|| (n > 3 && (n % 3 == 0))) { //check for 3 divisiable
return false;
}
int maxLookup = (int) Math.sqrt(n);
for (int i = 3; (i+2) <= maxLookup; i = i + 6) {
if (n % (i+2) == 0 || n % (i+4) == 0) {
return false;
}
}
return true;
}
You could also use some simple Math property for this in your for loop.
A number 'n' will be a prime number if and only if it is divisible by itself or 1.
If a number is not a prime number it will have two factors:
n = a * b
you can use the for loop to check till sqrt of the number 'n' instead of going all the way to 'n'. As in if 'a' and 'b' both are greater than the sqrt of the number 'n', a*b would be greater than 'n'. So at least one of the factors must be less than or equal to the square root.
so your loop would be something like below:
for(int i=2; i<=Math.sqrt(n); i++)
By doing this you would drastically reduce the run time complexity of the code.
I think it would come down to O(n/2).
One of the fastest way is looping only till the square root of n.
private static boolean isPrime(int n){
int square = (int)Math.ceil((Math.sqrt(n)));//find the square root
HashSet<Integer> nos = new HashSet<>();
for(int i=1;i<=square;i++){
if(n%i==0){
if(n/i==i){
nos.add(i);
}else{
nos.add(i);
int rem = n/i;
nos.add(rem);
}
}
}
return nos.size()==2;//if contains 1 and n then prime
}
You are checking i<=n.So when i==n, you will get 0 only and it will return false always.Try i<=(n/2).No need to check until i<n.
The mentioned above algorithm treats 1 as prime though it is not.
Hence here is the solution.
static boolean isPrime(int n) {
int perfect_modulo = 0;
boolean prime = false;
for ( int i = 1; i <= n; i++ ) {
if ( n % i == 0 ) {
perfect_modulo += 1;
}
}
if ( perfect_modulo == 2 ) {
prime = true;
}
return prime;
}
Doing it the Java 8 way is nicer and cleaner
private static boolean isPrimeA(final int number) {
return IntStream
.rangeClosed(2, number/2)
.noneMatch(i -> number%i == 0);
}

How can I tell if an array of integers is an alternating array?

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

Categories

Resources