Using if else in For Loop increment - java

I have a problem in Java:
Given a string, return a string made of the chars at indexes 0,1,4,5,8,9...
I know how to solve it, however I was wondering if it's possible for me to use if-else in for-loop increment itself, for example:
for (int i=0; i < str.length(); if (i%4==0) i++, else i+=3){
result += str.charAt(i);
}
Can we do something like that?

You can't use an if there but you can use a ternary operator
for (int i = 0; i < str.length(); i += i%4 == 0 ? 1 : 3) {
result += str.charAt(i);
}

Putting it simply, you want two characters from every 4th position starting from 0. You can use the following code for that:
StringBuilder builder = new StringBuilder();
for (int i = 0; i < safeLength; i += 4){
builder.Append(str.substring(i, i + 2));
}
Unlike the answer that you have accepted, in this answer there is:
no obfuscation;
the intent is very clear; and,
most importantly, no if-else or ternary operator.
Update: I'm aware of the possibility of IndexOutOfBoundsException but because I wanted to keep the attention on core logic only, I didn't add that check. Here is the code that needs to be added to avoid the exceptional cases:
Put following code above the for loop:
int safeLength = str.Length();
bool lengthCorrectionWasNeeded = (str.length() - 1) % 4 == 0;
if (lengthCorrectionWasNeeded) safeLength--;
Put following code below the for loop:
if (lengthCorrectionWasNeeded) builder.append(str.substring(str.length() - 2));
At the end builder.ToString() will contain the desired string.

As for the issue "Using if else in For Loop increment", I agree with Manos's answer.
The following are some of my suggestion.
In my opinion, it is important that codes are clear and clean.
And it is a good practice that extract str.length() to a local variable instead of 'calculating' it in every loop.
And if you are building a string by appending it lots of time, StringBuilder is a good choice.
String str = "this is your string ...";
int length = str.length();
StringBuilder builder = new StringBuilder();
for (int i = 0; i < length ; i += (i%4 == 0 ? 1 : 3)){
builder.append(str.charAt(i));
}
String result = builder.toString();

Related

How to separate a string into substrings of two characters

I am trying to split strings in substrings of two chararters for example for the input: "ABCDE" i want to get the substrings "AB" "BC" "CD" "DE".
I tried with this:
String route = "ABCDE";
int i = 0;
while(i < route.length()) {
String sub = route.substring(i,i+2);
System.out.println(sub);
i++;
}
but the index (i) gets out of range int the last iteration and causes an error.
is there any way to do this without getting the index (i) out of range ?
You need to change the loop condition.
while(i < route.length()-1)
In your code i goes till (length-1) and than in the substring(i,i+2) function you gives end index i+2. It is higher than largest index of string.
Also, As far as I know calling a library function in a loop condition is not considered a good practice.
In each iteration you call this function which is time consuming.
control goes to that subroutine in each iteration.
A good alternative to this would be to store the length in a variable and use that in a condition.
int temp = route.length()-1;
while(i<temp){
This should work fine
String route = "ABCDE";
if( route.length() > 2){
int i = 0;
do {
String res = route.substring(i,i+2);
System.out.println(res);
i++;
} while (i + 1 < route.length());
}
else{
System.out.println(route);
}
Edit: Added boundary case for the string has length less than 2
Add check for the size of the string to trap the error:
String route = "ABCDE";
int i = 0;
while(i < route.length()) {
if(i < route.length() - 1) {
String sub = route.substring(i,i+2);
System.out.println(sub);
} else {
String sub = route.substring(i,i+1);
System.out.println(sub);
i++;
}
So whenever the i counter almost close to string size, get the last char.
You are getting an StringIndexOutOfBoundsException because you are trying to access an index of the String that doesn't exist.
To fix this, change your loop condition from
while(i < route.length())
to
while(i < route.length() - 1)
Without the -1 on the last iteration of the while loop i + 2 is equal to 71 which is out of the Strings bounds.
Another (cleaner) solution to this problem is a for loop:
for(int i = 0; i < route.length() - 1; i++) {
System.out.println(route.substring(j, j + 2));
}
The for loop in this situation is just shorter as the declaration, conditional, and increment statements are all in one line.
1: This 7 reduces to 6 since the endIndex of substring is exclusive.
As denis already pointed out, the bug in the code is in the loop condition.
Should be: while(i < route.length() - 1)
. However, how about simplifying this logic to use a for loop.
String route = "ABCDE";
for (int i=0; i+2<=route.length(); i++)
System.out.println(route.substring(i,i+2));
you can not use
i < route.length(),because when i = 5, String sub = route.substring(i,i+2); the i+2=7,is out of index,so use i<route.length instead

Java Code output If input is "aabbba" then output should be "a2b3a1" [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I am doing one simple java code where if
input is : "aabbba"
then
output should be: "a2b3a1"
I have done the below coding but missing somewhere. So let me know my mistake.
public class Test {
public static void main(String[] args) {
String str = "aabbba";
int count = 1;
for (int i = 0; i < str.length(); i = i + count) {
count = 1;
for (int j = i + 1; j < str.length(); j++) {
if (str.charAt(i) == str.charAt(j)) {
count = count + 1;
} else {
System.out.println(str.charAt(i) + "" + count);
break;
}
}//end of inner for
}//end of outer for
}//end of main
}//end of class
Actually you have too much code, You only need one loop, and you should be comparing the letter to the previous one, not attempting to compare each letter to every letter after it.
If you are confused about what your program is doing, the best place to start is to use your debugger to step through the code.
for(int i = 0, count = 1; i < str.length(); i++, count++) {
char ch = str.charAt(i);
char next = i + 1 < str.length() ? str.charAt(i + 1) : (char) -1;
if (ch != next) {
System.out.print("" + ch + count);
count = 0;
}
}
Using your effort and code, you simply did put the print to the wrong place
String str = "aabbba";
int count = 1;
for(int i = 0; i <str.length();i=i+count){
count =1;
for(int j = i+1; j<str.length();j++){
if(str.charAt(i) == str.charAt(j)){
count = count+1;
}
else{
break;
}
}
// Print here otherwise you will miss the last group of letters
// Also if you just want one line use .print instead of println
System.out.print(str.charAt(i)+""+count);
}
Using Java-8 and my StreamEx library it's a one-liner:
String input = "aabbba";
String result = IntStreamEx.ofChars(input).mapToObj(ch -> (char)ch)
.runLengths().join("").joining();
Step-by step:
IntStreamEx.ofChars(input): create IntStreamEx (enhanced IntStream) where each element is the corresponding character of input line.
.mapToObj(ch -> (char)ch): transform to StreamEx<Character> (enhanced Stream<Character>) where each element is the Character object.
.runLengths(): convert to EntryStream<Character, Long> (enhanced Stream<Map.Entry<Character, Long>>) where keys are Character objects and values are counts of equal adjacent characters.
.join(""): convert to StreamEx<String>, joining keys (characters) and values (counts) via given empty separator.
.joining(): final reduction to the resulting string without additional separators.
You're just missing the print of the last group of letters. you only print inside the loop once you found a different letter, you should take into account the last group of letters that has no "different letter" after it
I would suggest using a StringBuilder:
public String myOutput(String str) {
if (str == null || str.length() == 0)
return str;
StringBuilder sb = new StringBuilder();
int count = 1;
char currentChar;
for (int i = 0; i < str.length() - 1; i++) {
currentChar = str.charAt(i);
if (currentChar == str.charAt(i+1)) {
count++;
} else {
sb.append(currentChar);
sb.append(String.valueOf(count));
count = 1;
}
}
sb.append(str.charAt(str.length()-1));
sb.append(String.valueOf(count));
return sb.toString();
}
You only need 1 loop
System.out.println() will cause your output to have line break. You better use System.out.print(). Now your currrent code is resulting :
a2
b3

Find char in string that is a digit and larger or equal to 2

I have a string that contains numbers like: 02101403101303101303140
how can I iterate the string to check whether the number in string is >= 2 and remember that number's index in array or list for further processing?
the further processing should be replacing substrings.
for example: the iterator found number 2 and remembers the index of this character.
Now it takes the next character from 2 and remembers this character index also.
Now it is possible to replace the substring.
Let's say there is 21. Now I want this to become 11
Or lets say there is 60, this should be replaced with 000000.
First number is indicator of "how many" and the second number is "what".
Or is there a better way to remember and replace certain substrings in that way?
Thank you in advance.
There you go. but remember to atleast try next time
String str = "02101403101303101303140";
StringBuilder sb = new StringBuilder();
for(int i=0; i < str.length(); i+=2)
for(int j =0; j < Integer.parseInt(String.valueOf(str.charAt(i))); j++)
sb.append(str.charAt(i+1));
System.out.print(sb.toString());
Not sure if I'm understanding well your question, you could try something like this:
String mystring = "02101403101303101303140";
String target = "21";
String replacement = "11"
String newString = mystring.replace(target, replacement);
String str = "02101403101303101303140";
StringBuilder sb = new StringBuilder();
for (int i = 0; i < str.length(); i++) {
if(Integer.parseInt(String.valueOf(str.charAt(i))) >= 2) {
int temp = Integer.parseInt(String.valueOf(str.charAt(i))) - 1;
for (int j = 0; j < temp ; j++) {
sb.append(str.charAt(i+1));
}
}
else {
sb.append(str.charAt(i));
}
}
System.out.println(sb.toString());
This would produce: 01101000011101000111010001110000 which is binary for "http" (without quotes).
Thank you all! What I really needed was a push to right direction and thank zubergu for that. Also fr34k gave the best answer!

How to capitalize every other letter in a string efficiently in java?

I'm currently working on a problem in code hunt level 6.02 which asks me to capitalize every other letter in a String. I have tried doing it with toCharArray + StringBuilder in for loops. It works, but it's not good enough. I still can't get the perfect score for the problem. I'm running out of ideas. Any help will be greatly appreciated.
Note: This is my first post on stack overflow. So if I miss anything or ask question in a wrong way. Pls feel free to point it out for me. Thx.
s is the input string
Attempt 1:
char [] words = s.toCharArray();
for (int i = 0; i < words.length; i +=2){
words[i] = Character.toUpperCase(words[i]);
}
return new String(words);
Attempt 2:
StringBuilder result = new StringBuilder(s);
for (int i = 0; i < result.length(); i +=2){
result.replace(i, i + 1, result.substring(i,i + 1).toUpperCase());
}
return result.toString();
Input: "iaiaa"
Expected output: "IaIaA"
In both of your attempts, you're going through the characters 2 1/2 times.
Taking your second attempt;
StringBuilder result = new StringBuilder(s);
for (int i = 0; i < result.length(); i +=2){
result.replace(i, i + 1, result.substring(i,i + 1).toUpperCase());
}
return result.toString();
The first line copies all the characters, and your last line copies all the characters. Your for loop goes through half the characters, for a total of 2 1/2 sets of characters.
I don't know if this is faster, but here's my attempt.
String r = "";
for (int i = 0; i < s.length; i++) {
if (i % 2 == 0) {
r += s.substring(i, i + 1).toUpperCase();
} else {
r += s.substring(i, i + 1);
}
}
return r;
I realize that this looks like a lot of intermediate Strings are created, but string concatenation has improved since Java 1.7.
I don't know how efficient this really is, but this does the trick for capitalizing the first letter and every other letter after.
String sentence = "i want to manipulate this string";
char[] array = new char[] {};
array = sentence.toCharArray(); //put the sentence into a character array
for (int i = 0; i < array.length; i += 2) {
if (array[i] == ' ') { //if the character is blank, move to the next index
i++;
}
array[i] = Character.toUpperCase(array[i]); //capitalize
}
sentence = new String(array); //revert array back to String
System.out.println(sentence); //display

Comparing two unknown strings and finding match [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
If I have
String x = "test";
String s = "tastaegasghet;
you can find t e s t inside the string s. The naive way of doing this with a known string would be something like this:
.*t+.*e+.*s+.*t+.*
This will return true if we can find the letters t e s t in order and any characters inbetween. I want to do the same thing but with two unknown Strings x and s or in otherwords, String s and x can be anything. I don't want something hard coded but something for general use instead.
This is the pseudocode for looping solution:
function (
needle, // x
haystack // s
) {
j = 0
for (i = 0; i < haystack.length && j < needle.length; i++) {
if (haystack[i] == needle[j]) {
j++
}
}
return j == needle.length
}
You only need to loop through each character in haystack string and advance the pointer in needle string when you find a matching character. If the pointer reaches the end of the needle string, it means the needle string can be found as a subsequence of the haystack string.
A small optimization you can do is checking needle.length <= haystack.length before starting the loop.
Just for fun
If you want to go the Cthulhu's way, you can use this construction:
(?>.*?t)(?>.*?e)(?>.*?s)(?>.*?t).*+
This doesn't have the risk of catastrophic backtracking, and should work similar to the loop above (linear complexity), except that it has a lot of overhead compiling and matching the regex.
It's not that hard to just use a loop.
String x = "test";
String s = "tastaegasghet";
int index = 0;
for(int i = 0; i < s.length() && index < x.length(); i++){
if(s.charAt(i) == x.charAt(index)) index++;
}
boolean exists = index == x.length();
System.out.println(exists);
This should be significantly faster than a regex, at least for longer input.
I'd make a simple function, with a loop, instead of a regex. Something like the following:
public boolean containsLetters(string a, string b)
{
char[] aArray = a.toCharArray();
char[] bArray = b.toCharArray();
int lettersFound = 0, lastLocation = 0;
for (int i = 0; i < aArray.length; i++)
{
for (lastLocation=lastLocation; lastLocation < bArray.length; lastLocation++)
{
if (aArray[i] == bArray[lastLocation])
{
lettersFound++;
break;
}
}
}
return lettersFound == aArray.length;
}
The inner for loop stops the first time it finds the letter. It doens't need to determine if it appears more than once since the function returns a boolean, so this saves some time for large strings. It will only return true if it finds them in order. It remembers the index of the last letter it found, and searches through for the next letter from that location.
You can use the Pattern class for this.
String x= "yourValue";
Pattern pattern = Pattern.compile(Mention your pattern here);
Matcher matcher = pattern.matcher(x);
if (matcher.find()) {
System.out.println(matcher.group(0)); //prints /{item}/
} else {
System.out.println("Match not found");
}
Java code without using any built-in function
String s1 = "test";
String s2 = "tastaegasghets";
char ch[] = new char[s1.length()];
char ch1[] = new char[s2.length()];
int k = 0;
for (int i = 0; i < s1.length(); i++) {
ch[i] = s1.charAt(i);
for (int j = 0; j < s2.length(); j++) {
ch1[j] = s2.charAt(j);
if (ch[i] == ch1[j]) {
k++;
break;
}
}
}
if (k == s1.length()) {
System.out.println("true");
} else {
System.out.println("false");
}

Categories