Java Method to find the occurencies of a certain character - java

my code should prompt the user to enter a string and a character, and tell where the character is located
for instance
"Welcome" and "e"
returns
"2, 7"
How can my code be fixed? Code is here. Thanks in advance (this is not homework, but some hint could be useful anyway if you don't want to post a solution).
import java.util.Scanner;
public class Test {
public static void main(String[] args) {
System.out.println("Please enter a string and a character");
Scanner input = new Scanner(System.in);
String s = input.nextLine();
char ch = input.next().charAt(0);
System.out.println(count(ch));
}
public static int count (String s, char a) {
int count = 0;
for (int i = 0; i < s.length(); i++) {
if (s.charAt(i) == a) {
count++;
}
}
return count;
}
}

Some mistakes:
Your code doesn't compile. Call:
System.out.println(count(s, ch));
instead of
System.out.println(count(ch));
You count the number of appearances. Instead, you should keep the indexes. You can use a String or you can add them to a list / array and convert it later to what you want.
public static String count(String s, char a) {
String result = "";
for (int i = 0; i < s.length(); i++) {
if (s.charAt(i) == a) {
result += (i+1) + ", ";
}
}
return result.substring(0, result.length() - 2);
}
I used i+1 instead of i because the indexes start at 0 in Java.
I also returned the string result.substring(0, result.length() - 2) without its last 2 characters, because I added , after every character.

Since Java 8, you can do this by using streams:
public static String count(String s, char a) {
return IntStream.range(0, s.length())
.filter(i -> a == s.charAt(i)).mapToObj(i -> i + "")
.collect(Collectors.joining(", "));
}
This code will print indexes of your Character, seprated by comma.
For more about streams, you can read here, in Java 8 documentation.

Just Change the count method :
public static ArrayList<Integer> count(String s, char a) {
ArrayList<Integer> positions = new ArrayList<>();
for (int i = 0; i < s.length(); i++) {
if (s.charAt(i) == a) {
positions.add(i+1);
}
}
return positions;
}

Related

Common characters in n strings

I m trying to make a function that prints the number of characters common in given n strings. (note that characters may be used multiple times)
I am struggling to perform this operation on n strings However I did it for 2 strings without any characters repeated more than once.
I have posted my code.
public class CommonChars {
public static void main(String[] args) {
String str1 = "abcd";
String str2 = "bcde";
StringBuffer sb = new StringBuffer();
// get unique chars from both the strings
str1 = uniqueChar(str1);
str2 = uniqueChar(str2);
int count = 0;
int str1Len = str1.length();
int str2Len = str2.length();
for (int i = 0; i < str1Len; i++) {
for (int j = 0; j < str2Len; j++) {
// found match stop the loop
if (str1.charAt(i) == str2.charAt(j)) {
count++;
sb.append(str1.charAt(i));
break;
}
}
}
System.out.println("Common Chars Count : " + count + "\nCommon Chars :" +
sb.toString());
}
public static String uniqueChar(String inputString) {
String outputstr="",temp="";
for(int i=0;i<inputstr.length();i++) {
if(temp.indexOf(inputstr.charAt(i))<0) {
temp+=inputstr.charAt(i);
}
}
System.out.println("completed");
return temp;
}
}
3
abcaa
bcbd
bgc
3
their may be chances that a same character can be present multiple times in
a string and you are not supposed to eliminate those characters instead
check the no. of times they are repeated in other strings. for eg
3
abacd
aaxyz
aatre
output should be 2
it will be better if i get solution in java
You have to convert all Strings to Set of Characters and retain all from the first one. Below solution has many places which could be optimised but you should understand general idea.
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class Main {
public static void main(String[] args) {
List<String> input = Arrays.asList("jonas", "ton", "bonny");
System.out.println(findCommonCharsFor(input));
}
public static Collection<Character> findCommonCharsFor(List<String> strings) {
if (strings == null || strings.isEmpty()) {
return Collections.emptyList();
}
Set<Character> commonChars = convertStringToSetOfChars(strings.get(0));
strings.stream().skip(1).forEach(s -> commonChars.retainAll(convertStringToSetOfChars(s)));
return commonChars;
}
private static Set<Character> convertStringToSetOfChars(String string) {
if (string == null || string.isEmpty()) {
return Collections.emptySet();
}
Set<Character> set = new HashSet<>(string.length() + 10);
for (char c : string.toCharArray()) {
set.add(c);
}
return set;
}
}
Above code prints:
[n, o]
A better strategy for your problem is to use this method:
public int[] countChars(String s){
int[] count = new int[26];
for(char c: s.toCharArray()){
count[c-'a']++;
}
return count;
}
Now if you have n Strings (String[] strings) just find the min of common chars for each letter:
int[][] result = new int[n][26]
for(int i = 0; i<strings.length;i++){
result[i] = countChars(s);
}
// now if you sum the min common chars for each counter you are ready
int commonChars = 0;
for(int i = 0; i< 26;i++){
int min = result[0][i];
for(int i = 1; i< n;i++){
if(min>result[j][i]){
min = result[j][i];
}
}
commonChars+=min;
}
Get list of characters for each string:
List<Character> chars1 = s1.chars() // list of chars for first string
.mapToObj(c -> (char) c)
.collect(Collectors.toList());
List<Character> chars2 = s2.chars() // list of chars for second string
.mapToObj(c -> (char) c)
.collect(Collectors.toList());
Then use retainAll method:
chars1.retainAll(chars2); // retain in chars1 only the chars that are contained in the chars2 also
System.out.println(chars1.size());
If you want to get number of unique chars just use Collectors.toSet() instead of toList()
Well if one goes for hashing:
public static int uniqueChars(String first, String second) {
boolean[] hash = new boolean[26];
int count = 0;
//reduce first string to unique letters
for (char c : first.toLowerCase().toCharArray()) {
hash[c - 'a'] = true;
}
//reduce to unique letters in both strings
for(char c : second.toLowerCase().toCharArray()){
if(hash[c - 'a']){
count++;
hash[c - 'a'] = false;
}
}
return count;
}
This is using bucketsort which gives a n+m complexity but needs the 26 buckets(the "hash" array).
Imo one can't do better in regards of complexity as you need to look at every letter at least once which sums up to n+m.
Insitu the best you can get is imho somewhere in the range of O(n log(n) ) .
Your aproach is somewhere in the league of O(n²)
Addon: if you need the characters as a String(in essence the same as above with count is the length of the String returned):
public static String uniqueChars(String first, String second) {
boolean[] hash = new boolean[26];
StringBuilder sb = new StringBuilder();
for (char c : first.toLowerCase().toCharArray()) {
hash[c - 'a'] = true;
}
for(char c : second.toLowerCase().toCharArray()){
if(hash[c - 'a']){
sb.append(c);
hash[c - 'a'] = false;
}
}
return sb.toString();
}
public static String getCommonCharacters(String... words) {
if (words == null || words.length == 0)
return "";
Set<Character> unique = words[0].chars().mapToObj(ch -> (char)ch).collect(Collectors.toCollection(TreeSet::new));
for (String word : words)
unique.retainAll(word.chars().mapToObj(ch -> (char)ch).collect(Collectors.toSet()));
return unique.stream().map(String::valueOf).collect(Collectors.joining());
}
Another variant without creating temporary Set and using Character.
public static String getCommonCharacters(String... words) {
if (words == null || words.length == 0)
return "";
int[] arr = new int[26];
boolean[] tmp = new boolean[26];
for (String word : words) {
Arrays.fill(tmp, false);
for (int i = 0; i < word.length(); i++) {
int pos = Character.toLowerCase(word.charAt(i)) - 'a';
if (tmp[pos])
continue;
tmp[pos] = true;
arr[pos]++;
}
}
StringBuilder buf = new StringBuilder(26);
for (int i = 0; i < arr.length; i++)
if (arr[i] == words.length)
buf.append((char)('a' + i));
return buf.toString();
}
Demo
System.out.println(getCommonCharacters("abcd", "bcde")); // bcd

Is there a method to count the number of times a variable has been previously stated in a string in java?

I'm trying to make a program that replaces any vowel with a number, counting up from 0 whenever a vowel occurs, while using loops
what I have so far:
int num = 0;
for (int number = 0; number <= (insert method that returns the number of times num occured in the string here / number of vowels of any type previously seen in the string); number ++)
{
num = number;
}
String word = "AEIOUaeiou87878alkjdaslwlejrlajflawjkflwj";
word = word.replaceAll("A", "" + num).replaceAll("E", "" + num)
.replaceAll("I", "" + num).replaceAll("O", "" + num)
.replaceAll("U", "" + num).replaceAll("a", "" + num)
.replaceAll("e", "" + num).replaceAll("i", "" + num)
.replaceAll("o", "" + num).replaceAll("u", "" + num);
System.out.println(word);
what is returned:
0123456789878780lkjd1slwl2jrl3jfl4wjkflwj
Does anybody know of a good way to make this work? Sorry if I'm not making much sense. I'm very new to coding.
Your problem is that you replace all instances of one letter at once. You need to have a counter for the vowels starting a 0, then increment it whenever you find one, then build a string out of that counter and the other non-vowel characters.
For example,
public static void vowelReplacer(String word) {
int vowelCount = 0;
StringBuilder sb = new StringBuilder();
for (int i = 0; i < word.length(); i++) {
char c = word.charAt(i);
if ("aieou".contains(String.valueOf(Character.toLowerCase(c)))) {
sb.append(vowelCount++);
} else {
sb.append(c);
}
}
System.out.println(sb.toString());
}
I/O
public static void main(String[] args) {
vowelReplacer("AEIOUaeiou87878alkjdaslwlejrlajflawjkflwj");
// 01234567898787810lkjd11slwl12jrl13jfl14wjkflwj
}
The most important step is to split the word into an Array. Then you can check your vowels step by step and replace the char with an int if its necessary. If not just leave the char as it is.
But if you have a match, dont forget to add one to i (i++)
public static void main(String[] args) {
String word = "AEIObUaeiou87878alkjdaslwlejrlajflawjkflwj";
replaceVowel(word);
}
private static void replaceVowel(String word){
String[] chars = word.split("");
int i = 0;
StringBuilder replacedWord = new StringBuilder();
for (String oneChar : chars){
if(check(oneChar)){
replacedWord.append(String.valueOf(i));
i++;
}
else{
replacedWord.append(oneChar);
}
}
System.out.println(replacedWord);
}
private static boolean check(String oneChar){
oneChar = oneChar.toLowerCase();
if(oneChar.equals("a")||oneChar.equals("b")){ // ...the rest of your vowels
return true;
}else{
return false;
}
}
For checking your vowels you only need lowercase because we are able to change the String to lowercase just for that check. So you have less writing.

implement basic string compression

I am working on question 1.5 from the book Cracking The Coding interview. The problem is to take a string "aabcccccaaa" and turn it into a2b1c5a3.
If the compressed string is not smaller than the original string, then return the original string.
My code is below. I used an ArrayList because I would not know how long the compressed string would be.
My output is [a, 2, b, 1, c, 5], aabc, []. When the program gets to the end of string, it doesn't have a character to compare the last character too.
import java.util.*;
import java.io.*;
public class stringCompression {
public static void main(String[] args) {
String a = "aabcccccaaa";
String b = "aabc";
String v = "aaaa";
check(a);
System.out.println("");
check(b);
System.out.println("");
check(v);
}
public static void check(String g){
ArrayList<Character> c = new ArrayList<Character>();
int count = 1;
int i = 0;
int h = g.length();
for(int j = i + 1; j < g.length(); j++)
{
if(g.charAt(i) == g.charAt(j)){
count++;
}
else {
c.add(g.charAt(i));
c.add((char)( '0' + count));
i = j;
count = 1;
}
}
if(c.size() == g.length()){
System.out.print(g);
}
else{
System.out.print(c);
}
}
}
In the last loop you're not adding the result to the array. When j = g.length() still needs to add the current char and count to the array. So you could check the next value of j before increment it:
for(int j = i + 1; j < g.length(); j++)
{
if(g.charAt(i) == g.charAt(j)){
count++;
}
else {
c.add(g.charAt(i));
c.add((char)( '0' + count));
i = j;
count = 1;
}
if((j + 1) = g.length()){
c.add(g.charAt(i));
c.add((char)( '0' + count));
}
}
I would use a StringBuilder rather than an ArrayList to build your compressed String. When you start compressing, the first character should already be added to the result. The count of the character will be added once you've encountered a different character. When you've reached the end of the String you should just be appending the remaining count to the result for the last letter.
public static void main(String[] args) throws Exception {
String[] data = new String[] {
"aabcccccaaa",
"aabc",
"aaaa"
};
for (String d : data) {
System.out.println(compress(d));
}
}
public static String compress(String str) {
StringBuilder compressed = new StringBuilder();
// Add first character to compressed result
char currentChar = str.charAt(0);
compressed.append(currentChar);
// Always have a count of 1
int count = 1;
for (int i = 1; i < str.length(); i++) {
char nextChar = str.charAt(i);
if (currentChar == nextChar) {
count++;
} else {
// Append the count of the current character
compressed.append(count);
// Set the current character and count
currentChar = nextChar;
count = 1;
// Append the new current character
compressed.append(currentChar);
}
}
// Append the count of the last character
compressed.append(count);
// If the compressed string is not smaller than the original string, then return the original string
return (compressed.length() < str.length() ? compressed.toString() : str);
}
Results:
a2b1c5a3
aabc
a4
You have two errors:
one that Typo just mentioned, because your last character was not added;
and another one, if the original string is shorter like "abc" with only three chars: "a1b1c1" has six chars (the task is "If the compressed string is not smaller than the original string, then return the original string.")
You have to change your if statement, ask for >= instead of ==
if(c.size() >= g.length()){
System.out.print(g);
} else {
System.out.print(c);
}
Use StringBuilder and then iterate on the input string.
private static string CompressString(string inputString)
{
var count = 1;
var compressedSb = new StringBuilder();
for (var i = 0; i < inputString.Length; i++)
{
// Check if we are at the end
if(i == inputString.Length - 1)
{
compressedSb.Append(inputString[i] + count.ToString());
break;
}
if (inputString[i] == inputString[i + 1])
count++;
else
{
compressedSb.Append(inputString[i] + count.ToString());
count = 1;
}
}
var compressedString = compressedSb.ToString();
return compressedString.Length > inputString.Length ? inputString : compressedString;
}

Java Counting number of words in a string without using split or StringTokenizers etc

The program asks for string input, then a minimum word length input.
If the word is less than the minimum word length, it will not count.
I'm trying to do the program without using split() or whatever every other post says to do for these problems.
I thought maybe I have to check the first word, last word, and then words in between. But I'm having trouble. I spent way too long on this and I can't figure it out.
IO is a different class used to input, output, etc.
public class WordCount {
public static void main(String[] args) {
int minLength;
System.out.println("Enter a string.");
String string=IO.readString();
String str1=string.toLowerCase(); //changes all characters in the string to lower case
String str=str1.trim(); //Trims all spaces in the end.
System.out.println("Enter minimum length for each word.");
minLength=IO.readInt();
int num=wordCount(str, minLength);
IO.outputIntAnswer(num);
}
public static int wordCount(String str, int minLength){ //Method that counts words.
int count=0;
// First Word
for(int i=0;i<str.length();i++){
if (str.charAt(i)==' '){
String firstWord=str.substring(0,i);
if (firstWord.length()>=minLength){
count++;
}
}
}
// Last Word
for (int i=str.length()-1;i>0;i--){
if(str.charAt(i)==' '){
String lastWord=str.substring(i, str.length()-1);
if(lastWord.length()>=minLength){
count++;
}
for (int j=0; j<i;j++){ //An attempt to find other words in between..does not work
if(str.charAt(j)==' '){
String word=str.substring(j+1, str.indexOf(' ', j+1));
if(word.length()>=minLength){
count++;
}
}
}
}
}
return count;
}
}
This should be enough:
public static int wordCount(String str, int min) {
int count = 0;
str = str.trim()+" ";
for(int i=0, st=0; i<str.length(); i++) {
if(str.charAt(i) != ' ') continue;
if(i-st >= min) count++;
st = i+1;
}
return count;
}
Beside the fact that your code is kind of scrappy and inadequate, the main problem here is that your first FOR loop doesn't stop after finding the first word. In fact, in counts every word in the input string, minus 1.
There is the same problem in your second loop.
If you really want to do it this way, you should use the BREAK keyword, to stop the loops when necessary.
EDIT
This should work
public static int wordCount(String str, int minLength) { //Method that counts words.
int count = 0;
for (int i = 0, wordLength = 0; i < str.length() + 1; i++) {
if (i == str.length() || str.charAt(i) == ' ') {
if (wordLength >= minLength) {
count++;
}
wordLength = 0;
} else {
wordLength++;
}
}
return count;
}
Please try this.
This takes care of extra spaces, leading, & also trailing spaces.
public class WordsCount {
static String str = " I Love Java for its oops concepts ";
static int i;
static int count = 0;
public static int numOfWords(String str) {
int length = str.length();
for(i=0;i<length;) {
if(str.charAt(i)!=' ') {
while(str.charAt(i)!=' ') {
i++;
if(i>=str.length())
break;
}
count = count+1;
} else {
i++;
}
}
return count;
}
public static void main(String[] args) {
count = numOfWords(str);
System.out.println("Count of words is : "+count);
}
}

Why are my string variables not being pushed in my stacks?

import java.util.*;
public class Pemdas {
public static double Express(String str)
{
Stack<Double> num = new Stack<Double>();
Stack<String> op = new Stack<String>();
String number = "[0-9]*"; // any digit from 0-9
for (int i = 0; i < str.length(); i++)
{
if (str.substring(i,i+1).equals(number))
num.push(Double.parseDouble(str.substring(i, i+1)));
else if (str.substring(i, i+1).equals("+"))
op.push(str.substring(i, i +1));
System.out.println(str);
}
double n = num.pop();
if (op.pop().equals("+"))
n = n + num.pop();
return n;
}
public static void main(String[] args)
{
System.out.print("Enter an Expression: ");
String ex = StdIn.readString(); // This is where I enter my string input
System.out.println(Express(ex));
}
}
Let's say that I have an String variable of "5 + 5" as my input. In the for loop, the 5 is supposed to be pushed into the num stack, but I keep getting an ESE and I don't understand why.
You're using equals() when you want to match against a regex. equals() is for comparing literal strings. You likely want matches():
if (str.substring(i,i+1).matches(number))
num.push(Double.parseDouble(str.substring(i, i+1)));
In fact, you don't need a regex at all here. You can simplify your loop by doing something like:
for (int i = 0; i < str.length(); i++)
{
char c = str.charAt(i);
if (Character.isDigit(c))
num.push((double) (c - '0'));
else if (c == '+')
op.push("+");
System.out.println(str);
}
Finally, please follow Java's naming conventions and call your method express() instead of Express().

Categories