Check that the next char is end of array - java - java

So trying to create a method which goes through a string and checks each char for vowels.
However when it reaches the end and does a forward check for the char. i get a strings out of bound exception. i tried adding a check for whitespace for the char ahead but still get the exception.
for (char i = 0; i < buffer.length; i++) {
if (isVowel(key.charAt(i + 1)) && !Character.isWhitespace(key.charAt(i + 1)) {
buffer[i] = key.charAt(i);
} else {
break;
}
}

Create the buffer for a correct size like
char[] keyChar = key.toCharArray();
char[] buffer = new char[keyChar.length]; //same size
Then, iterate the key, not the buffer
for(int i = 0; i < keyChar.length -1; ++i)
And don't go to the end since you use [i + 1] in the logic.
Note that this will ignore the last character, you have to see if you want that last character or not in the buffer. If so, you will need to add it (without your check on the next one obviously)

for (char i = 0; i < buffer.length-1; i++) {
if (isVowel(key.charAt(i + 1)) && !key.charAt(i + 1) && !Character.isWhitespace(key.charAt(i + 1)) {
buffer[i] = key.charAt(i);
} else {
break;
}
}

Related

How to fix: Number of occurrences of a letter in a string

I'm trying to count the number of occurrences of letters that are in string. The code that I have written technically does what I want, but not the way I want to do it. For example, if I input "Hello World", I want my code to return "a=0 b=0 c=0 d=0 e=1 etc...." with the code I have written it returns "H=1, e=1, l=2 etc...."
Also how would I make sure that it is not case sensitive and it doesn't count spaces.
Code:
import java.util.Scanner;
public class Sequence {
private static Scanner scan = null;
public static void main(String[] args) {
scan = new Scanner(System.in);
String str = null;
System.out.print("Type text: ");
str = scan.nextLine();
int[] count = new int[255];
int length = str.length();
for (int i = 0; i < length; i++)
{
count[str.charAt(i)]++;
}
char[] ch = new char[str.length()];
for (int i = 0; i < length; i++)
{
ch[i] = str.charAt(i);
int find = 0;
for (int j = 0; j <= i; j++)
{
if (str.charAt(i) == ch[j])
find++;
}
if (find == 1)
{
System.out.print(str.charAt(i) + "=" + count[str.charAt(i)] + " ");
}
}
}
}
As I hinted in my original comment you only need an array of 26 int(s) because there are only 26 letters in the alphabet. Before I share the code, it is important to note that Java char is an integral type (and, for example, 'a' + 1 == 'b'). That property is important, because it allows you to determine the correct offset in an array (especially if you force the input to lower case). Something like,
Scanner scan = new Scanner(System.in);
System.out.print("Type text: ");
String str = scan.nextLine();
int[] count = new int[26];
for (int i = 0; i < str.length(); i++) {
char ch = Character.toLowerCase(str.charAt(i)); // not case sensitive
if (ch >= 'a' && ch <= 'z') { // don't count "spaces" (or anything non-letter)
count[ch - 'a']++; // as 'a' + 1 == 'b', so 'b' - 'a' == 1
}
}
for (int i = 0; i < count.length; i++) {
if (count[i] != 0) {
System.out.printf("%c=%d ", 'a' + i, count[i]);
}
}
System.out.println();
If you really want to see all of the letters that have counts of zero (seems pointless to me), change
if (count[i] != 0) {
System.out.printf("%c=%d ", 'a' + i, count[i]);
}
to remove the if and just
System.out.printf("%c=%d ", 'a' + i, count[i]);
Change str = scan.nextLine(); to str = scan.nextLine().toLowerCase().replaceAll("\\s+","");
.toLowerCase() is a method which makes every char in the string lowercase.
.replaceAll() is a method which replaces one char with another. In this case, it replaces whitespaces with nothing.

index out of bounds exception strings 8

I'm trying to set up a compression algorithm that places a number before a char in a string when that char can be seen in succession. EX: for the string
"balloonnnnns" it would be compressed to "ba2l2o5n" but I am receiving an index out of bounds error:
for(int i = 0; i < (length-1); i++ ){
if (original.charAt(i) == original.charAt(i + 1)){
count = count + 1;
original = original.substring(i, i+1);
System.out.println(original);
System.out.println(count);
if(count > 0){
altered = count + original.substring(i);
System.out.println(altered);
}
}else{
count = 0;
As #Jon Skeet pointed out you shouldn't change your original while in the loop.
You could try this way (comments on code for understanding)
Test:
public class Test
{
public static void main ( String [ ] args )
{
String original = "balloonnnnns";
int length = original.length ( );
int count = 1;
String altered = "";
//Loop over all string
for(int i = 0; i < (length-1); i++ ){
//while they are the same
while (original.charAt(i) == original.charAt(i + 1)){
//count and keep going on the original string
count++;
i++;
//avoid border case when last character is repeated, i.e : baaaaaaaa
if ( i == length -1)
{
break;
}
}
//if they are repetead
if(count > 1)
{
//add altered + count + charRepeated, i.e. a3e5t
altered = altered +count + original.charAt(i);
}
else{
//just add the normal character without count
altered += original.charAt(i);
}
//add last character if not repeated
if ( (i == length - 2) && (count > 1))
{
altered += original.charAt ( i+1 );
}
//reset counting
count = 1;
}
System.out.println ( altered );
}
}
Output:
ba2l2o5ns
The first time your loop gets executed, you update string named 'original' with the first character of actual 'original' string.
For eg. if String original = "aaa" - after loop executes for 0, value for original becomes 'a'!
You can refer this for solutions:
Java compressing Strings

Code flow not entering the statement of nested if for changing a string to title case

This code does not work after the nested if condition. I am trying to convert a String to title case where as soon as a space is encountered in the string, I check the next character for lowercase and convert it to uppercase using ASCII character encoding. However it does go until the nested if loop, but does not execute the condition there. I have used Eclipse debug perspective to come to this conclusion
public class Word {
public static void main(String args[]) {
String rev= "This is a string";
char a[]=new char[rev.length()];
for (int i = 0; i < a.length;i ++) {
a[i]=rev.charAt(i);
if (a[i] == ' ') {
if (a[i+1] >= 'a' && a[i+1] <= 'z') {
a[i+1] -= 32;
}
}
}
String title=new String (a);
System.out.print(title);
}
}
The problem with the given program is :
In if (a[i+1] >= 'a' && a[i+1] <= 'z') , a[i+1] is not initilized by a[i]=rev.charAt(i); so, at (i +1) index, it doesn't get any value on a[i+1].
You make upper case in index (i +1) using a[i+1] -= 32; and on the next iteration , this index value again replace by a[i]=rev.charAt(i);
Consider last character as space then use if (rev.charAt(i) == ' ' && i +1 < a.length) condition for handling that
Check this :
public class Word {
public static void main(String args[]) {
String rev = "This is a string";
char[] a = new char[rev.length()];
int i = 0;
for (; i < a.length; i++) {
a[i] = rev.charAt(i);
if (rev.charAt(i) == ' ' && i + 1 < a.length) {
if (rev.charAt(i+1) >= 'a' && rev.charAt(i+1) <= 'z') {
a[i + 1] = (char)(rev.charAt(i + 1) - 32);
i++;
}
}
}
String title = new String(a);
System.out.print(title);
}
}
Output:
This Is A String
char a[]=new char[rev.length()];
Here you create a new char[]. What are the values of each character at this time? (hint: System.out.println( Character.digit( a[0], 10 ) );, or just use a debugger to inspect it)
for (int i = 0; i < a.length;i ++) {
a[i]=rev.charAt(i);
This is a simple and straightforward loop to copy characters one at a time from a String to a char[]. At each iteration through the loop, the elements in the array from a[0] through a[i] are set to a meaningful value. The elements in the array from a[i+1] through a[a.length] are not yet set.
if (a[i+1]
Since you have not yet set a[i+1], checking its value is not very meaningful.
Also, consider what happens if the last character of the string is a space ...
class Word {
public static void main(String args[]) {
String rev= "This is a string";
Pattern pattern=Pattern.compile("(^\\w)|(\\s\\w)");
//taken from http://docs.oracle.com/javase/6/docs/api/java/util/regex/Matcher.html#appendReplacement(java.lang.StringBuffer, java.lang.String)
Matcher matcher = pattern.matcher(rev);
StringBuffer sb = new StringBuffer();
while (matcher.find()) {
matcher.appendReplacement(sb, matcher.group().toUpperCase());
}
matcher.appendTail(sb);
System.out.print(sb.toString());
}
}

File Compression

I am trying to compress a string by turning it in to letters and numbers. Example:
INPUT: AAAAbbWWWW
OUTPUT: A4-b2-W4
Here is the problem I am running in to:
When I run it with the query "aaaaaaa", I get "a7".
When I run it with the query "aaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbb", I get "a12-b2-b2-b2-b2-b2-b2-b2-b2-b2-b2-b2-b2-b2-b2".
My code is
List<Character> chars = new ArrayList<Character>();
for (int i = 0; i < toCompress.length(); i++) {
chars.add(toCompress.charAt(i));
}
List<String> bits = new ArrayList<String>();
for (int i = 0; i < chars.size(); i++) {
char toMatch = chars.get(i);
int matching = 1;
for (int dontuse = i; dontuse < chars.size(); dontuse++) {
int x = dontuse + 1;
if (x >= chars.size()) {
continue;
}
if (chars.get(x) == toMatch && (x - 1 == matching)) {
matching++;
}
}
if (!bits.contains(toMatch + "" + matching)) {
bits.add(toMatch + "" + (matching + 1));
i = i + matching;
}
}
String compressed = "";
for (int y = 0; y < bits.size(); y++) {
if (y == (bits.size() - 1)) {
compressed += bits.get(y);
} else {
compressed += bits.get(y) + "-";
}
}
return compressed;
Can anyone tell me how to stop it from only counting to two in every segment but the first?
A simple algorithm for your problem would be the following:
private static String compress(String str) {
StringBuilder compressed = new StringBuilder();
int i = 0;
while (i < str.length()) {
int length = 1;
while (i < str.length() - 1 && str.charAt(i) == str.charAt(i+1)) {
length++;
i++;
}
compressed.append(str.charAt(i)).append(length).append('-');
i++;
}
return compressed.deleteCharAt(compressed.length() - 1).toString();
}
It goes like this: while the character of the input String at index i is the same as the following character, we increment a length. As a result, length is then equal to the number of following characters that are the same.
When we hit a different character, we stop the loop, store the current character and its length, and repeat all this again for the next character.
Note that this algorithm will "compress" the String b into b1. You did not specify how it should behave on such Strings. If you don't want to this, you can simply add a check on length before it is appended to the current compressed String.
Alright, I fixed it. Here is what I did:
List<Character> chars = new ArrayList<Character>();
List<Character> oChars = new ArrayList<Character>();
for (int i = 0; i < toCompress.length(); i++) {
chars.add(toCompress.charAt(i));
}
for (char c : chars) {
if (!oChars.contains(c)) {
oChars.add(c);
}
}
HashMap<Character, Integer> map = new HashMap<Character, Integer>();
for (int i = 0; i < chars.size(); i++) {
try {
map.put(chars.get(i), map.get(chars.get(i)) + 1);
} catch (NullPointerException ex) {
map.put(chars.get(i), 1);
}
}
String compressed = "";
for (char c : oChars) {
int amount = map.get(c);
compressed += c + "" + amount + "-";
}
StringBuilder b = new StringBuilder(compressed);
b.replace(compressed.lastIndexOf("-"), compressed.lastIndexOf("-") + 1, "" );
compressed = b.toString();
return compressed;
Well, your logic doesn't really work. In fact, it's pretty hard to understand what you are trying to do here.
The place where you add to bits is the important part, because at the end you basically display what's in bits. So let's look at that part.
if (!bits.contains(toMatch + "" + matching)) {
bits.add(toMatch + "" + (matching + 1));
i = i + matching;
}
So it's important to see where you change the matching.
The first loop runs fine verifying against the a. But your problem is in this condition:
if (chars.get(x) == toMatch && (x - 1 == matching)) {
matching is 1 at the beginning of the inner loop. So as soon as you are into ranges of i that are beyond 0 and 1, x - 1 is not going to be equal to matching, and that means that matching will not change, it will stay at 1.
So except your first character, you'll never get a correct number in matching, because it will never be incremented. There is no point in comparing a running index to a count.

how to get all the positions of the set bits of a binary string in java?

For example if the binary string is 10100010 then the program must return 1st,3rd and 7th i.e the positions of the 1's.
Below is the code which you are looking for note that regex starts with zeroth position.
String regex = "[1]";
String data = "10100010";
Matcher m = Pattern.compile(regex).matcher(data);
while(m.find())
{
System.out.println(m.group() + " => " + (m.start()+1) );
}
Two options:
Convert it to an integer/long (if possible) and then shift one bit each time and check if it's 1. For example:
String str = "10100010";
Integer x = Integer.valueOf(str);
int len = str.length();
while (x != 0) {
if (x & 0x1 == 1) {
System.out.println(len);
}
len--;
x >>= 1;
}
Scan the string by-index and check if its' value is 1:
for (int i = 0; i < str.length(); i++) {
if (str.chatAt(i) == '1') {
//print
}
}
char[] str="10100010".toCharArray();
for(int i=0;i<str.length;i++){
if(str[i]=='1'){
int setBit=1;
setBit+=i;
System.out.println(setBit+"th");
}
}

Categories