Can someone please explain these two simple loops? - java

Hello I have a problem with understanding the following code.
public static void main(String[] args) {
String vstup = "DEN DOBRY";
String vystup = "";
int i = 2;
do {
vystup = vystup + vstup.charAt(i);
i++;
} while (vystup.charAt(0)>=vstup.charAt(i));
System.out.println(vystup);
}
Why does this one print out "N D"?
And the second one:
public static void main(String[] args) {
String vstup = "Mama má emu.";
String vystup = "";
for (int i = 0;i<vstup.length();i++)
if ((i % 3) == 1) vystup = vystup.concat(vstup.substring(i, i+2));
System.out.println(vystup);
}
Why does this one print out "am m eu."?

Issues
The first part of the code can throw index out of bounds exception(or similar)
The second part of the code can also throw similar exception
Example Input for 1st case: ZYXWV
do {
vystup = vystup + vstup.charAt(i);
i++;
} while (vystup.charAt(0) >= vstup.charAt(i)); // i can get invalid
Example Input for 2nd case: ab
if ((i % 3) == 1) vystup = vystup.concat(vstup.substring(i, i+2)); // i + 2 can be invalid index
What 1st does?
Starts from 2nd index i = 2
concatenates character at index to output and increments index by 1
repeat step 2 if character at current (incremented) index is lesser than or equal to the first character(0th index) of the string
By >=, it compares the code points (numeric values of the character)
What 2nd does?
Starting from 2nd character(1 index), selects 2 adjacent characters(2 and 3rd character)
repeat by moving 3 character (from 2nd character exclusive) to right
str: M a m a m á e m u .
index: 0 1 2 3 4 5 6 7 8 9 10 11
i%3==1 i i+1 i i+1 i i+1 i i+1
I hope this helps you.

Related

Find the smallest binary number without continous 1

So here is the thing.
I have to write code to show a binary number X's next smallest "code-X number" which is bigger than binary number X.
code-X number is a binary number which have no continuously 1. For example: 1100 is not a code X number because it has 11, and 1001001001 is a code-X number
Here is my code
String a = "11001110101010";
String b = "";
int d = 0;
for(int i = a.length()-1; i>0;i--){
if(a.charAt(i) == '1' && a.charAt(i-1)=='1'){
while(a.charAt(i)=='1'){
b = b + '0';
if(i!=0){i--;}
d++;
}
}
b = b + a.charAt(i);
}
StringBuffer c = new StringBuffer(b);
System.out.println(c.reverse());
I plan on copy the binary string to string b, replace every '1' which next i is '1' into '0' and insert an '1'
like:
1100 ---> 10000
but i have no idea how to do it :)
May you help me some how? Thanks
Try this. This handles arbitrary length bit strings. The algorithm is as follows.
Needed to conditionally modify last two bits to force a change if the number is not a codeEx number. This ensures it will be higher. Thanks to John Mitchell for this observation.
Starting from the left, find the first group of 1's. e.g 0110
If not at the beginning replace it with 100 to get 1000
Otherwise, insert 1 at the beginning.
In all cases, replace everything to the right of the grouping with 0's.
String x = "10000101000000000001000001000000001111000000000000110000000000011011";
System.out.println(x.length());
String result = codeX(x);
System.out.println(x);
System.out.println(result);
public static String codeX(String bitStr) {
StringBuilder sb = new StringBuilder(bitStr);
int i = 0;
int len = sb.length();
// Make adjust to ensure new number is larger than
// original. If the word ends in 00 or 10, then adding one will
// increase the value in all cases. If it ends in 01
// then replacing with 10 will do the same. Once done
// the algorithm takes over to find the next CodeX number.
if (s.equals("01")) {
sb.replace(len - 2, len, "10");
} else {
sb.replace(len- 1, len, "1");
}
while ((i = sb.indexOf("11")) >= 0) {
sb.replace(i, len, "0".repeat(len - i));
if (i != 0) {
sb.replace(i - 1, i + 2, "100");
} else {
sb.insert(i, "1");
}
}
String str = sb.toString();
i = str.indexOf("1");
return i >= 0 ? str.substring(i) : str;
}
Prints
10000101000000000001000001000000001111000000000000110000000000011011
10000101000000000001000001000000010000000000000000000000000000000000
Using raw binary you can use the following.
public static void main(String[] args) {
long l = 0b1000010100000000010000010000000011110000000000110000000000011011L;
System.out.println(
Long.toBinaryString(nextX(l)));
}
public static long nextX(long l) {
long l2 = l >>> 1;
long next = Long.highestOneBit(l & l2);
long cutoff = next << 1;
long mask = ~(cutoff - 1);
return (l & mask) | cutoff;
}
prints
1000010100000000010000010000000010000000000000000000000000000000
EDIT: Based on #WJS correct way to find the smallest value just larger.
This is a slight expansion WJS' 99% correct answer.
There is just one thing missing, the number is not incremented if there are no consecutive 1's in the original X string.
This modification to the main method handles that.
Edit; Added an else {}. Starting from the end of the string, all digits should be inverted until a 0 is found. Then we change it to a 1 and break before passing the resulting string to WJS' codeX function.
(codeX version does not include sb.replace(len-2,len,"11");)
public static void main(String[] args) {
String x = "10100";
StringBuilder sb = new StringBuilder(x);
if (!x.contains("11")) {
for (int i = sb.length()-1; i >= 0; i--) {
if (sb.charAt(i) == '0') {
sb.setCharAt(i, '1');
break;
} else {
sb.setCharAt(i, '0');
}
}
}
String result = codeX(sb.toString());
System.out.println(x);
System.out.println(result);
}

How to print every third character of a string? java

I am trying to print every 3rd character of a string so an example would be:
123456 returns 36
But my code below returns 14
public String getEveryThird() {
String newString = "";
for (int i = 0; i < string.length(); i++) {
if (i % 3 == 0) {
newString += (string.charAt(i));
}
}
return newString;
}
Good try. The only problem is you choose the wrong remainder of the division since elements start from 0.
Try this condition:
if (i % 3 == 2)
Your current approach is off in the remainder (as already mentioned), however a much faster approach is available; instead of iterating every character, start with the third character and increase your index by three on each iteration. Remember, the third character is at index two (0, 1, 2). Also, it is better to use a StringBuilder over String concatenation (as Java String is immutable). Like,
StringBuilder sb = new StringBuilder();
for (int i = 2; i < string.length(); i += 3) {
sb.append(string.charAt(i));
}
return sb.toString();
It is returning 14 because your loop starts in 0 and 0 % 0 is equal to 0.
Then, when it gets to number 4, the index i is equal to 3, and again 3 % 3 = 0.
Try something like:
if((i+1) % 3 == 0){
newString += (string.charAt(i));
}

segregate list elements with different groups in java

Suppose I have one list which always has the count of even number. Now I want to segregate the list with different group indexes with below conditions,
1) First element (1st element) with one index (EX: 1)
2) Next two elements with same index (Ex: 2nd, 3rd element with index 2,
4th and 5th element with index 3)
3) Last element(6th element) with index 4
I tried with nested for loops to achieve the same, but didn't get the expected output.
Any help is appreciated.
Sample Input:
[2,3,53,52,33,12,44,66]
Sample Output:
2 - 1
3 - 2
53 - 2
52 - 3
33 - 3
12 - 4
44 - 4
66 - 5
I have implemented this using the two additional variables z and count, I am
incrementing z only if the count%2 is 0, and at-last we need to check if the
size-1 is equal to the i variable for the third condition.
Also, for the first condition I am printing the arraylist value at first index and z variable value at i iff the i counter value is 0.
Please see the below code that I have simulated for your input list that I
have added manually ! Please use the link to test :
http://rextester.com/ESYF23501
import javafx.collections.ArrayChangeListener;
import java.util.ArrayList;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
ArrayList<Integer> a= new ArrayList<Integer>();
a.add(2);
a.add(3);
a.add(53);
a.add(52);
a.add(33);
a.add(12);
a.add(44);
a.add(66);
int i = 0;
int z = 2;
//Count to group the middle number by checking its value with respect to mod 2
int count = 0;
for(i = 0; i < a.size(); i++)
{
if(i == 0 )
{
z = i+1;
System.out.println(""+a.get(i)+" " + "" +z+"" );
}
if(i > 0 && i != (a.size() -1))
{
//Increament z if the count is even so that we print the group for two times
if(count%2 == 0)
{
z++;
}
System.out.println(""+a.get(i)+"" +" "+ ""+z+"" );
count ++;
}
if(i == a.size() -1 )
{
z++;
System.out.println(""+a.get(i)+"" +" "+ ""+z+"" );
}
}
}
}
This should work correctly if I understood your question right:
System.out.println(elements.get(0) + " - 1"); // Prints the first number, which has the value of 1
int value = 2; // Value corresponding to the number
for (int i = 1; i < elements.size(); i++) { // Loops through the list starting at second element (index of 1)
System.out.println(elements.get(i) + " - " + value); // Prints the number and the value
if (i % 2 == 0) value++; // Increases the value every two loops
}
It starts by printing out the first number and 1, which as you described always corresponds to each other. Then it loops through the list of numbers starting at the second number (i = 1), and prints out each number and the corresponding value. The value increases every two loops, which is every time the loop number is divisible by 2 (i % 2).

How to write a program that returns number of occurrences of a string in another string? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
So I'm new to programming. I'm using java. Right now I have an assignment I can't solve on a website that teaches java.
This is the assignment
Write a program that returns number of occurrences of a string in another string.
E.g
Input:
First String: the
Second String: The students are working hard in the faculty of Engineering because they love it
Output:
3
Note: You should only use nested loops. Don’t use methods like indexOf or substring.
Ienter image description here reached to the code the calculate the number of occurrences but it failed in case of repeated letters
E.g
input:
First String : ooo
Second String : wooooooooooooooooooooow
Output : 21
It's supposed to be 7 since the ooo have only repeated 7 times
This question can be simply solved by using z-function in linear time.
int NumberOfcopies(String t, String h){
// t = the first string i.e "ooo"
// h = the second string i.e "wooooooooooooooooooooow"
String s = t + "$" + h; // adding a sentinel character in between
int n = s.length(); // length of new string
int[] z = new int[n]; // z array
// Code ref : http://e-maxx-eng.github.io/string/z-function.html
int l = 0, r = 0;
for (int i = 1; i < n; i++){
if (i <= r)
z[i] = Math.min(r - i + 1, z[i - 1]);
while (i + z[i] < n && s.charAt(z[i]) == s.charAt(i + z[i]))
++z[i];
if (i + z[i] - 1 > r){
l = i;
r = i + z[i] - 1;
}
}
//checking for all the occurance of string t in string h
int res = 0;
for (int i = t.length() + 1; i < n; ){
if (z[i] == t.length()){
//A copy is found so skip next t.length chars
i += t.length();
++res;
}
else ++i;
}
System.out.println("Number of Occurance : " + res);
return res;
}
The Z-function for this string is an array of length n where
the i-th element is equal to the greatest number of characters
starting from the position i that coincide with the first
characters of s.
This can be exploited to find the number of occurrences of a string t in another string h. Suppose we join the string t and h with a sentinel character in between (Sentinel character is a character that does not occur in either of the strings) to form a new string s.
Lets us calculate the z function in array z[].
Now lets start searching from the character after the sentinel character i.e. the characters of string h. For i-th character in string h ( such that i-th character belongs to string s) if z[i] equals to length of string t (the pattern) then it implies that starting from i-th char, the t.length() chars are same as the first t.length() chars of string s which is what the string t equals.
example :
t = ab
h = aaabaab
s = a b $ a a a b a a b
z = 0 0 0 1 1 2 0 1 2 0
i = 0 1 2 3 4 5 6 7 8 9
for i = 5 we can see that z[i] == t.length(), that means we found a copy. Now to prevent Overlapping solutions, we skip the t.length() chars hence now i = 7
continuing this will get you the result.

Longest Snake Sequence

Question : A set of numbers separated by space is passed as input. The program must print the largest snake sequence present in the numbers. A snake sequence is made up of adjacent numbers such that for each number, the number on the right or left is +1 or -1 of it's value. If multiple snake sequences of maximum length is possible print the snake sequence appearing in the natural input order.
Example Input/Output 1:
Input:
5 6 7 9 8 8
Output:
5 6 7 8 9 8
8 9 8 7 6 5
Example Input/Output 2:
Input:
9 8 7 5 3 0 1 -2 -3 1 2
Output:
3 2 1 0 1
void doPermute(int[] in, StringBuffer out, boolean[] used, int length, int level, StringBuffer max) {
if (level == length) {
int count = 0;
for (int i = 1; i < out.length(); i++) {
if (Math.abs(Character.getNumericValue(out.charAt(i)) - Character.getNumericValue(out.charAt(i - 1))) != 1) {
//System.out.println(Character.getNumericValue(i) - Character.getNumericValue(i - 1) + " " + i + " yes");
count++;
break;
}
}
if (count == 0) {
max.append(out + " ");
}
return;
}
for (int i = 0; i < length; ++i) {
if (used[i]) {
continue;
}
out.append(in[i]);
used[i] = true;
doPermute(in, out, used, length, level + 1, max);
used[i] = false;
out.setLength(out.length() - 1);
}
}
As i am using StringBuffer my code passed the test cases that contains positive value (first test case) but failed in test cases containing negative values(second test case).
Update:-
I replaced stringbuffer with Integer[] and made few changes.it works fine for smaller inputs of length 8 or 9. How to make it fast for larger inputs of length 13 to 15?
Have you tried doing the process using an array of integers?
Scanner sc = new Scanner(System.in);
String s = sc.nextLine(); //The numbers entered in string format separated by spaces
String ss = s.split(" "); //Numbers separated by space will be put as individual numbers in a String array but each number is still in string format
int l = ss.length, i = 0;
int[] n = new int[l]; //The integer array which will store the values
for(i = 0; i < l; i++)
{
n[i] = Integer.parseInt(ss[i]); //Has integers now instead of string numbers
}
There might be creation of a few extra arrays but then calling the Character.getNumericValue() function repeatedly can also reduce efficiency. Also might solve your StringBuffer problem.
But SkillRack is very annoying anyway.
Your comparison isn't finding adjacent numbers for negative values.
For example: Abs(-2) - (-3) = 5 but -2 and -3 should be adjacent.
Ok. I see you're parsing - and digit separately.
Given the requirement of what a snake sequence is, the longest snake sequence for "5 6 7 9 8 8" is "5 6 7". The output listed above does not correspond to the definition: " adjacent numbers such that for each number, the number on the right or left is +1 or -1 of it's value". How does "5 6 7 8 9 8" meet the definition of snake sequence for "5 6 7 9 8 8"? Sorry I couldn't help.
You might want to parse the code into Integers, store the longest sequences in a map).
#Test
public void testSnake(){
String t2 = "9 8 7 5 3 0 1 -2 -3 1 2";
List<String> numsStr = Arrays.asList(t2.split(" "));
List<Integer> nums = new ArrayList();
HashMap<Integer,List<Integer> > numMap = new HashMap();
numsStr.forEach((s) -> {
Integer val = Integer.decode(s);
nums.add(val);
});
nums.forEach((num) -> {
System.out.println("num: " + num);
// track longest sequence, store in numMap
});
// Print numMap
}

Categories