Counting the character 'e' - java

Hi I have to create a method that takes the word message, and counts how many times the character e appears this is what I have but I always get 0. any suggestions?
public class run
{
public static void main(String[] args)
{
String message ="message";
int count=0;
for(int i=0; i>=message.length()-1;i++)
{
char ch = message.charAt(i);
char e='e';
if( ch == e)
{
count = count +1;
}
}
System.out.println(count);
}
}

for(int i=0; i>=message.length()-1;i++)
This will never enter the loop (except for some short-message edge cases where it will then stay in the loop for quite a while) since you have the comparison sense around the wrong way. You need:
for (int i = 0; i < message.length(); i++)
And you don't really need those extra variables, this will do fine:
int count = 0;
for (int i = 0; i < message.length(); i++)
if (message.charAt(i) == 'e')
count++;

Here is another recursive method:
public int countE(String str) {
int count = 0;
if (str.charAt(0) == 'e')
count++;
if (str.length() > 1) {
count += countE (str.substring(1));
}
return count;
}

Heres a recursive solution:
public static int countChar (String message, char e)
{
int charOccurences = 0;
for (int i = 0 ; i < message.length () ; i++)
{
if (message.charAt (i) == e)
{
charOccurences++;
message = message.substring (0, i) + message.substring (i + 1);
return charOccurences + countChar (message, e);
}
}
return charOccurences;
}

Related

How to remove the pattern string until there is no pattern string in the text?

Problem Descripition
You are given 2 strings,text and pattern , you should do the following operations
If pattern is not in text, goto 4
delete the first occurrence of pattern in text
goto 1
print current text
end
I try to solve this problem using KMP Algorithm. I find the delete operation will cost much time, so I use another textNext array to store the next element's index of text string to skip the pattern string in text(avoiding really deleting it from text). For example, text is ukpkmkk, and the pattern is pk. After executing the operations, textNext should be {1,4,3,4,5,6,7}(textNext is initialized to i+1 for element). I use the code below to traverse the string after those operations.
for (int i = 0; i < text.length(); i = textNext[i]) {...}
My problem is that I can't get the correct result using my algorithm. Here is my code.
public static void main(String[] args) {
String text = in.next();
String pattern = in.next();
int[] textNext = new int[text.length()];
for (int i = beginIndex; i < textNext.length; i++) {
textNext[i] = i + 1;
}
while (kmp(text, pattern, textNext) != -1) {}
for (int i = beginIndex; i < text.length(); i = textNext[i]) {
out.print(text.charAt(i));
}
out.println("");
out.close();
}
public static int kmp(String text, String pattern, int[] textNext) {
int[] patternNext = buildNext(pattern);
int head = 0;
for (int i = beginIndex, j = 0; i < text.length(); i = textNext[i]) {
while (j > 0 && text.charAt(i) != pattern.charAt(j)) {
j = patternNext[j - 1];
}
if (text.charAt(i) == pattern.charAt(j)) {
if (j == 0) {
head = i;
}
j++;
}
if (j == pattern.length()) {
if (head == 0) {
beginIndex = i + 1;
} else {
textNext[head - 1] = i + 1;
}
return head;
}
}
return -1;
}
public static int[] buildNext(String pattern) {
int[] next = new int[pattern.length()];
next[0] = 0;
for (int i = 1, j = 0; i < next.length; i++) {
while (j > 0 && pattern.charAt(i) != pattern.charAt(j)) {
j = next[j - 1];
}
if (pattern.charAt(i) == pattern.charAt(j)) {
j++;
}
next[i] = j;
}
return next;
}
Please point out where my algorithm's problem is or just offer other way to solve this problem.

Remove static int counter from this recursive solution

I have this recursive code for counting the number of permutations a string can have
public class Permutation {
static int counter = 0;
public static int perms(String s, int level,int length) {
if(level == length-1) {
counter++;
}
else {
for (int i = 0; i < s.length(); i++) {
String newString = s.substring(0, i) + s.substring(i + 1);
perms(newString,level + 1, length);
}
}
return counter;
}
public static void main(String[] args) {
System.out.println(perms("plot", 0, 4));
}
}
I was wondering how I can rewrite it so that it doesn't use static int counter = 0? Thanks!
NOTE: Yes, I know I can just use the permutation formula for this haha
Without the need for a static counter or passing a counter value to each method call. Note that your implementation counts all permutations and not unique permutations (String "aab" returns 6, not 3).
public static int permsRedone(String s, int level,int length){
int count = 0;
if(level == length-1){
return 1;
}
else {
for (int i = 0; i < s.length(); i++) {
String newString = s.substring(0,i)+s.substring(i+1);
count += permsRedone(newString,level+1,length);
}
}
return count;
}
You can pass the counter as the fourth argument (using 0 as the initial value). Return it from perms and set it to the value returned from the inner call.
public static int perms2(String s, int level,int length, int count){
if(level == length-1){
count++;
}
else {
for (int i = 0; i < s.length(); i++) {
String newString = s.substring(0,i)+s.substring(i+1);
count = perms2(newString,level+1,length, count);
}
}
return count;
}

Find the number of unordered anagramic pairs of substrings

I am trying to solve the following question:
https://www.hackerrank.com/challenges/sherlock-and-anagrams
This is my code
import java.util.*;
public class Solution {
public static boolean check(String s1,String s2)
{
int [] count1 = new int[26];
for( int i = 0; i < s1.length(); i++ )
{
char ch1 = s1.charAt(i);
count1[ch1-'a']++;
}
int [] count2 = new int[26];
for( int i = 0; i < s2.length(); i++ )
{
char ch2 = s2.charAt(i);
count2[ch2-'a']++;
}
int count =0;
for(int j=0;j<26;j++)
{
count = count + Math.abs(count1[j]-count2[j]);
}
if(count ==0)
return true;
else return false;
}
public static void main(String[] args) {
String s,sub;
int i,c,len;
List<String> all = new ArrayList<>();
Scanner in = new Scanner(System.in);
int t = Integer.parseInt(in.nextLine());
while((t--)>0)
{
s = in.nextLine();
len = s.length();
for( c = 0 ; c < len ; c++ )
{
for( i = 1 ; i <= len - c ; i++ )
{
sub = s.substring(c, c+i);
all.add(sub);
}
}
String[] arr = new String[all.size()];
for( i = 0; i < all.size(); i++)
arr[i] = all.get(i);
int l=0;
for (int m=0;m<arr.length;m++)
{
for(int n=m+1;n<arr.length;n++)
{
if(check(arr[m],arr[n]))
l++;
}
}
System.out.println(l);all.clear();
}
}
}
My code worked for few test cases which have small strings but failed to work if string size is too big
Sample input
5
ifailugtyovhdfuhdouarjsnrbfpvmupwjjjfiwneogwnoegnoegneognoewhrlkpekxxnebfrwibylcvkfealgonjkzw
gffryqktmwocejbrexfidpjfgrrkpowoxwggxaknmltjcpazgtnakcfbveieivoenwvpnoevvneocogzatyskqjyorcftw
uqlzvuzgkwhkkrrfpwarkckansgabfclzgnumdrojexnofeqjnqnxwidhbvbenevun9evnnv9euxxhfwargwkikjq
sygjxynvofnvirarcoacwnhxyqlrviikfuiuotifznqmzpjrxycnqkeibvibvewioebvitkryutpqvbgbgthfges
mkenscyiamnwlpxytkndjsygifmqlqibxxqlauxamfviftquntvkwppxrzuncyenavebiobeviobeiobeibvcfivtigv
My Output
4s : Terminated due to timeout
is there any better way to solve it or to change the existing code so that executed time is within 4mins
You can check out this link. It is explained very well here.
I think that you are storing all substrings and then searching for the anagram pair because of that space complexity of your code is very much. So you can improve that. You can also reduce the number of operations in your check function by returning false at the very first point where they mismatch.
I have implemented the above problem in c++. Here is my code:
#define MAX 26
bool isAnagram(int *count1, int *count2) {
for(int i = 0; i < MAX; i++) {
if(count1[i] != count2[i])
return false;
}
return true;
}
int findPair(string str, int start, char *tmp, int n) {
int len = str.length();
if(strlen(tmp) > len-start) {
return 0;
}
int *count1 = new int[MAX];
int *count2 = new int[MAX];
int cnt = 0;
int i;
for(i = 0; i < MAX; i++) {
count1[i] = 0;
count2[i] = 0;
}
for(i = 0; i < n && (start+i) < len; i++) {
count1[tmp[i]-'a']++;
count2[str[start+i]-'a']++;
}
int j;
for(j = start + i; j < len; j++) {
if(isAnagram(count1, count2)) {
cnt++;
}
count2[str[start]-'a']--;
count2[str[j]-'a']++;
start++;
}
if(j == len) {
if(isAnagram(count1, count2)) {
cnt++;
}
}
delete []count1;
delete []count2;
return cnt;
}
int countPairs(string str) {
int n = str.length();
if(n < 2) {
return 0;
}
int cnt = 0;
char *tmp = new char[n];
for(int i = 0; i < n; i++) {
int k = 0;
for(int j = i; j < n; j++) {
tmp[k] = str[j];
tmp[k+1] = '\0';
cnt += findPair(str, i+1, tmp, k+1);
k++;
}
}
delete []tmp;
return cnt;
}
int main() {
int t;
cin>>t;
while(t--) {
string str;
cin>>str;
cout<<countPairs(str)<<endl;
}
return 0;
}
Apart from early termination. You can use a HashMap, the key being the length and the value being a list of substrings of the same length. Store the substrings and check only with elements inside the 'value'.
Although you might think it works the same as early termination if the lengths are different, it makes a difference and doesn't give early termination problems.
import java.io.*;
import java.util.*;
import java.text.*;
import java.math.*;
import java.util.regex.*;
public class Solution {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
int x=sc.nextInt();
for(int k=0; k<x; k++){
String str1=sc.next();
HashMap<Integer,ArrayList<String>> sub= getSub(str1);
int counter=0;
for(int t=1; t<=str1.length(); t++){
ArrayList<String> subsl= sub.get(t);
for(int i=0; i<subsl.size()-1; i++){
for(int j=i+1; j<subsl.size(); j++){
if(isAnagram(subsl.get(j),subsl.get(i))){
counter++;
}
}
}
}
System.out.println(counter);
}
}
public static HashMap<Integer,ArrayList<String>> getSub(String str1){
HashMap<Integer,ArrayList<String>> ret= new HashMap<Integer,ArrayList<String>>();
for(int i=0; i<str1.length(); i++){
for(int j=i; j<str1.length(); j++){
if(!ret.containsKey(str1.substring(i, j+1).length())){
ArrayList<String> x= new ArrayList<String>();
x.add(str1.substring(i, j+1));
ret.put(str1.substring(i, j+1).length(), x);
}
else
ret.get(str1.substring(i, j+1).length()).add(str1.substring(i, j+1));
}
}
return ret;
}
public static boolean isAnagram(String a1, String a2){
int count1[]= new int[26];
int count2[]= new int[26];
if(a1.length()!=a2.length())
return false;
for(int i=0; i<a1.length(); i++){
count1[(int)a1.charAt(i)-97]++;
count2[(int)a2.charAt(i)-97]++;
}
for(int i=0; i<26; i++){
if(count1[i]!=count2[i])
return false;
}
return true;
}
}
If you want to make it even faster, then change the HashMap to include an object with has the counts of all 26 alphabets. That'll obviously take more memory so you can have something intermediate with the length and say counts of letters a,b,c (or 3 such letters).
To make the checking efficient, use bit manipulation to encode all these (length, count of a, count of b and count of c). Though take care to not exceed the number of bits for Integer.
Try this.
What I have done here is broken the string into two substrings and checked all the anagramic pairs of 1st string in the second.
for ex:abba
1st substring=a;
2nd substring=bba
now check all anagramic pairs of a in bba
import java.util.*;
public class SherlockAndAnagrams{
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
int t=Integer.parseInt(sc.nextLine());
while(t-->0){
String s=sc.nextLine();
int count=0;
for(int i=0;i < s.length();i++){
for(int k=i+1;k < s.length();k++){
int num=anagram(s.substring(i,k),s.substring(i+1),s.substring(i,k).length());
count=count+num;
}
}
System.out.println(count);
}
}
static int anagram(String s1,String s2,int len){
int count = 0;
char[] c1=s1.toCharArray();
Arrays.sort(c1);
String ss1=new String(c1);
int length=s2.length();
for(int i=0;i<length;i++){
if(i+len<=length){
String sub=s2.substring(i,i+len);
char[] c2=sub.toCharArray();
Arrays.sort(c2);
String ss2=new String(c2);
if(ss1.compareTo(ss2)==0)
count++;
}
}
return count;
}
}

Alternating characters of two different inputs

I want to take two strings and alternate the characters into a new string using a for method.
Example: "two" and "one"
Result: "townoe"
This is what I have so far, and I really don't know how to finish it.
public class Alternator {
String alternate(String a, String b) {
String s = "";
for (int i = 0; i < a.length(); i++) {
s += i;
System.out.println(s);
}
return null;
}
}
public class Alternator{
public static String alternate(String a, String b){
String s = "";
int i = 0;
while (i < a.length() && i < b.length()){
s += a.charAt(i) +""+ b.charAt(i);
i++;
}
while (i < a.length() ){
s += a.charAt(i);
i++;
}
while (i < b.length()){
s += b.charAt(i);
i++;
}
return s;
}
public static void main(String[] args){
String a = "two", b = "one";
String s = Alternator.alternate(a,b);
System.out.println(s);
}
}
To use for loop instead of while loop, simply remove all while lines with for lines like the following, then remove the i++ line from each while loop
for(; i < a.length() && i < b.length(); i++){
//the inside of the loop MINUS THE LINE i++
}
for(; i < a.length(); i++){
//the inside of the loop MINUS THE LINE i++
}
for(; i < b.length(); i++){
//the inside of the loop MINUS THE LINE i++
}
Here is some compact way of doing that:
String alternate(String a, String b) {
StringBuilder builder = new StringBuilder();
int smallerStringLength = Math.min(a.length(), b.length());
for (int i = 0; i < smallerStringLength; i++) {
builder.append(a.charAt(i));
builder.append(b.charAt(i));
}
return builder.toString();
}
Or even more optimized:
String alternate(String first, String second) {
char[] firstChars = first.toCharArray();
char[] secondChars = second.toCharArray();
int smallerCharsCount = Math.min(firstChars.length, secondChars.length);
StringBuilder builder = new StringBuilder(smallerCharsCount * 2);
for (int i = 0; i < smallerCharsCount; i++) {
builder.append(firstChars[i]);
builder.append(secondChars[i]);
}
return builder.toString();
}
This will work if string are of same length or of the different lengths.
static void mergeStrings(String a, String b) {
StringBuilder mergedBuilder = new StringBuilder();
char[] aCharArr = a.toCharArray();
char[] bCharArr = b.toCharArray();
int minLength = aCharArr.length >= bCharArr.length ? bCharArr.length : aCharArr.length;
for (int i=0; i<minLength; i++) {
mergedBuilder.append(aCharArr[i]).append(bCharArr[i]);
}
if(minLength < aCharArr.length) {
mergedBuilder.append(a.substring(minLength));
}
else{
mergedBuilder.append(b.substring(minLength));
}
Systemout.println(mergedBuilder.toString());
}
Assuming that the two strings are the exact same length, you can do the following. If they are different length, then currently your prompt doesn't say how you want the resultant string to be set up.
public class Alternator {
String alternate(String a, String b) {
String s = "";
for (int i = 0; i < 2*a.length(); i++) {
if (i%2==0) // modular arithmetic to alternate
s += a.charAt(i/2); // Note the integer division
else
s += b.charAt(i/2);
}
System.out.println(s);
return s;
}
}
Alternatively, even easier, but the index i doesn't mark the length of your string s:
public class Alternator {
String alternate(String a, String b) {
String s = "";
for(int i = 0; i < a.length(); i++){
s += a.charAt(i);
s += b.charAt(i);
}
return s;
}
}
Use this:
String alternate(String a, String b){
StringBuilder builder = new StringBuilder();
final int greaterLength = a.length() > b.length() ? a.length() : b.length();
for(int i = 0; i < greaterLength; i++){
if (i < a.length()) {
builder.append(a.charAt(i));
}
if (i < b.length()) {
builder.append(b.charAt(i));
}
}
return builder.toString();
}
It uses the String.charAt method to obtain letters, and a StringBuilder to create the string.
(When given two strings of non-equal length, this returns an alternation of the first two chars, and then does just the remaining string. EG: Hello and Hi --> HHeillo)
According to the comments I've read, you are having trouble understanding for loops, and how to use them with strings.
For loops are most often used to iterate over arrays, or to perform a task a given number of times.
for (int i = 0; i < 5; i++) {
System.out.println(i);
}
This would give the output
0
1
2
3
4
For loops start at the value of the initializer, the first thing you put in int i = 0;
They then check the expression, the second part of the for loop, and if it returns true, it executes all of the code inside the braces. i < 5;
Once it has done that, it runs the incrementor, the last part of the for loop. i++
After that, it checks the expression again. I guess you can see where this is going. Until the expression returns false, everything inside the curly braces of the for loop gets executed over and over again.
Strings can be iterated over with a for loop, but you can't reference it like an array using array[index]. You have to either convert it into an array, using .toCharArray() on your String, and return the result to an empty char array char[], or use the .charAt(index) method on your string.
This code will go over a string, and output each character, one by one:
for (int i = 0; i < myString.length(); i++) {
System.out.println(myString.charAt(i));
}
If the string had a value of "Hello", the output would be:
H
e
l
l
o
Using this, instead of outputting the characters using System.out.println();, we can put them into an empty string, using +=:
myOtherString += myString.charAt(i);
That means, if we want to go over two Strings at a time, and alternate them, like you do, we can iterate over two strings at the same time, and add them to a new string:
myAlternatedString += myString.charAt(i);
myAlternatedString += myOtherString.charAt(i);
if MyString was still "Hello" and myOtherString was "World", the new string would be:
Hweolrllod
following code reads 2 different inputs and merges into a single string.
public class PrintAlternnateCharacterString {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String a = in.next();
String b = in.next();
String mergedString = "";
int lenA = a.length();
int lenB = b.length();
if (lenA >= lenB) {
for (int i = 0; i < lenA; i++) {
if (i < lenB) {
mergedString += a.charAt(i) + "" + b.charAt(i);
} else {
mergedString += a.charAt(i);
}
}
}
if (lenB > lenA) {
for (int i = 0; i < lenB; i++) {
if (i < lenA) {
mergedString += a.charAt(i) + "" + b.charAt(i);
} else {
mergedString += b.charAt(i);
}
}
}
System.out.println("the merged string is-->" + mergedString);
}
}
public static String stringConcate(String str1,String str2){
String str3="";
if(str1!=null && str2!=null && !str1.isEmpty() && !str2.isEmpty()){
if(str1.length()==str2.length()){
for(int i=0;i<=str1.length()-1;i++){
str3+=str1.charAt(i);
str3+=str2.charAt(i);
}
}
if(str1.length()>str2.length()){
for(int i=0;i<=str1.length()-1;i++){
str3+=str1.charAt(i);
if(i<str2.length()){
str3+=str2.charAt(i);
}
}
}
if(str2.length()>str1.length()){
for(int i=0;i<=str2.length()-1;i++){
if(i<str1.length()){
str3+=str1.charAt(i);
}
str3+=str2.charAt(i);
}
}
}
return str3;
}
String str1 = "one"; String str2 = "two";
StringBuilder sb = new StringBuilder();
int i = 0;
for (; i < str1.length() && i < str2.length(); i++) {
sb.append(str1.charAt(i)).append(str2.charAt(i));
}
for(; i < str1.length(); i++) {
sb.append(str1.charAt(i));
}
for(; i < str2.length(); i++) {
sb.append(str2.charAt(i));
}
System.out.println("result = " + sb.toString());// otnweo
This will handle for different length too
This could be donw with very simple if...else.
public static void main(String... args) {
int[] one = { 1, 2, 3 };
int[] two = { 44, 55, 66, 77, 88 };
System.out.println(Arrays.toString(alternate(one, two)));
}
public static int[] alternate(int[] one, int[] two) {
int[] res = new int[one.length + two.length];
for (int i = 0, j = 0, k = 0; i < res.length; i++) {
if (i % 2 == 0)
res[i] = j < one.length ? one[j++] : two[k++];
else
res[i] = k < two.length ? two[k++] : one[j++];
}
return res;
}
Output:
[1, 44, 2, 55, 3, 66, 77, 88]

How can I find the maximum value within a string?

For example, if a user were to input "ABZ748FJ9K" as a string, how would I pinpoint the max value of that string (in this case it is 9), and then output it back to the user.
Any non-numeric character is supposed to be ignored.
I tried doing some if-else ladder, but that would require me to list out every number, and it wasn't behaving the way I wanted it to anyways. I know there must be a better solution. Some help would be greatly appreciated. Thanks!
import java.util.Scanner;
public class Question{
public static void main(String args[]){
Scanner input = new Scanner(System.in);
System.out.println("Please enter a string");
String userInput = input.next();
int finalMax = max(userInput);
System.out.println("The maximum value is " + finalMax);
}
public static int max(String s){
int x = s.length();
int y = 0;
for (int i=0; i < x; i++){
if (s.charAt(i) == 9){
y=9;
}
else if (s.charAt(i) == 8){
y=8;
}
}
return y;
}
}
}
Try this:
public static int max(String s){
s=s.replaceAll("\\D","");
int x = s.length();
int y = Character.getNumericValue(s.charAt(0));
for (int i=1; i < x; i++){
if (Character.getNumericValue(s.charAt(i)) > y){
y=Character.getNumericValue(s.charAt(i));
}
}
return y;
}
s=s.replaceAll("\\D","") will make sure all character in your string is a digit by replacing all non-digit character with ""
Use the function below instead of your version:
public static int max(String s){
int x = s.length();
int y = 0;
Character temp = null;
for (int i=0; i < x; i++){
char ch = s.charAt(i);
if (ch >= '0' && ch <='9' && (temp == null || temp < ch )){
temp = s.chartAt(i);
}
}
return Integer.valueOf(temp);
}
Start a max value with 0, then u will loop the string. Each loop u must verify if it is char or int, if int then check if it is > than the max value, if so, set the new max value.
I leave as a challenge to u, to think about each position of the string will be treated as a char.
Cheers. Good luck.
you should try something like:
public static int max(String s){
int max = -1;
char current;
for(int i = 0; i<s.length; i++){
current = s.charAt(i);
if(current > '0' && current < '9')
if(current > max)
max = current;
}
return max;
}

Categories