Counting character occurrences in a string - Java - java

I'm having trouble writing a method that takes a string and counts the number of times the first character (or really any character) appears. The code I've written is below, but for some reason keeps returning half the correct count when I run it. Any help would be appreciated, thanks.
public static void countOccurrences(String string1) {
int counter = 0;
char toCheck = string1.charAt(0);
char compareChar;
for (int i = 0; i < string1.length(); i++) {
compareChar = string1.charAt(i);
if (toCheck == compareChar) {
counter++;
}
i++;
}
System.out.println(toCheck + " appears " + counter + " times in string1.");
}

You're incrementing i twice in each iteration, so you are skipping half the characters:
for (int i = 0; i < string1.length(); i++) { // i is incremented here
compareChar = string1.charAt(i);
if (toCheck == compareChar){
counter++ ;
}
i++ ; // i is incremented again here - remove this line
}

i++ in for loop is incrementing the i value by 1, no need to increment inside th eloop
check Working of For loop here
public static void countOccurrences(String string1) {
int counter = 0;
char toCheck = string1.charAt(0);
char compareChar;
for (int i = 0; i < string1.length(); i++) {
compareChar = string1.charAt(i);
if (toCheck == compareChar){
counter++ ;
}
}
System.out.println(toCheck + " appears " + counter + " times in string1.");
}

Your immediate problem is that i++; happens twice per iteration.
An alternative approach is to use
s.length() - s.replace("x", "").length()
which gives you the number of times "x" appears in s. Arguably it's not the most efficient way, but it's clear.

Related

Remove a duplicate word sentence in an array

Given a problem that determines the output of the word, length of each word, and the number of times the word repeats, I have the following code capable to determine the word and length of each word below:
String sentence;
String charSentence;
String[] wordOutput;
private void analyzeWords(String s) {
String[] words = sentence.split(" ");
wordOutput = new String[words.length];
int[] repeats = new int[words.length];
// Increment a single repeat
for (int i = 0; i < words.length; i++) {
repeats[i] = 1;
// Increment when repeated.
for (int j = i + 1; j < words.length - 1; j++) {
if (words[i].equalsIgnoreCase(words[j])) {
repeats[i]++;
}
}
wordOutput[i] = words[i] + "\t" + words[i].length() + "\t" + repeats[i];
}
When I run the program, I get the following output:
Equal 5 2
Equal 5 1 <- This is a duplicate word and should not be here when it repeats.
Does anyone know where my problem is? Is it something relating that deals with my repeats array?
The first problem is that in the inner for loop you are looping from i+1 to length-1. You need to loop till length. Second you will need to determine if there are any occurrences of the word in the String, and if so use a continue statement. You can do:
outer:
for (int i = 0; i < words.length; i++) {
repeats[i] = 1;
for(int index = i-1; index >= 0; index--) {
if(words[i].equals(words[index])) {
continue outer;
}
}
...
}
However the problem with this is that there will be null values at the end of the list, as you specify an Array with the same length as the number of words. To solve this you can do:
wordOutput = Arrays.stream(wordOutput).filter(e-> e!= null).toArray(String[]::new);
Which will filter out the null values
Output:
(With the input String: "This is a String is a with a lot lot of this repeats repeats")
This 4 2
is 2 2
a 1 3
String 6 1
with 4 1
lot 3 2
of 2 1
this 4 1
repeats 7 2
Instead of incrementing count at all index store the count only in last occurence of word, in other case, have the count value of 0. at the end traverse the count array, if its greater than zero, print the value and its count
private void analyzeWords(String s) {
String[] words = sentence.split(" ");
wordOutput = new String[words.length];
int[] repeats = new int[words.length];
for (int i = 0; i < words.length; i++) {
int count =1;
int index = i;
for (int j = i + 1; j < words.length - 1; j++) {
if (words[i].equalsIgnoreCase(words[j])) {
count++;
index = j;
}
}
if(repeats[index]==0){
repeats[index]=count; // update repeat array only for last occurence of word
wordOutput[i] = words[i] + "\t" + words[i].length() + "\t" + repeats[index];
}
}
First, as GBlodgett mention you should check all left words for repeats, your current solution skips last word. Update second loop termination condition to j < words.length.
Second, if you want to print duplicates only once you need a condition in your solution. One of the example:
boolean[] duplicates = new boolean[words.length];
// Increment a single repeat
for (int i = 0; i < words.length; i++) {
repeats[i] = 1;
// Check for duplicates,
// If the word was not marked as duplicate
if (!duplicates[i]) {
// Increment when repeated.
for (int j = i + 1; j < words.length; j++) {
if (words[i].equalsIgnoreCase(words[j])) {
repeats[i]++;
duplicates[j] = true;
}
}
wordOutput[i] = words[i] + "\t" + words[i].length() + "\t" + repeats[i];
}
}
There is a Java 8+ solution, for example:
Map<String, Long> m = Arrays.stream(s.split(" ")).collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
Map will have pairs of word and it occurrences.

use for loop how print it separately after two character a string java

input 10100011
output 10 10 00 11 two word separately.
static String getValue(String x){
String y = "";
int getLength = x.length();
if (getLength % 2 == 0){
System.out.println("Length : "+getLength/2);
for (int i = 0; i < getLength/2; i++){
}
}
return y;
}
You can use string operations for this:
for (int i = 0; i < str.length()-1; i+=2){
System.out.print(str.substring(i, i+2) + " ");
}
if(str.length() % 2 != 0)
System.out.print(str.substring(str.length()-1));
This solution uses a StringBuilder1 to append the character to the string being built.
The for loop starts at index 0. In the body of the for loop, it gets the character at index i and i + 1 and appends to the current builder along with a space. On each iteration, i gets incremented by two.
StringBuilder builder = new StringBuilder();
if (getLength % 2 == 0){
System.out.println("Length : "+getLength/2);
for (int i = 0; i < x.length(); i += 2){
builder.append(x.charAt(i))
.append(x.charAt(i + 1))
.append(" ");
}
}
return builder.toString();
1The reason for using a StringBuilder is for performance benefits. Read more about this here.
As per my understanding, you want to print two digits in string separately.
As per 10 10 00 11 this output,
static String getValue(String x){
String y = "";
int getLength = x.length();
System.out.println("Length : "+getLength/2);
for (int i = 0; i < getLength; i++){
if(i%2 == 1) { // this purpose of this check is to make sure this string index starting from 0.
System.out.println(y[i]+" ") // whenever second digit comes it will print space as well to show seperation.
} else {
System.out.println(y[i])
}
}
return y;
}

First repeated string java

OK, i know this question was asked many times here, but i still don't get it, how to find the first repeated character in a string ?
I did something which was close, but it gave me all repeated characters instead of only the first one.
Here's what i did :
private static void stringChar(){
String s = "sababa";
int count = 0;
char c[] = s.toCharArray();
System.out.println("Duplicate characters are :");
for(int i = 0; i < s.length(); i++){
for(int j = i + 1; j < s.length(); j++){
if(c[i] == c[j]) {
System.out.println(c[j]);
count++;
break;
}
}
}
}
One quick and dirty (yet effective) approach which comes to mind is to maintain a map whose keys are the characters. In this case, we don't even need a formal map, because we can use an integer array which maps to the underlying ASCII values of the characters.
The basic idea here is to walk down the string, and check the array if we have seen it before. If so, then print that character and exit.
int[] nums = new int[128]; // assuming only basic ASCII characters
String str = "stuff";
for (int i=0; i < str.length(); ++i) {
int index = str.charAt(i);
if (nums[index] != 0) {
System.out.println("The first repeated character is: " + str.charAt(i));
break;
}
++nums[index];
}
Demo
You need to break the outer loop if you have already found the repeating character.
boolean found = false;
for(int i = 0; i < s.length(); i++){
for(int j = i + 1; j < s.length(); j++){
if(c[i] == c[j]) {
System.out.println(c[j]);
found = true;
break;
}
}
if (found) {
break;
}
}
If you want the count of it
int count = 0;
char repeatingChar = '0'; //dummy to overcome compiler warning
for(int i = 0; i < s.length(); i++){
for(int j = i + 1; j < s.length(); j++){
if(c[i] == c[j]) {
repeatingChar = c[j];
count++;
}
}
if (count > 0) {
System.out.println("Repeating char is " + repeatingChar + ". Occurred " + count + " times");
break;
}
}
The first repeated char is one you have seen before as you iterate the chars in the string. You can keep track of the first time you see a char with a Boolean array. The array is indexed with the char value. Java automatically "widens" char to int. So, for each char, check if it's been seen before and if not, mark that it has been seen.
String s = "sababa";
boolean[] seenChars = new boolean[Character.MAX_VALUE + 1]; // initialized to all false.
for (char c : s.toCharArray()) {
if (Character.isSurrogate(c)) throw new IllegalArgumentException("No first char seen before seeing a surrogate. This algorithm doesn't work for codepoints needing surrogates in UTF-16.");
if (seenChars[c]) {
System.out.println("First repeated char is: " + c);
break;
}
seenChars[c] = true;
}
You might notice that I've been saying char instead of character. Character is not a well-defined term. Java's text datatypes use the UTF-16 encoding of the Unicode character set. Some Unicode codepoints require two UTF-16 code units (char), which are sometimes called surrogate pairs. Since they are not all unique as individual chars, the algorithm doesn't work if they are present. For example, try String s = "sab🚲aba"; (You can also write it as "sab\uD83D\uDEB2aba".) The answer would be "a", again. But now try String s = "sab🚲🚶aba"; (You can also write it as "sab\uD83D\uDEB2\uD83D\uDEB6aba".) The answer should still be "a" but the algorithm would say "\uD83D" (which of course can't be displayed because it is only part of a codepoint).
Short and Simple >
void findFirstDupChar() {
String s = "google";
Integer dupIndex = s.length() - 1;
boolean isDuplicateExists = false;
Map<Character, Integer> map = new LinkedHashMap<>();
char[] words = s.toCharArray();
for (int i = 0; i < words.length; i++) {
Integer index = map.put(words[i], i);
if (index != null) {
if (index < dupIndex) {
dupIndex = index;
isDuplicateExists = true;
}
}
}
System.out.println(isDuplicateExists ? words[dupIndex] + ", index=" + dupIndex : "No duplicateds found");
}
This will print output as following >
g, index=0

Compare & Remove a specific character from two strings at a time and display the remaining strings

my probem is i have two strings like durgaprasad and spandana . here i want to compare 1st string first cahr to the second string all characters if the first sting first char is matched then remove that character from first & second string also, and then display the string (all chars except removed char).
like
durgaprasad
spandana
1st string 1st char - d
compare to all chars in 2nd string-
founded---at position[4]--d
remove that char from 1st string & 2nd string
so we get-----
1st string :urgaprasad
2nd string :spanana
finally i want to get --
1st string--urgrd2nd string--nn
i have tried a lot but i have getting compare to above my code is like this
for(int i = 0; i < firstStr.length(); i++) {
System.out.println("char position :"+firstStr.charAt(i));
int k = 0;
for( int j = 0; j < secondStr.length(); j++) {
//System.out.println("second position :"+secondStr.charAt(j));
if ( ( firstStr.charAt(i) == secondStr.charAt(j) ) && ( k == 0 ) ) {
secondStr = secondStr.substring( 0 , j ).concat(secondStr.substring( j + 1 ) );<br />firstStr = firstStr.substring( 0 , i ).concat(firstStr.substring( i + 1 ) );
}
}
}
for my requirement what changes i have done here
Thanks
Something like...this?
public void RemoveCharacter(String s1, String s2) {
System.out.println("First string: " + s1 + "\nSecond string: " + s2);
for (int i = 0; i < s1.length(); i++) {
for (int j = 0; j < s2.length(); j++) {
if (s1.charAt(i) == s2.charAt(j)) {
RemoveCharacter(s1.substring(0, i) + s1.substring(i + 1), s2.substring(0, j) + s2.substring(j + 1);
return;
}
}
}
}
It pretty much has to be a recursive function if you want to continually strip characters, because removing characters screws up the for-loop iterations (although I suppose you could do i-- and j-- inside the if-statement).
Here's some code.
for(int i = 0; i < firstStr.length(); i++) {
System.out.println("char position :" + firstStr.charAt(i));
for(int j = 0; j < secondStr.length(); j++) {
//System.out.println("second position :" + secondStr.charAt(j));
if (firstStr.charAt(i) == secondStr.charAt(j)) {
firstStr = firstStr.substring(0, i) + firstStr.substring(i + 1);
secondStr = secondStr.substring(0, j) + secondStr.substring(j + 1);
}
}
}
Mostly your code was valid. You must remove the character from firstStr as well as secondStr to achieve the wanted result. Also, you can concat strings with just +.

pyramid sequence in Java

I am new to Java. Just now I'm practing. If I give input as 6, output should be like this:
1
2 3
4 5 6
Here I'm posting code that I tried:
import java.util.Scanner;
public class Number {
public static void main(String args[]){
int n;
Scanner in = new Scanner(System.in);
n = in.nextInt();
in.close();
int k = 1;
for (int i = 1; i <= n; i++)
{
// k=i;
for (int j = 1; j <= i; j++)
{
System.out.print(" " + k);
if (n==k)
{
break;
}
k++;
}
System.out.println("\n");
}
}
}
If I input n=4,i t show the output as:
1
2 3
4
4
Your break will only exit the inner loop (the one that loops over j). The outer loop will continue to run, leading to extra numbers being printed.
You need to either replace it with a return; or System.exit(0), or put a label in front of your outer loop (the one that loops over i) and use a labeled break.
Properly indent your code. It helps your brain to understand.
That said, the solution is two loops with three variables.
You need a loop that goes from 1 to n.
An inner loop that goes from 1 to the number of elements per line.
And you need the number of elements per line. This variable increases every time the inner loop is executed.
It's a badly worded question, but I'm going to guess you want to know why the extra 4?
The reason is you have nested loops, so the break only breaks one loop. Here's how you break out of the outer loop:
outer: for (int i = 1; i <= n; i++) {
...
break outer;
The label outer is arbitrary - you can call it fred is you want.
int n = 6; // target
int i = 0;
int nextRowAt = 2;
int currentRow = 1;
while (++i <= n) {
if (i == nextRowAt) {
System.out.println();
nextRowAt = ++currentRow + i;
}
System.out.print("" + i + " ");
}
But unless you understand it and can properly explain the code, you will probably get a fail on your assignment.
My suggestion is to start by creating/understanding on pen and paper. Write out the sequences and figure out how the algorithm should work. THEN you start coding it.
int sum =0;
int n =10;
// n------> number till where you want to print
boolean limtCrossed = false;
for (int i = 0; i < n &&!limtCrossed; i++) {
for(int j=0;j<=i;j++) {
sum++;
if (sum>n) {
limtCrossed = true;
break;
}
System.out.print(+ sum +" " );
}
System.out.println("\n");
}
public static void main(String[] args)
{
int n = 10;
int k = 1;
boolean breakOuter = false;
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= i; j++)
{
System.out.print(" " + k);
if (n==k)
{
breakOuter = true;
break;
}
k++;
}
if(breakOuter) break;
System.out.println("\n");
}
}

Categories

Resources