I want to count the number of letter, digit and symbol using JAVA
However the result output is not ideal. it should be 5,2,4
but I got 5,2,13
int charCount = 0;
int digitCount = 0;
int symbol = 0;
char temp;
String y = "apple66<<<<++++++>>>";
for (int i = 0; i < y.length(); i++) {
temp = y.charAt(i);
if (Character.isLetter(temp)) {
charCount++;
} else if (Character.isDigit(temp)) {
digitCount++;
} else if (y.contains("<")) {
symbol++;
}
}
System.out.println(charCount);
System.out.println( digitCount);
System.out.println( symbol);
It should be
} else if (temp == '<')) {
symbol++;
}
In your solution, for every non-letter-or-digit character you check if the entire string contains <. This is always true (at least in your example), so the result you get is the number of special characters in the string.
You should use y.charAt(i) == '<' rather than y.contains("<")
if you use y.contains("<"), it uses the whole string to check whether it contains '<' or not. Since String y contains '<'. When in for loop, there are 4 '<', 6 '+' and 3 '>'.
For checking such charraters, y.contains("<") always be true. That is why you get 13 (=4+6+3) for symbol rather than 4.
This bit is wrong:
y.contains("<")
You are checking the whole string each time when you only want to check a single character (temp)
int charCount = 0;
int digitCount = 0;
int symbol = 0;
char temp;
String y = "apple66<<<<++++++>>>";
for (int i = 0; i < y.length(); i++) {
temp = y.charAt(i);
if (Character.isLetter(temp)) {
charCount++;
} else if (Character.isDigit(temp)) {
digitCount++;
****} else if (temp =="<") {
symbol++;
}
}****
else if (y.contains("<")) {
should be
else if (temp == '<') {
because else every time youu have no letter or digit it is raised.
y.contains("<")
seaches for the substring "<" in the string "apple66<<<<++++++>>>" and it always finds it. This happens 13 times which is the number of chars in the substring <<<<++++++>>>" which does contains neither a letter nor a digt.
Related
(Java) How can I count the number of tab and space before the first character of a string
Assume that a string
String line = " Java is good."
There are totally 10 spaces in this string.
However, how can I count the number of tab and space before the first character "J" only?
There are 8 spaces before the first character "J" only.
How about:
String s = " Java is good.";
int total = 0;
for (int i = 0; i < s.length(); i++) {
if (Character.isWhitespace(s.charAt(i))) {
total++;
} else {
break;
}
}
System.out.println(total);
Or
String s = " Java is good.";
int total = 0;
for (int i = 0; i < s.length(); i++) {
char ch = s.charAt(i);
if (ch == ' ' || ch == '\t') {
total++;
} else {
break;
}
}
System.out.println(total);
We can use a regex replacement length trick here:
String line = "\t \t Java is good.";
int numSpaces = line.length() - line.replaceAll("^[\t ]+", "").length();
System.out.println(numSpaces); // 7
For a project which uses the Guava library, the CharMatcher class can determine this:
int count = CharMatcher.noneOf(" \t").indexIn(line);
If the string does not contain a non-space, non-tab character, -1 is returned. Depending on the desired behavior, this special value can be checked for and an appropriate value returned.
For a project which uses the StreamEx library, the IntStreamEx.indexOf() method can determine this:
long count = IntStreamEx.ofChars(line).indexOf(c -> c != ' ' && c != '\t')
.orElse(line.length());
If the string does not contain a non-space, non-tab character, the length of the string is returned. This behavior can be changed by returning a different value from .orElse or otherwise changing how the OptionalLong value is accessed.
There is a trim method which removes leading and trailing whitespaces.
If you were positive there was only leading whitespace and not trailing, you could compare the length of the non-trimmed with the trimmed.
`
int diff = line.length - line.trim().length;
`
Or just count with a for loop
`
int spaces = 0;
for(int x = 0; x < line.length; x++){
if(line[x].equals(" ")){
spaces++;
}else break;
}
`
I have reversed the string and have a for loop to iterate through the reversed string.
I am counting characters and I know I have a logic flaw, but I cannot pinpoint why I am having this issue.
The solution needs to return the length of the last word in the string.
My first thought was to iterate through the string backward (I don't know why I decided to create a new string, I should have just iterated through it by decrementing my for loop from the end of the string).
But the logic should be the same from that point for my second for loop.
My logic is basically to try to count characters that aren't whitespace in the last word, and then when the count variable has a value, as well as the next whitespace after the count has counted the characters of the last word.
class Solution {
public int lengthOfLastWord(String s) {
int count = 0;
int countWhite = 0;
char ch;
String reversed = "";
for(int i = 0; i < s.length(); i++) {
ch = s.charAt(i);
reversed += ch;
}
for(int i = 0; i < reversed.length(); i++) {
if(!Character.isWhitespace(reversed.charAt(i))) {
count++;
if(count > 1 && Character.isWhitespace(reversed.charAt(i)) == true) {
break;
}
}
}
return count;
}
}
Maybe try this,
public int lengthOfLastWord(String s) {
String [] arr = s.trim().split(" ");
return arr[arr.length-1].length();
}
Another option would be to use index of last space and calculate length from it:
public int lengthOfLastWord(String string) {
int whiteSpaceIndex = string.lastIndexOf(" ");
if (whiteSpaceIndex == -1) {
return string.length();
}
int lastIndex = string.length() - 1;
return lastIndex - whiteSpaceIndex;
}
String.lastIndexOf() finds the start index of the last occurence of the specified string. -1 means the string was not found, in which case we have a single word and length of the entire string is what we need. Otherwise means we have index of the last space and we can calculate last word length using lastIndexInWord - lastSpaceIndex.
There are lots of ways to achieve that. The most efficient approach is to determine the index of the last white space followed by a letter.
It could be done by iterating over indexes of the given string (reminder: String maintains an array of bytes internally) or simply by invoking method lastIndexOf().
Keeping in mind that the length of a string that could be encountered at runtime is limited to Integer.MAX_VALUE, it'll not be a performance-wise solution to allocate in memory an array, produced as a result of splitting of this lengthy string, when only the length of a single element is required.
The code below demonstrates how to address this problem with Stream IPA and a usual for loop.
The logic of the stream:
Create an IntStream that iterates over the indexes of the given string, starting from the last.
Discard all non-alphabetic symbols at the end of the string with dropWhile().
Then retain all letters until the first non-alphabetic symbol encountered by using takeWhile().
Get the count of element in the stream.
Stream-based solution:
public static int getLastWordLength(String source) {
return (int) IntStream.iterate(source.length() - 1, i -> i >= 0, i -> --i)
.map(source::charAt)
.dropWhile(ch -> !Character.isLetter(ch))
.takeWhile(Character::isLetter)
.count();
}
If your choice is a loop there's no need to reverse the string. You can start iteration from the last index, determine the values of the end and start and return the difference.
Just in case, if you need to reverse a string that is the most simple and efficient way:
new StringBuilder(source).reverse().toString();
Iterative solution:
public static int getLastWordLength(String source) {
int end = -1; // initialized with illegal index
int start = 0;
for (int i = source.length() - 1; i >= 0; i--) {
if (Character.isLetter(source.charAt(i)) && end == -1) {
end = i;
}
if (Character.isWhitespace(source.charAt(i)) && end != -1) {
start = i;
break;
}
}
return end == -1 ? 0 : end - start;
}
main()
public static void main(String[] args) {
System.out.println(getLastWord("Humpty Dumpty sat on a wall % _ (&)"));
}
output
4 - last word is "wall"
Firstly, as you have mentioned, your reverse string formed is just a copy of your original string. To rectify that,
for (int i = s.length() - 1; i >= 0; i--) {
ch = s.charAt(i);
reversed += ch;
}
Secondly, the second if condition is inside your first if condition. That is why, it will never break ( because you are first checking if character is whitespace, if it is, then you are not going inside the if statement, thus your second condition of your inner if loop will never be satisfied).
public class HW5 {
public static void main(String[] args) {
String s = "My name is Mathew";
int count = lengthOfLastWord(s);
System.out.println(count);
}
public static int lengthOfLastWord(String s) {
int count = 0;
int countWhite = 0;
char ch;
String reversed = "";
System.out.println("original string is----" + s);
for (int i = s.length() - 1; i >= 0; i--) {
ch = s.charAt(i);
reversed += ch;
}
System.out.println("reversed string is----" + reversed);
for (int i = 0; i < reversed.length(); i++) {
if (!Character.isWhitespace(reversed.charAt(i)))
count++;
if (count > 1 && Character.isWhitespace(reversed.charAt(i)) == true) {
break;
}
}
return count;
}
}
=
and the output is :
original string is----My name is Mathew
reversed string is----wehtaM si eman yM
6
Another way to go about is : you use the inbuilt function split which returns an array of string and then return the count of last string in the array.
I'm trying to write a program which accepts a word in lowercase, converts it into uppercase and changes the vowels in the word to the next alphabet. So far, I've done this:
import java.util.*;
class prg11
{
public static void main(String args[])
{
Scanner sc = new Scanner(System.in);
System.out.println("Enter a word in lowercase.");
String word = sc.next();
word = word.toUpperCase();
int length = word.length();
char ch[] = new char[length+1];
for (int i = 0; i<=length; i++)
{
ch[i] = word.charAt(i);
if("aeiou".indexOf(ch[i]) == 0)
{
ch[i]+=1;
}
}
String str = new String(ch);
System.out.println(str);
}
}
The code compiles fine. But, when I run the program and enter a word, say 'hey', the word is printed in uppercase only. The vowels in it (in this case, 'e'), do not get changed to the next alphabet.
How do I resolve this? TIA.
Need to change three places, according to the code in the question.
word = word.toUpperCase();
int length = word.length();
// yours: char ch[] = new char[length + 1];
// resulting array needs to be as same length as the original word
// if not, there will be array index out of bound issues
char ch[] = new char[length];
// yours: for (int i = 0; i<=length; i++)
// need to go through valid indexes of the array - 0 to length-1
for (int i = 0; i < length; i++) {
ch[i] = word.charAt(i);
// yours: if ("aeiou".indexOf(ch[i]) == 0) {
// two problems when used like that
// 1. indexOf() methods are all case-sensitive
// since you've uppercased your word, need to use AEIOU
// 2. indexOf() returns the index of the given character
// which would be >= 0 when that character exist inside the string
// or -1 if it does not exist
// so need to see if the returned value represents any valid index, not just 0
if ("AEIOU".indexOf(ch[i]) >= 0) {
ch[i] += 1;
}
}
Here's a little concise version. Note the changes I've done.
String word = sc.next().toUpperCase();
char ch[] = word.toCharArray();
for (int i = 0; i < ch.length; i++) {
if ("AEIOU".indexOf(ch[i]) >= 0) {
ch[i] += 1;
}
}
Java doc of indexOf().
public int indexOf(int ch)
Returns the index within this string of the first occurrence of the specified character.
If a character with value ch occurs in the character sequence represented by this String object,
then the index (in Unicode code units) of the first such occurrence is returned.
For values of ch in the range from 0 to 0xFFFF (inclusive), this is the smallest value k such that:
this.charAt(k) == ch
is true. For other values of ch, it is the smallest value k such that:
this.codePointAt(k) == ch
is true. In either case, if no such character occurs in this string, then -1 is returned.
Parameters:
ch - a character (Unicode code point).
Returns:
the index of the first occurrence of the character in the character sequence represented by this object,
or -1 if the character does not occur.
I think this should do it, let me know if it doesn't
public class prg11 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("Enter a word.");
String word = sc.next();
sc.close();
word = word.toUpperCase();
int length = word.length();
char ch[] = new char[length+1];
for (int i = 0; i<length; i++) {
ch[i] = word.charAt(i);
if("AEIOU".indexOf(ch[i]) > -1) {
ch[i]+=1;
}
}
String str = new String(ch);
System.out.println(str);
}
}
Let me know if it works.
Happy coding ;) -Charlie
Use:
for (int i = 0; i<length; i++)
instead as the last index is length-1.
use for (int i = 0; i<=length-1; i++) instead of for (int i = 0; i<=length; i++) and if("AEIOU".indexOf(ch[i]) != -1) instead of if("aeiou".indexOf(ch[i]) == 0)
reason
1.array index starts from 0 that's why length-1
2. As you already made your string in upper case so check condition on "AEIOU"
3. every non-vowel character will return -1 so use if("AEIOU".indexOf(ch[i]) != -1)
"aeiou".indexOf(ch[i]) == 0 will only match 'a' characters (since that is the character at index 0). You should be looking for any index that is greater than -1. Additionally, since you've already converted the string to uppercase, you should be checking against "AEIOU" instead of "aeiou".
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
If I have
String x = "test";
String s = "tastaegasghet;
you can find t e s t inside the string s. The naive way of doing this with a known string would be something like this:
.*t+.*e+.*s+.*t+.*
This will return true if we can find the letters t e s t in order and any characters inbetween. I want to do the same thing but with two unknown Strings x and s or in otherwords, String s and x can be anything. I don't want something hard coded but something for general use instead.
This is the pseudocode for looping solution:
function (
needle, // x
haystack // s
) {
j = 0
for (i = 0; i < haystack.length && j < needle.length; i++) {
if (haystack[i] == needle[j]) {
j++
}
}
return j == needle.length
}
You only need to loop through each character in haystack string and advance the pointer in needle string when you find a matching character. If the pointer reaches the end of the needle string, it means the needle string can be found as a subsequence of the haystack string.
A small optimization you can do is checking needle.length <= haystack.length before starting the loop.
Just for fun
If you want to go the Cthulhu's way, you can use this construction:
(?>.*?t)(?>.*?e)(?>.*?s)(?>.*?t).*+
This doesn't have the risk of catastrophic backtracking, and should work similar to the loop above (linear complexity), except that it has a lot of overhead compiling and matching the regex.
It's not that hard to just use a loop.
String x = "test";
String s = "tastaegasghet";
int index = 0;
for(int i = 0; i < s.length() && index < x.length(); i++){
if(s.charAt(i) == x.charAt(index)) index++;
}
boolean exists = index == x.length();
System.out.println(exists);
This should be significantly faster than a regex, at least for longer input.
I'd make a simple function, with a loop, instead of a regex. Something like the following:
public boolean containsLetters(string a, string b)
{
char[] aArray = a.toCharArray();
char[] bArray = b.toCharArray();
int lettersFound = 0, lastLocation = 0;
for (int i = 0; i < aArray.length; i++)
{
for (lastLocation=lastLocation; lastLocation < bArray.length; lastLocation++)
{
if (aArray[i] == bArray[lastLocation])
{
lettersFound++;
break;
}
}
}
return lettersFound == aArray.length;
}
The inner for loop stops the first time it finds the letter. It doens't need to determine if it appears more than once since the function returns a boolean, so this saves some time for large strings. It will only return true if it finds them in order. It remembers the index of the last letter it found, and searches through for the next letter from that location.
You can use the Pattern class for this.
String x= "yourValue";
Pattern pattern = Pattern.compile(Mention your pattern here);
Matcher matcher = pattern.matcher(x);
if (matcher.find()) {
System.out.println(matcher.group(0)); //prints /{item}/
} else {
System.out.println("Match not found");
}
Java code without using any built-in function
String s1 = "test";
String s2 = "tastaegasghets";
char ch[] = new char[s1.length()];
char ch1[] = new char[s2.length()];
int k = 0;
for (int i = 0; i < s1.length(); i++) {
ch[i] = s1.charAt(i);
for (int j = 0; j < s2.length(); j++) {
ch1[j] = s2.charAt(j);
if (ch[i] == ch1[j]) {
k++;
break;
}
}
}
if (k == s1.length()) {
System.out.println("true");
} else {
System.out.println("false");
}
I m working with an array of characters in java. The array can have some missing entries in the middle and I need to know the leftmost index that is empty
My code for that is
private int checkMissingEntry(){
int p = 0;
for(int i = characterArray.length - 1; i >= 0; i--){
if (characterArray[i] == ' '){
p = i;
}
else{
}
}
return p;
}
However, characterArray[i] == ' ' does not detect empty character, the code always returns whatever p was originally assigned to, in this case 0. the if statement never gets executed.
I tried '\0' and '\u0000' but none seems to work.
What is the solution?
private int checkMissingEntry(){
String tmp = new String(characterArray);
if (tmp != null)
return tmp.lastIndexOf(" ");
return -1;
}
Why not search from left to right and return the index immediately when you've reached the first missing character?
EDIT: included example array with missing value
private int checkMissingEntry(){
char[]characterArray = new char[4]; // 4 characters in 1 array
characterArray[0] = 'a'; //but we'll only set values for 3 of them
characterArray[2] = 'b'; //so: index 1 is your empty character
characterArray[3] = 'd';
for(int i = 0; i < characterArray.length ; i++){
char c = characterArray[i]; //get the character at index i
if(c =='\0' || c =='\u0000'){ //check for empty character
return i; //return index
}
} return -1; //only returns -1 if characterArray does not contain the empty character
}