I was writing a code that counts special characters in a string prompt from the key board. This is the method.
public static int specislChar(String s){
int counter = 0;
char ch;
for (int i =0 ; i<=s.length(); i++){
ch = s.charAt(i);
if (!Character.isLetterOrDigit(ch) || ch != ' ') {
System.out.print(" " + ch);
counter++;
}
}
return counter;
}
Every time I call this method, at the System.out.print() it gives me an error:
Exception in thread "main" java.lang.StringIndexOutOfBoundsException:
String index out of range: 20
your loop should be less than i<s.length(). it is the cause of StringIndexOutOfBoundsException and you have to use AND operator not OR
for (int i = 0; i < s.length(); i++) {
ch = s.charAt(i);
if (!Character.isLetterOrDigit(ch) && !Character.isSpaceChar(ch)) {
System.out.print(" " + ch);
counter++;
}
}
When debugging this kind of issues, always run you code step by step and check if what you wrote is doing what you expect at every step, it's a simple but invaluable technique :)
If you want to count chars that are not letter/digit/space, this:
|| ch != ' '
will always give true for every character that is not space, the check you need to to is this one:
if ( !(Character.isLetterOrDigit(ch) || (ch==' ')) ){
Or, applying De Morgan's Law:
if ( (!Character.isLetterOrDigit(ch)) && (ch!=' ') ){
The error you are getting is due to this line: for (int i =0 ; i<=s.length(); i++){. In Java, arrays are 0 based and run from 0 to n-1, where n is the amount of entries you have.
Thus, changing it to for (int i =0 ; i<s.length(); i++){ will remove the error.
Also, this: || ch != ' ' will be true for any non special character as well, which will cause inaccurate results. I think you mean && ch != ' '.
Example code:
public class ____QuickTester {
public static void main(String[] args) {
// This should be 11
System.out.println("Number of special characters: " +
specialChar("asdaskd12312!#(#(!##)(*asdas12301230"));
// This should be 8
System.out.println("Number of special characters: " +
specialChar("!a#b#c$d%e aaa bbb ccc !!!"));
}
public static int specialChar(String s) {
// Get rid of alphabets, digits and space
s = s.replaceAll("[A-Za-z0-9 ]", "");
return s.length();
}
}
Output:
Number of special characters: 11
Number of special characters: 8
A much simpler way would be to remove all alphabets, digits, and space
The remaining content will be the special characters
Change your for loop condition from <= to < to solve StringIndexOutOfBoundsException as array index start from 0 so it will go upto length-1.
i < s.length();
And use &&(And) operator instead of ||(Or) operator in if condition as you want to check both the conditions.
if (!Character.isLetterOrDigit(ch) && !Character.isSpaceChar(ch) )
Do something like this :-
public static int specislChar(String s) {
int counter = 0;
for (char ch : s.toCharArray())
if (!Character.isLetterOrDigit(ch) && ch != ' ')
counter++;
return counter;
}
Input :- %#%^&*(hi hello$!!+ #
Output :- 12
you are looping though i<=s.length(); but it should be i<=s.length()-1; because index starts at 0. If it starts at 0 then it should be only to length-1
Related
I'm a beginner in Java and I have a question regarding loops. I've been struggling with this task where it says: Write programs that read a line of input as a string and print the positions of all vowels in the string.
I have managed to print out the number of vowels in the input but I got stuck when it came to print out their positions.
Any help would be appreciated!
System.out.println("Enter your input: ");
String input = in.nextLine();
int sum = 0;
for(int i = 0; i < input.length(); i++){
char vowel = input.charAt(i);
if(vowel == 'a'|| vowel == 'e'|| vowel == 'i'||
vowel == 'o'|| vowel == 'u'|| vowel == 'y'){
sum++;
}
}
System.out.println(sum);
System.out.println("Enter your input: ");
String input = in.nextLine();
int sum = 0;
for(int i = 0; i < input.length(); i++){
char vowel = input.charAt(i);
if(vowel == 'a'|| vowel == 'e'|| vowel == 'i'||
vowel == 'o'|| vowel == 'u'|| vowel == 'y'){
sum++;
System.out.println("position ->"+i);//added line
}
}
System.out.println(sum);
you just needed to add single line that prints the positions
Avoid char
The char type has been essentially broken since Java 2, and legacy since Java 5. As a 16-bit value, char is physically incapable of representing most of the >144,000 characters defined in Unicode.
Code point
To work with individual characters, use code point integer numbers.
Define your set of targeted vowels. Sort the array, so that we may search quickly via binary search.
int[] vowelCodePoints = "aeiouy".codePoints().sorted().toArray() ;
Get the code points of the characters in your input.
int[] codePoints = "test".codePoints().toArray() ;
Loop the array of code points of our input string, by index (zero-based counting). Test each code point to see if it is found within our array of vowel code points.
To go in the reverse direction, from code point integer to the character as text, call Character.toString.
Example code
Pull all the code together.
int[] vowelCodePoints = "aeiouy".codePoints().sorted().toArray();
int[] codePoints = "testy".codePoints().toArray();
List < Integer > indicesOfVowels = new ArrayList <>( codePoints.length );
for ( int index = 0 ; index < codePoints.length ; index++ )
{
int position = Arrays.binarySearch( vowelCodePoints , codePoints[ index ] );
if ( position >= 0 )
{
String vowel = Character.toString( codePoints[ index ] );
System.out.println( "Vowel: " + vowel + " | Index: " + index );
}
}
See this code run at Ideone.com.
Vowel: e | Index: 1
Vowel: y | Index: 4
I got 3 strings from the user as input.Then count the vowels in each word and print as follows.If the vowel count = 0 and 1 then print 0.If the vowel count = 2 then print 2.If the vowel count is greater than or equal to 3 then print 3.
I tried this code.
Scanner in = new Scanner(System.in);
String[] str = new String[3];
for (int i = 0; i<3; i++)
str[i] = in .nextLine();
for (int j = 0; j<3; j++) {
String s1 = str[j];
String s = s1.toLowerCase();
int count = 0;
for (int i = 0; i<s.length(); i++)
{
if (s.charAt(i) == 'a' || s.charAt(i) == 'e' || s.charAt(i) == 'i' || s.charAt(i) == 'o' || s.charAt(i) == 'u') {
count++;
}
if (s.charAt(i) == ' ') {
if (count == 0||count == 1) {
System.out.print("0");
} else if (count == 2) {
System.out.print("1");
} else {
System.out.print("3");
}
count = 0;
}
}
if (count == 0||count == 1) {
System.out.println("0");
} else if (count == 2) {
System.out.println("1");
} else {
System.out.println("3");
}
}
But there is one condition only print the vowel count for 3 words only even if the user enter the string with more than 3 words.For eg if the user gives the string "hi hello all, how are you,I am fine and u" it prints "010
011
001" like this only but this code prints as "010
011
00100".Now how can i change the code to print the vowel count only for 3 words and not for more than 3?
You need some kind of a break after the third word. One option would be to make an extra variable for tracking it and increment it when the character is space. After 3 words you could break the loop.
Other option would be to split the String into words with split() method and the iterate over the first 3 only.
You could simplify your code a lot and it will be easier to achieve what you want. Instead of loop on each char, you can split your string. And then loop on the words. Something like this:
for (int j = 0; j<3; j++) {
String[] words = str[j].toLowerCase().split(" ");
// Use Math.min, thanks that it works even if you have only 2 words
for(int i = 0; i < Math.min(3, words.length()); i++) {
int count = 0;
for (char letter : words[i].toCharArray()) {
// if letter is vowel: count += 1;
}
// System.out.println depending on count value
}
}
You could use a Regex to split words into a sentence, using this method:
String[] splits = myPhrase.split(" ");
to split words in a sentence, but you have to be careful that if the user enters more spaces, the first one is "eliminated" and those just after end up in the split.
For example:
String phrase = "1 2 3 z";
String[] splits = phrase.split(" ");
generates this array: [1|2| |3| | |z].
So, in my opinion, at that point you could use a filter, go through the array / list again eliminating any space derived from the regex or more simply when you scroll through the array / list and find a space you don't consider it.
At this point go to analyze the first 3 elements of the array / list, discarding the others (maybe using a counter).
Finally, again using a Regex, you can also check if the character you are analyzing is a vowel or not using this command:
if (s.charAt(i).matches("[AEIOUaeiou]")){ /*it's a vowel*/}
Can you guys, please, explain to me what does count[word.charAt(i)]++, exactly do in this code and overall--?
public static void main(String[] args) {
String S = "Some random text to test.";
int count[] = new int[124];
for (int i=0; i< S.length(); i++) {
count[S.charAt(i)]++;
System.out.print(count[S.charAt(i)] + " ");
}
int max = 1;
char result = ' ';
for (int i = 0; i < S.length(); i++) {
if (max < count[S.charAt(i)] && S.charAt(i) != ' ') {
max = count[S.charAt(i)];
result = S.charAt(i);
}
}
System.out.println(result);
}
The printing of count[S.charAt(i)] was just me trying to figure it out.
S.charAt(i) returns the character in the i-th position of that string S.
Then count[S.charAt(i)] will execute like this. Lets say you get 'S' as the character. Then the character value for 'S' will be 83. So, it will take the element of the 83 index in count array and increment it by one.
word.charAt(i) returns the character at the i-th index in the String word.
count is an int array with all zeros automatically : int count[] = new int[124];
count[i]++ increments the value that is in count at index i by 1.
Here, you're passing word.charAt(i) as an index i.e count[word.charAt(i)]++, and what it does is:
-Evaluate word.charAt(i) first, but
note that index i must be an integer!
so automatically gets the ASCII value of the character. For example ('a' = 97, 'b' = 98..)
-then, count[ASCII number returned]++, for example count[97]++, will be incremented and now count[97] = 1
But note that if your String has '}', there will be Index out of bound exception, since its ASCII value is 125; and 125 > 124 the size of count!
This is my function which takes a string as input for example aabbaaa. I am deleting the character if the next one to it is the same. In this way I am removing consecutive occurrences of a character i.e the string will become aba. But it is throwing me indexoutofbounds exception.
static int alternatingCharacters(String s)
{
StringBuilder sb = new StringBuilder(s);
try
{
for(int i = 0; i < sb.length(); i++)
{
while (sb.charAt(i) == sb.charAt(i+1) && i+1<sb.length())
{
sb=sb.deleteCharAt(i);
}
}
}
catch(Exception e)
{
e.printStackTrace();
}
return 0;
System.out.println(sb);
}
Irrespective of the exception, this is a very inefficient way to delete chars from the string.
Every time you invoke sb.deleteCharAt(i), it has to shift all of the characters to the right of i along by 1. In the worst case, this has quadratic time complexity.
Instead, it is much more efficient simply to move the characters, and then trim the end:
StringBuilder sb = new StringBuilder(s);
if (!s.isEmpty()) {
int len = 1;
for (int i = 1; i < sb.length(); ++i) {
if (sb.charAt(i) != sb.charAt(len - 1)) {
sb.setCharAt(len++, sb.charAt(i));
}
}
sb.setLength(len);
}
This has linear time complexity.
You can do it a little more directly, too, by operating directly on a char[]:
if (!s.isEmpty()) {
char[] cs = s.toCharArray();
int len = 1; // Start at 1, since the first character isn't equal to the one before it.
for (int i = 1; i < cs.length; ++i) {
if (cs[i] != cs[len-1]) {
cs[len++] = cs[i];
}
}
s = new String(cs, len);
}
while (sb.charAt(i) == sb.charAt(i+1) && i+1<sb.length())
In this line, sb.charAt(i) == sb.charAt(i+1) is evaluated before i+1<sb.length(), which means that you check that a following character exists only after you try to retrieve it.
Swap the two conditions, so that the check is performed before.
The index goes out of bounds because of the i+1
The for(int i = 0; i < sb.length(); i++) makes i vary from 0 to length - 1 due to the less than symbol.
This is correct because a String or N characters will start at index 0 and finish at index N-1.
When you do i+1 in the for loop, when it reaches the last character at index i, i+1 goes out of the character array bounds.
Your problem, as mentioned in the comments, is the while loop - so you should first check i + 1 < sb.length() and then check sb.charAt(i) == sb.charAt(i + 1).
Also - two other things:
Remove the println statement as this makes it not compile
No point returning an int (and hardcoded to 0), so change it to String
Example:
static String alternatingCharacters(String s) {
StringBuilder sb = new StringBuilder(s);
try {
for (int i = 0; i < sb.length(); i++) {
while (i + 1 < sb.length() && sb.charAt(i) == sb.charAt(i + 1)) {
sb = sb.deleteCharAt(i);
}
}
} catch (Exception e) {
e.printStackTrace();
}
return sb.toString();
}
Online Demo
Your problem is that you are iterating till sb.length() and then inside the loop in the while condition you are using :
while (sb.charAt(i) == sb.charAt(i+1) && i+1<sb.length())
And the sentence sb.charAt(i+1) is what icauses the IndexOutOfBoundException because there's no such index in the string.
When the loop reaches the last element, you call sb.charAt(i+1) in the while which is placed before i+1<sb.length() so it will be always executed.
What you need to do is to swap the two conditions in the while loop: while(i+1<sb.length() && sb.charAt(i) == sb.charAt(i+1)).
Index out of bounds is generally caused when you are referencing an index that doesn't exist. Also remember that the index count starts from 0 not 1. On the last loop sb.charAt(i+1) would be 7 + 1 = 8, which doesn't exist since your upper boundary is sb.Length(), to fix this just make your upper boundary for(int i = 0; i < sb.length() - 1; i++)
Loop and delete will cause certainly IndexOutOfBoundsException
StringBuilder sb = new StringBuilder("hello"); // length is 5
sb.deleteCharAt(2); // length is 4
And you still iterate until reaching 5, this will cause the exception
You can use Regex to build a clean solution:
"aaabbcccc".replaceAll("([a-z])\\1{1,}", "$1"); // the result will be abc
I want to write a program that prints words incrementally until a complete sentence appears. For example : I need to write (input), and output:
I
I need
I need to
I need to write.
Here is my code:
public static void main(String[] args) {
String sentence = "I need to write.";
int len = sentence.length();
int numSpace=0;
System.out.println(sentence);
System.out.println(len);
for(int k=0; k<len; k++){
if(sentence.charAt(k)!='\t')
continue;
numSpace++;
}
System.out.println("Found "+numSpace +"\t in the string.");
int n=1;
for (int m = 1; m <=3; m++) {
n=sentence.indexOf('\t',n-1);
System.out.println("ligne"+m+sentence.substring(0, n));
}
}
and this is what I get:
I need to write.
16
Found 0 in the string.
Exception in thread "main" java.lang.StringIndexOutOfBoundsException:
String index out of range: -1 at
java.lang.String.substring(String.java:1937) at
split1.Split1.main(Split1.java:36) Java Result: 1 BUILD SUCCESSFUL
(total time: 0 seconds)
I don't understand why numSpace doesn't count the occurrences of spaces, nor why I don't get the correct output (even if I replace numSpace by 3 for example).
You don't have a \t character, so indexOf(..) returns -1
You try a substring from 0 to -1 - fails
The solution is to check:
if (n > -1) {
System.out.prinltn(...);
}
Your loop looking for numSpace is incorrect. You are looking for a \t which is a tab character, of which there are none in the string.
Further, when you loop in the bottom, you get an exception because you are trying to parse by that same\t, which will again return no results. The value of n in n=sentence.indexOf('\t',n-1); is going to return -1 which means "there is not last index of what you are looking for". Then you try to get an actual substring with the value of -1 which is an invalid substring, so you get an exception.
You are mistaken by the concept of \t which is an escape sequence for a horizontal tab and not for a whitespace character (space). Searching for ' ' would do the trick and find the whitespaces in your sentence.
This looks like homework, so my answer is a hint.
Hint: read the javadoc for String.indexOf paying attention to what it says about the value returned when the string / character is not found.
(In fact - even if this is not formal homework, you are clearly a Java beginner. And beginners need to learn that the javadocs are the first place to look when using an unfamiliar method.)
The easiest way to solve this I guess would be to split the String first by using the function String.split. Something like this:
static void sentence(String snt) {
String[] split = snt.split(" ");
for (int i = 0; i < split.length; i++) {
for (int j = 0; j <= i; j++) {
if (i == 1 && j == 0) System.out.print(split[j]);
else System.out.printf(" %s", split[j]);
}
}
}
As other people pointed out. You are counting every characters except tabs(\t) as a space. You need to check for spaces by
if (sentence.charAt(k) == ' ')
\t represents a tab. To look for a space, just use ' '.
.indexOf() returns -1 if it can't find a character in the string. So we keep looping until .indexOf() returns -1.
Use of continue wasn't really needed here. We increment numSpaces when we encounter a space.
System.out.format is useful when we want to mix literal strings and variables. No ugly +s needed.
String sentence = "I need to write.";
int len = sentence.length();
int numSpace = 0;
for (int k = 0; k < len; k++) {
if (sentence.charAt(k) == ' ') {
numSpace++;
}
}
System.out.format("Found %s in the string.\n", numSpace);
int index = sentence.indexOf(' ');
while(index > -1) {
System.out.println(sentence.substring(0, index));
index = sentence.indexOf(' ', index + 1);
}
System.out.println(sentence);
}
Try this, it should pretty much do what you want. I figure you have already finished this so I just made the code real fast. Read the comments for the reasons behind the code.
public static void main(String[] args) {
String sentence = "I need to write.";
int len = sentence.length();
String[] broken = sentence.split(" "); //Doing this instead of the counting of characters is just easier...
/*
* The split method makes it where it populates the array based on either side of a " "
* (blank space) so at the array index of 0 would be 'I' at 1 would be "need", etc.
*/
boolean done = false;
int n = 0;
while (!done) { // While done is false do the below
for (int i = 0; i <= n; i++) { //This prints out the below however many times the count of 'n' is.
/*
* The reason behind this is so that it will print just 'I' the first time when
* 'n' is 0 (because it only prints once starting at 0, which is 'I') but when 'n' is
* 1 it goes through twice making it print 2 times ('I' then 'need") and so on and so
* forth.
*/
System.out.print(broken[i] + " ");
}
System.out.println(); // Since the above method is a print this puts an '\n' (enter) moving the next prints on the next line
n++; //Makes 'n' go up so that it is larger for the next go around
if (n == broken.length) { //the '.length' portion says how many indexes there are in the array broken
/* If you don't have this then the 'while' will go on forever. basically when 'n' hits
* the same number as the amount of words in the array it stops printing.
*/
done = true;
}
}
}