calculating the number of string occurances in another string - java

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'

Related

Java String to Substring match program error

This program is intended to match a string to another string and calculate the number common substrings they share. For some reason, it always prints the same incorrect values. Using the same methods, how can I make this code work as I intended it to?
public static void main(String[] args) {
String secret = "word";
String guess = "gzek";
int count = 0;
int length = secret.length();
int guess_length = guess.length();
for(int i=0;i<length-1;i++){
if(secret.substring(i, i).equals(guess.substring(i, i))){
count ++;
}
}
System.out.println(count);
}
According to its JavaDoc, the end index parameter of the substring() method is exclusive:
#param beginIndex the beginning index, inclusive.
#param endIndex the ending index, exclusive.
This means that secret.substring(i, i) returns the sub-string from i to i-1, which is always the empty string "". Therefore, secret.substring(i, i).equals(guess.substring(i, i)) always compares "" with "" and is always true. Your code effectively counts the number of characters in guess.
If you want to compute all sub-strings of a string s, you need two loops, one for the start index and one for the end index:
for (int i = 0; i < s.length(); i++) {
for (int j = i; j < s.length(); j++) {
String substring = s.substring(i, j + 1);
// further code ...
}
}
Note that this only computes the sub-strings of one string. If I understood your question correctly, you want to compute all common sub-strings of two strings. To do this, you will need a total of four nested loops. This is going to be very slow even for small strings. There are of course much faster approaches, but they are also more complex.

Printing words from an array in reverse

I have a task where I need to print words from an array in reverse(the word itself). This is what the task states :
Create an array of words called ‘wordList’ and assign the values ‘Stressed’, ‘Parts’, ‘Straw’, ‘Keep’, ‘Wolf’
Create a string called ‘reversedWord’ and do not assign it a value.
Similar to the above challenge, however, instead of reversing a sentence, reverse the order of the letters
within each string.
a. You will need to create a for-loop to access each word in turn. Immediately within the loop set
‘reversedWord = “”;’
b. Then create another for-loop inside of the first one to iterate backwards through the current
word. Update the value of ‘reversedWord’ on each iteration.
c. Print the reversed word on the screen.
STRETCH CHALLENGE: Handle the word so that it reads properly backwards. (Stressed becomes Dessert)
I don't know wether I'm just not understanding the wording of the task or not, but this is the code I have at the moment:
String[] wordList = {"Stressed", "Parts", "Straw", "Keep", "Wolf"};
String reversedWord;
for (int i = wordList.length; i >= 0; i++) {
reversedWord = "";
for (int j = wordList[i].length() - 1; i >= 0; j--) {
reversedWord += wordList[i].charAt(j);
System.out.println(reversedWord);
}
}
It gives me this error when i run it:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 5 out of bounds for length 5
at Main.main(Main.java:22)
Any help explanation would be helpful.
There are a few issues here. In the line
for (int i = wordList.length; i >= 0; i++) {
you are setting i to be the length of the wordList, which is 5. Remember, though, that array indexes start at 0. So the valid indexes of wordList are 0, 1, 2, 3, and 4, but not 5. To fix this, you can just subtract 1 from the length.
for (int i = wordList.length - 1; i >= 0; i++) {
The next problem is that you are increasing i at the end of each loop. Since it seems like you're trying to iterate backwards, you're gonna want to decrease i, not increase it.
for (int i = wordList.length - 1; i >= 0; i--) {
There is a simpler solution using Java's StringBuilder class:
public static void main(String[] args) {
String[] wordList = {"Stressed", "Parts", "Straw", "Keep", "Wolf"};
for (int i = 0; i < wordList.length; i++) {
String word = wordList[i]; // Get the word from array
word = new StringBuilder(word).reverse().toString(); // use StringBuilder to reverse the word
wordList[i] = word; // put word back in the array
}
System.out.println(Arrays.asList(wordList));
}
This outputs
[dessertS, straP, wartS, peeK, floW]
UPDATE:
For the words to read properly (first character in uppercase), You could do something like this:
word = word.toLowerCase();
word = word.replace(word.substring(0,1), word.substring(0,1).toUpperCase());
wordList[i] = word; // put word back in the array
There are more effective ways to do this, but is simpler for you to understand. This obviously outputs:
[Desserts, Strap, Warts, Peek, Flow]
substring(0,1) returns the first character (substring from index 0 to index 1; where the last index is not inclusive) as a String. Then, you are replacing the same substring with the uppercase substring.

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

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

Compare two strings in Java and show the character differences

I'm looking for a way to compare two strings to each other character by character.
It should show whether there are other characters which don't appear in both strings.
Does someone have a solution for?
for(int j=0; j < min; j++) {
s1 = w1.substring(j,j+1);
s2 = w2.substring(j,j+1);
if (!s1.equalsIgnoreCase(s2) ){
counter++;
}
}
This only looks sequential for differences. But I want to find out whether there are differences between those two strings at all.
So **abc** and **cab** should count as a hit
I think what you want is to show that 2 strings have the same letters and the same amount of each letter. Use 2 hashsets, where the key is the character and the value is the number of occurrence in the string. you'll have one hashset for each string, then loop through the string add the characters to the set and compare to see if the sets are equal.
Turn them into charArrays and add the differences to an empty string as a for loop scans through them, for instance
String a = "abc";
char[] aa = a.toCharArray();
String b = "cba";
char[] bb = b.toCharArray();
String dif;
public void differ() {
for(int i = 0; i < aa.length - 1; i++) {
if(!aa[i].equals(bb[i])) {
dif += aa[i];
}
}
}
I believe running differ() would return "ac" because they both have b in the middle. Is this what you wanted?

How do I reorder characters in a String without the use of Hashmaps?

My code below is giving the following error and I can't figure out why. I am trying to reorder the entered word ("Polish" for example) in the order of:
(First letter, last letter, second letter, second last letter, third letter... so on) so the output should be "Phosli".
Updated code
public static String encodeTheWord(String word1)
{
int b = 0;
int e = word1.length()-1;
String word2 = "";
for (int i=0; i<e; i++)
{
word2 = word2 + word1.charAt(b) + word1.charAt(e);
b+=1;
e-=1;
}
System.out.println(word2);
return (word2);
}
For a word with an even amount of characters (Polish), the order of the characters becomes 051423, so the maximum value of b is 2 and the minimum value is e is from 5 to 3. Thus, your loop should decrement e and increment b twice (so you run the loop for word1.length() / 2 times). Also,
int e = word1.length();
Would need to be:
int e = word1.length() - 1;
For words of an uneven length (word1.length() % 2 > 0) you need an extra check or you will repeat the middle character.
your for loop is wrong, you can get a char at index 0, until the word1.length()-1...
must be
for (int i=0; i<word1.length()-1; i++)
the same applies for this...
word1.charAt(e);
because you defined e as word1.length()

Categories