Finding no. of occurences of String in another String in smart way - java

I am stuck on this question after doing a lot of research. I want to find the no. of occurrences of String in another String but needed very smart approach.
a = "ASAD" str = "ASADASAD" expect output:2
b = "AAA" str2 = "AAAAAAAAAA" expect output:8
For example, considers these two strings. On the first line, 'a' occurs twice in 'str' while on the second line if you see the whole combinations of b occurs 8 times in str2. How to address both these challenges at once in the same code. I have coded these two scenarios separately but I want to do it in a smart way so one code can deal with all possible combinations of input strings. Here is my code.
For Case 1
Type1 = (LongString.split(SmallStr, -1).length-1);
for Case 2
while (Index < SmallStr.length())
{
String tester = LongString.substring(Index);
Counter = (tester.split(SmallStr,-1).length-1);
ans= Counter + ans;
lastIndex ++;
}
System.out.println(ans);

You might try something like this:
String myString = "ASADASAD"; // or "AAAAAAAAAA"
String stringToFind = "ASAD"; // or "AAA"
int offset = 0;
int count = 0;
while (offset < myString.length())
{
int index = myString.indexOf(stringToFind, offset);
if (index < 0)
break;
count++;
offset = index + 1;
}

Related

calculating the number of string occurances in another string

This is my assignment. I am not allowed to use if statements.
Write a program NumStrings.java that receives two strings through the command line as
input and then prints out the number of times the second string occurs as a substring in the
first.
My bad code:
public class Test {
public static void main(String[] args) {
String a = "HelloHelloHelloHello";
String b = "Hello";
int times = 0;
for(int i=0; i <= a.length()-5; i++){
for (int z=4; z<=(a.length()-1) && a.compareTo(b)==0; z++){
times = times +1;
}
}
System.out.print(times);
}
}
Here is the correct way to do it, using subString() (documentation here: https://docs.oracle.com/javase/7/docs/api/java/lang/String.html#substring(int)):
String a = "HelloHelloHelloHello";
String b = "Hello";
int times = 0;
for (int i = 0; i <= a.length() - b.length(); i++) {
String substring = a.subString(i, i + b.length());
if (substring.equals(b)) {
times = times + 1;
}
}
System.out.println(times);
And here is a way to do it without if statements... Which I don't recommend. But if you have to do it that way, this will work.
String a = "HelloHelloHelloHello";
String b = "Hello";
int times = 0;
for (int i = 0; i <= a.length() - b.length(); i++) {
String substring = a.substring(i, i + b.length());
for (int j = 0; substring.equals(b) && j < 1; j++) {
times = times + 1;
}
}
System.out.println(times);
Look at it this way: you don't have to count how often you find the second string in the first String, because you always have to check if you found it or not. So, to avoid all sorts of conditions or if statements, consider using firstString.split(secondString).
split(someString) will return you an array of remaining substrings once you "split" the base string everytime it finds your substring:
String first = "bababa";
String second = "a";
String[] substrings = first.split(second);
now substrings will look like this: ["b", "b", b"] because every a has been removed and the rest put in separate Strings.
Next you have to check the size of the array and you'll see how often your first String was split.
int count = substrings.length; // 3
However, this is not the end of it because we still have the following case:
String first = "bababaa";
With the above solution you would get an array of size 3: ["b", "b", "b"]. The last occurrence of a will only be removed without leaving any substring behind (not even an empty one '').
So you can take advantage of another (slightly different) split():
first.split(second, limit);
Where limit is the maximum number of occurrences the method tries to find. So how often can you find your second string in the first one? As many letters the first string has: int limit = first.length
first.split(second, first.length); // will produce [b, b, b, , ]
Can you see what happens? there are two empty strings at the end where there where two a. You get an array of substrings for everything that is found before or after the occurrence of the second String.
Naturally, when you split the string ba you would get ["b", ] so 2 substrings. But you don't care about the b just the "commas" in the middle (for every a a ,).
first.split(second, first.length).length -1; // that's how many commas there are, and thats how many second strings there are
EDIT
(thanks #saka1029 !) So, the "split" method still misses something when first="aaa" and second="aa" because it counts only 1 not 2 occurrences.
To correct that I thought of looping through the whole first string and checking only for the very first occurrence, and then removing the first letter and continuing (since OP already accepted another answer, I just post my code):
String first = "ZZZ";
String second = "ZZ";
int counter = 0; // counts the number of occurrences
int n = first.length(); // needs to be fixed, because we'll change the length of the first string in the loop
for(int i = 0; i < n; i++){ // check the first string letter by letter
String[] split = first.split(second, 2); // we want one substring and the rest (2 in total) like: ['', 'Z'] when we cut off the first 'ZZ'
counter += split.length - 1; // now add the number of occurrences (which will be either 0 or 1 in our case)
first = first.substring(1); // cut off the first letter of the first string and continue
}
System.out.println("counter = " + counter); // now we should get 3 for 'ZZZ'

Determine if a string contains a substring

I wanna know how I can find if string A has string B in it without breaking apart the whole string; also finding how much times it repeats using loops. BTW, it doesn't have to be case-sensitive. For example:
public static void main(String[] args) {
String st = abababajjjabababb;
String aba = null;
String st2 = aba;
int i = 0;
char ch = st.charAt(i);
int j;
for (j = 0;j < st2.length();j = j + 1){
for (int k = 0; k < st.length(); k = k + 1){
if(ch == st.charAt(j)) {
break;
}
}
if(j == st2.length()) {
}
}
System.out.println("the letters in s1 dont repeat in s2");
}
I know how to find if st2 repeats in st but I don't know how to program it to tell me how many times it repeats.
Thanks! I got my answer and I'm done with this program, thanks to you all that gave suggestions.
I know how to find if st2 repeats in st but I don't know how to program it to tell me how much times it repeats.
You could remove all occurrences of the substring and then divide by the length of the substring to get the number of occurrences.
String st = "abababajjjabababb";
String st2 = "aba";
int intOccurrences = (st.length() - st.replace(st2, "").length()) / st2.length();
Haven't used Java in a bit so I'm a little rusty.
For your example, this would return:
(17 - 8) / 3
= 3 occurrences
you can use count to count how many times it repeats. just declare count as a int. and have count ++ everytime it goes through the loop
You can also use StringUtils.countMatches from Apache commons lang to count the number of matches of a substring in a string:
int numOccurrences = StringUtils.countMatches(st, st2);

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

Unsure how to implement for loop

Hello I am having trouble implementing this function
Function:
Decompress the String s. Character in the string is preceded by a number. The number tells you how many times to repeat the letter. return a new string.
"3d1v0m" becomes "dddv"
I realize my code is incorrect thus far. I am unsure on how to fix it.
My code thus far is :
int start = 0;
for(int j = 0; j < s.length(); j++){
if (s.isDigit(charAt(s.indexOf(j)) == true){
Integer.parseInt(s.substring(0, s.index(j))
Assuming the input is in correct format, the following can be a simple code using for loop. Of course this is not a stylish code and you may write more concise and functional style code using Commons Lang or Guava.
StringBuilder builder = new StringBuilder();
for (int i = 0; i < s.length(); i += 2) {
final int n = Character.getNumericValue(s.charAt(i));
for (int j = 0; j < n; j++) {
builder.append(s.charAt(i + 1));
}
}
System.out.println(builder.toString());
Here is a solution you may like to use that uses Regex:
String query = "3d1v0m";
StringBuilder result = new StringBuilder();
String[] digitsA = query.split("\\D+");
String[] letterA = query.split("[0-9]+");
for (int arrIndex = 0; arrIndex < digitsA.length; arrIndex++)
{
for (int count = 0; count < Integer.parseInt(digitsA[arrIndex]); count++)
{
result.append(letterA[arrIndex + 1]);
}
}
System.out.println(result);
Output
dddv
This solution is scalable to support more than 1 digit numbers and more than 1 letter patterns.
i.e.
Input
3vs1a10m
Output
vsvsvsammmmmmmmmm
Though Nami's answer is terse and good. I'm still adding my solution for variety, built as a static method, which does not use a nested For loop, instead, it uses a While loop. And, it requires that the input string has even number of characters and every odd positioned character in the compressed string is a number.
public static String decompress_string(String compressed_string)
{
String decompressed_string = "";
for(int i=0; i<compressed_string.length(); i = i+2) //Skip by 2 characters in the compressed string
{
if(compressed_string.substring(i, i+1).matches("\\d")) //Check for a number at odd positions
{
int reps = Integer.parseInt(compressed_string.substring(i, i+1)); //Take the first number
String character = compressed_string.substring(i+1, i+2); //Take the next character in sequence
int count = 1;
while(count<=reps)//check if at least one repetition is required
{
decompressed_string = decompressed_string + character; //append the character to end of string
count++;
};
}
else
{
//In case the first character of the code pair is not a number
//Or when the string has uneven number of characters
return("Incorrect compressed string!!");
}
}
return decompressed_string;
}

Writing a word backwards using only 1 string converted to an array, a character, and an integer

I'm trying to create a code that writes an array backwards and can only use an array, character, and an integer. So far I have this, but it isn't doing anything. I'm a beginner at java.
import javax.swing.JOptionPane;
public class TestingArraysUsingOneArray
{
public static void main(String args[])
{
{
String str = JOptionPane.showInputDialog("Enter any text that you want to reverse.");
char[] charArray = str.toCharArray();
char current;
int a = 0;
for (int i = 0; i>=str.length()%2; i++) {
current = str.charAt(a);
charArray[a] = str.charAt(str.length()-a);
charArray[str.length()-a] = current;
a++;
}
System.out.println(charArray);
}
}
}
The output I'm getting is hello when I enter in hello. What do I need to change to get this program to work?
Your don't need half the code. I would try to make it as simple as possible. Try this
String str = ...
for(int i = str.length() - 1; i >= 0; i--)
System.out.print(str.chatAt(i));
System.out.println();
If the assignment says you have to reverse an array of chars you can do this.
String str = ...
char[] chars = str.toCharArray();
for(int i = 0; i < chars.length/2; i++) {
char ch = chars[i];
chars[i] = chars[chars.length - i - 1];
chars[chars.length - i - 1] = ch;
}
System.out.println(new String(chars));
As you can see this is needlessly complicated, so you would not do this. Another way you can do this if you don't want to use a loop is
String str = ...
System.out.println(new StringBuilder(str).reverse());
Well, for one thing, I think you want i<str.length()/2 - this will give you half the length. If you say i>=str.length()%2, you're getting the remainder when its length is divided by 2 - which is always either 1 or 0, and the loop continues as long as i is more than either 1 or 0. This should result in an infinite loop. Also, you don't need the variable a, as it is always equivalent to i. This, however, results in the string index being out of bounds sometimes, but I'll let you figure out how to solve that.
Your for loop is never entering because it should be i < str.length(), because at the moment when i is 0, the current check will immediately fail.
With that condition set, you need to change the two instances of str.length()-a to str.length()-a-1, because str.length-a when a is 0 will cause an StringIndexOutOfBoundException because the maximum index you can access is str.length-1.
Those are just corrections to the existing code. There's a better, more concise way of reversing the string suggested in another answer, which is the one you should accept.
What you want to do is replace the first character with the last and so on..
char[] charArray = str.toCharArray();
char current;
for (int i = 0; i < charArray.length / 2; i++) {
current = charArray[i];
charArray[i] = charArray[charArray.length - i - 1];
charArray[charArray.length - i - 1] = current;
}
The a int is completely redundant, and it would be a second int in your code - don't forget the variable in the for loop.

Categories