I have a string "text" in one class which calls on a method in another class to convert text in various ways. In this method though I am left with an "ArrayIndexOutOfBoundsException" error.
public String toUnicode() {
char unicodeTextArray[] = new char[text.length()];
if (text == null || text.isEmpty()) {
return "";
}
String unicodeTextArrayString[] = new String[text.length()];
for (int i = 0; i < text.length(); i++) {
unicodeTextArray[i] = text.charAt(i);
if (unicodeTextArray[i] < 0x10) {
unicodeTextArrayString[i] = "\\u000" + Integer.toHexString(unicodeTextArray[i]);
} else if (unicodeTextArray[i] < 0x100) {
unicodeTextArrayString[i] = "\\u00" + Integer.toHexString(unicodeTextArray[i]);
} else if (unicodeTextArray[i] < 0x1000) {
unicodeTextArrayString[i] = "\\u0" + Integer.toHexString(unicodeTextArray[i]);
}
unicodeTextArrayString[i] = "\\u" + Integer.toHexString(unicodeTextArray[i]);
}
String unicode = unicodeTextArrayString[text.length()];
return unicode;
}
Changing one line to an arbitrarily large number such as:
String unicodeTextArrayString[] = new String[9999];
Results in no error, but it returns null.
I thought about setting an int variable to increase the length of the array, but * 4 was still too small of an array size and it seems like if I go too large it just returns null.
How could I go about getting the correct length of the array?
EDIT: I found a non-array approach that works, but I would still like to know if there is a way to make the above array approach work in some way.
public String toUnicode()
{
String unicodeString = "";
for (int i = 0; i < text.length(); i++)
{
char c = text.charAt(i);
String s = String.format ("\\u%04x", (int)c);
unicodeString = unicodeString + s;
}
return unicodeString;
}
EDIT 2: In case anyone reading this is curious, to get the decimal value of the unicode:
public String toUnicode()
{
String unicodeString = "";
for (int i = 0; i < text.length(); i++)
{
char c = text.charAt(i);
int unicodeDecimal = c;
unicodeString = unicodeString + unicodeDecimal + " ";
}
return unicodeString;
}
EDIT 3: I ended up deciding to use the following, which separates unicode decimals by space, and checks for the unicode value 10 (which means new line) and outputs a new line into the string instead of that value.
public String toUnicode()
{
String unicodeString = "";
for (int i = 0; i < text.length(); i++)
{
char c = text.charAt(i);
int unicodeDecimal = c;
if (unicodeDecimal == 10)
{
unicodeString = unicodeString + "\n";
}
else
{
unicodeString = unicodeString + unicodeDecimal + " ";
}
}
return unicodeString;
}
couple of things
1) Move line
char unicodeTextArray[] = new char[text.length()]; after following code
if (text == null || text.isEmpty())
{
return "";
}
char unicodeTextArray[] = new char[text.length()];
2) Error is because of this String unicode = unicodeTextArrayString[text.length()];
e.g you get a text as "hello", then you initialized unicodeTextArrayString of size text.length() which is 5. So you can fetch back from this array for index 0 to 4 only, but you are trying to fetch from index 5, which is out of bounds.
3) After having said so, the code/logic seems wrong. I just modified your logic using StringBuilder instead. You can check for conversion logic
public static String toUnicode(String text)
{
if (text == null || text.isEmpty())
{
return "";
}
StringBuilder unicodeTextArrayString = new StringBuilder();
for (int i = 0; i < text.length(); i++)
{
char ch = text.charAt(i);
if (ch < 0x10)
{
unicodeTextArrayString.append("\\u000" + Integer.toHexString(ch));
}
else if (ch < 0x100)
{
unicodeTextArrayString.append("\\u00" + Integer.toHexString(ch));
}
else if (ch < 0x1000)
{
unicodeTextArrayString.append("\\u0" + Integer.toHexString(ch));
}
else
{
unicodeTextArrayString.append("\\u" + Integer.toHexString(ch));
}
}
return unicodeTextArrayString.toString();
}
4) If you want to use array based approach, then add each chars to arrays, and then iterate again through array where u stored chars, and then build a string (instead of getting a string from last index) and then return the string
this one is the culprit
String unicode = unicodeTextArrayString[text.length()];
edit:
If you really want to make the original code to work in some way, I think there are several ways to do it. The following code is one of them.
public String toUnicode() {
char unicodeTextArray[] = new char[text.length()];
if (text == null) {
return "";
}
String unicodeTextArrayString[] = new String[text.length()];
StringBuilder unicode= new StringBuilder();
for (int i = 0; i < text.length(); i++) {
unicodeTextArray[i] = text.charAt(i);
if (unicodeTextArray[i] < 0x10) {
unicodeTextArrayString[i] = "\\u000" + Integer.toHexString(unicodeTextArray[i]);
} else if (unicodeTextArray[i] < 0x100) {
unicodeTextArrayString[i] = "\\u00" + Integer.toHexString(unicodeTextArray[i]);
} else if (unicodeTextArray[i] < 0x1000) {
unicodeTextArrayString[i] = "\\u0" + Integer.toHexString(unicodeTextArray[i]);
} else
unicodeTextArrayString[i] = "\\u" + Integer.toHexString(unicodeTextArray[i]);
unicode = unicode.append(unicodeTextArrayString[i]);
}
return unicode.toString();
}
Related
This is what I have so far and I don't know where to go from here.
(I am a beginner so please try to use simple logic for me to understand)
public static void countSentences(String text) {
String comma = ",";
String period = ".";
String Question = "?";
String ex = "!";
text = "..,,??!!";
int c = 0;
for (int i = 0; i < text.length(); i++) {
if (comma.equals(text.charAt(i)) || period.equals(text.charAt(i)) ||
Question.equals(text.charAt(i)) || ex.equals(text.charAt(i))) {
c += 1;
}else {
c += 0;
i++;
}
}
}
You have some redundant lines of code here. Removing the else block entirely should do the trick:
public static void countSentences(String text) {
char comma = ',';
char period = '.';
char Question = '?';
char ex = '!';
text = "..,,??!!";
int c = 0;
for (int i = 0; i < text.length(); i++) {
if (comma == text.charAt(i) || period == text.charAt(i) ||
Question == text.charAt(i) || ex == text.charAt(i)) {
c += 1;
}
}
}
You can use streams as well
public static void countSentences(String text) {
char comma = ',';
char period = '.';
char Question = '?';
char ex = '!';
String text = "..,,??!!";
long count = text.chars().filter(ch -> ch == comma ||ch == Question ||ch == period ).count();
}
This is something of a spoiler, but you could use a replacement approach:
public static int countSentences(String text) {
return text.length() - text.replaceAll("[.?!]", "").length();
}
This just compares the length of the original text against the length of the text with all ., ?, and ! removed.
How to count the characters only if they are right next to each other, otherwise just print the characters as they are. I wrote the following code based on my little knowledge of Java.
for example String w="kjiikkkjial";
the result should be: kji2k3jial
String am ="asbbaamkkkjkssg";
char op = 0;
char[] ch = am.toCharArray();
for(int i=0; i<ch.length; i++) {
int k=1;
for(int j=i+1; j<ch.length; j++) {
if(ch[i]==ch[j]) {
k++;
op=ch[j];
i=j;
}
else break;
}
if(k>1)
System.out.print(op+""+k);
else
System.out.print(ch[i]);
}
This should work, call this function with the input as your string and it will return the expected output.
public static String runLengthEncoding(String text) {
String encodedString = "";
for (int i = 0, count = 1; i < text.length(); i++) {
if (i + 1 < text.length() && text.charAt(i) == text.charAt(i + 1))
count++;
else {
encodedString = encodedString.concat(Character.toString(text.charAt(i)));
if(count>1) {
encodedString = encodedString.concat(Integer.toString(count));
}
count = 1;
}
}
return encodedString;
}
This is a link to the working example on ideone.
I am trying to make a method that returns a version of the original string as follows: each digit 0-9 that appears in the original string is replaced by that many occurrences of the character to the right of the digit. So the string "a3tx2z" yields "attttxzzz", and "12x" yields "2xxx". A digit not followed by a character (i.e. at the end of the string) is replaced by nothing.
I've written the code but it only works for just the first digit and remains unchanged for the next ones.
public String blowUp( String str ){
StringBuffer buffer = null;
String toAdd = null;
String toReturnString = null;
if( str.length() == 0 ){
return "no string found";
}else{
for( int count = 0; count < str.length(); count++ ){
char c = str.charAt( count );
if( count == str.length() - 1 ){
if( Character.isDigit( c ) ){
return str.substring( 0, count );
}else{
return str;
}
}else if( Character.isDigit( c ) ){
char next = str.charAt( count + 1 );
buffer = new StringBuffer();
int nooftimes = Integer.parseInt(Character.toString( c ));
for( int j = 0; j < nooftimes; j++ ){
buffer.append( next );
}
toAdd = buffer.toString();
toReturnString = str.substring( 0, count ) + toAdd + str.substring( count + 1 );
return toReturnString;
}
}
return toReturnString;
}
// return toReturnString;
}
See the comments.
public String blowUp(String str) {
StringBuffer buffer = new StringBuffer();
// String toAdd = null;
// String toReturnString = null;
if (str.length() == 0) {
return "no string found";
} else {
for (int count = 0; count < str.length(); count++) {
char c = str.charAt(count);
/*
* if (count == str.length() - 1) {
*
* if (Character.isDigit(c)) {
*
* return str.substring(0, count); } else {
*
* return str; } } else
*/
if (Character.isDigit(c) && count < str.length()-1) {
char next = str.charAt(count + 1);
if (!Character.isDigit(next)) { // append only if next
// character isn't digit
// buffer = new StringBuffer();
int nooftimes = Integer.parseInt(Character.toString(c));
for (int j = 0; j < nooftimes; j++) {
buffer.append(next);
}
} else {
buffer.append(str.charAt(count+1)); // append digit followed by another digit with next digit
}
// toAdd = buffer.toString();
// toReturnString = str.substring(0, count) + toAdd
// + str.substring(count + 1);
} else {
buffer.append(c); // simply append if not digit
}
}
return buffer.toString();
}
// return toReturnString;
}
It looks like you're making this more complicated than it has to be, and in the process getting the logic a bit confused.
In pseudocode, this problem basically boils down to the following:
for every character 'c' in the input, starting from the first:
if c is not a digit:
add c to the output
otherwise (i.e. if c is a digit), if c is not the last character in the input:
let 'x' be the number represented by c
let 'n' be the next character in the input after c
add x copies of n to the output
return the output
I'll leave translating that into Java to you*.
* EDIT: or to #TheKojuEffect!
There are no less than 5 return points in your code, this is really, really bad. It makes it impossible to accurately determine what is going on in your code.
I'm old school, so I believe in one entry point and one exit point for any method, it makes it SO much easier to figure out what's going on...
Let's start with...
if( str.length() == 0 ){
return "no string found";
This should actually be returning the original String unchanged...don't you think...
if( count == str.length() - 1 ){
if( Character.isDigit( c ) ){
return str.substring( 0, count );
}else{
return str;
}
I can't even figure out why you would need this. The last character is no more special than the first, apart from the fact that if it's a digit, you should ignore it...
char next = str.charAt( count + 1 );
buffer = new StringBuffer();
int nooftimes = Integer.parseInt(Character.toString( c ));
for( int j = 0; j < nooftimes; j++ ){
buffer.append( next );
}
toAdd = buffer.toString();
toReturnString = str.substring( 0, count ) + toAdd + str.substring( count + 1 );
return toReturnString;
Then your return here! But you've only entered this section of code once! What about the rest of the String?
You also seem to be ignoring all the other characters in the String from what I can tell...
A simpler idea would be to use the StringBuffer (or StringBuilder as I prefer) and keep appending the resulting values to it, for example...
public static String blowUp(String str) {
StringBuilder sb = new StringBuilder(128);
for (int count = 0; count < str.length(); count++) {
char c = str.charAt(count);
if (Character.isDigit(c) && count < str.length() - 1) {
char next = str.charAt(count + 1);
int nooftimes = Integer.parseInt(Character.toString(c));
for (int j = 0; j < nooftimes; j++) {
sb.append(next);
}
count++;
} else if (!Character.isDigit(c)) {
sb.append(c);
}
}
return sb.toString();
}
Example input output
If I input...
a3tx2z
12x
a3tx2z1
12x1
I get
atttxzz
2x
atttxzz
2x
as output
#MadProgrammer I modified a little bit based on your code.
public String blowup(String str) {
StringBuilder sb = new StringBuilder();
for(int i =0; i < str.length(); i++) {
char c = str.charAt(i);
if(Character.isDigit(c) && i < str.length()-1) {
char next = str.charAt(i+1);
if(!Character.isDigit(next)) {
int repTimes = Integer.parseInt(Character.toString(c));
for(int k = 0; k < repTimes; k++) {
sb.append(next);
}
}
else {
sb.append(c);
}
}
else {
sb.append(c);
}
}
return new String(sb);
}
I am attempting to solve a codingbat problem called mirrorEnds. My solution fails but I'm not getting any useful feedback from the site, only a failed test run:
And my code (I changed string to str cause I'm used to the problems with "str"):
public String mirrorEnds(String string) {
String str = string;
StringBuilder sb = new StringBuilder();
int beg = 0;
int end = str.length()-1;
while(beg < end)
{
if(str.charAt(beg)==str.charAt(end))
sb.append(str.substring(beg,beg+1));
else
break;
++beg;
--end;
}
if(beg==end)
return str;
else
return sb.toString();
}
Here's mine, for what it's worth (not much, I know, but I was writing it while you were finding the bug..)
private String mirrorEnds(String string) {
final char[] chars = string.toCharArray();
final int n = chars.length;
StringBuilder sb = new StringBuilder();
for (int i = 0; i < n; i++) {
if (chars[i] != chars[n - i - 1])
break;
sb.append(chars[i]);
}
return sb.toString();
}
Bah. I found it. Instance is "abba"
Needed to change "if(beg==end)" to "if(beg>=end)".
public String mirrorEnds(String string) {
String s = "";
String str = "";
for (int i=string.length()-1; i>=0; i--)
{
s = s + string.charAt(i);
}
for (int j=0; j<string.length(); j++)
{
if (s.charAt(j) == string.charAt(j))
{
str = str + string.charAt(j);
}
if (s.charAt(j) != string.charAt(j))
{
break;
}
}
return str;
}
public static String mirrorEnds(String string) {
for (int i = 0; i < string.length(); i++) {
if(string.charAt(i) != string.charAt(string.length()-i-1)){
return string.substring(0,i);
}
else if(i==string.length()-1) return string;
}
return "";
}
Making a helper method is both efficient and makes the job easier, and logic clearer, recommended strategy for beginners, dissect the logic out, then put it together, as seen in codingBat's fizzBuzz questions that build up to the real fizzBuzz. Even though there a shorter solutions, this shows the full extent of logic used.
public String mirrorEnds(String string) {
String reversed = reverseString(string); //the reversed version
String result = "";
for(int a = 0; a < string.length(); a++){
if(string.charAt(a) == reversed.charAt(a)){ //keep going...
result += string.charAt(a);
}
else if(string.charAt(a) != reversed.charAt(a)){
break; //error, stop
}
}
return result;
}
public String reverseString(String s){
String reversed = "";
for(int a = s.length() - 1; a >= 0; a--){
reversed += s.charAt(a);
}
return reversed;
}
Here is mine:
public String mirrorEnds(String str) {
String res = "";
int count = str.length() - 1;
for(int i = 0;i < str.length();i++)
{
if(str.charAt(i) == str.charAt(count))
res += str.substring(i, i + 1);
else
break;
count--;
}
return res;
}
Here's my solution, hope it can help you
public String mirrorEnds(String string) {
int mid = string.length() / 2;
String s = "";
for (int i = 0, j = string.length()-1; i <= mid; i++, j--) {
if (i == mid) {
return string;
}
if (string.charAt(i) == string.charAt(j)) {
s += string.charAt(i) + "";
} else {
break;
}
}
return s;
}
Here's mine. I did mine a little bit different.
public String mirrorEnds(String string) {
//Create a string that we will eventually return.
String ret = "";
//Create a for loop that takes in chars from both ends.
for (int i = 0; i < string.length(); i++)
{
//Create one and two characters in order to simplify it.
char one = string.charAt(i);
char two = string.charAt(string.length() - 1 - i);
//If the front and back character in the iteration
//equal each other, then we add the character to the return string.
if (one == two)
{
ret = ret + one;
}
//Otherwise, we end the loop because we don't want to
//Have a loopback problem.
else
{
break;
}
}
//Return the string that we are working on.
return ret;
}
J2ME String Tokenizer:
public String[] split(String toSplit, char delim, boolean ignoreEmpty) {
StringBuffer buffer = new StringBuffer();
Stack stringStack = new Stack();
for (int i = 0; i < toSplit.length(); i++) {
if (toSplit.charAt(i) != delim) {
buffer.append((char) toSplit.charAt(i));
} else {
if (buffer.toString().trim().length() == 0 && ignoreEmpty) {
} else {
stringStack.addElement(buffer.toString());
}
buffer = new StringBuffer();
}
}
if (buffer.length() != 0) {
stringStack.addElement(buffer.toString());
}
String[] split = new String[stringStack.size()];
for (int i = 0; i < split.length; i++) {
split[split.length - 1 - i] = (String) stringStack.pop();
}
stringStack = null;
buffer = null;
return split;
}
Method Used To Call It:
String toSplit = myThreadObject.GetInfo();
String del = DelimiterValue.getString();
char delimiter = del.charAt(0);
String[] result = split(toSplit, delimiter, false);
if (result != null) {
for (int i = 0; i < result.length; i++) {
System.out.println("The elements are: " + result[i]);
}
} else {
System.out.println("The result is empty");
}
This is an example of how to split up a string in J2ME, it is actually splitting up html content from a website pulled in a thread.
Can anyone tell me how I add a simple counter into this code to count the number of times the result is printed out, i.e. how many tokens there are? Because i am struggling.
Many thanks
No need to add a counter as the array has the public .length property which exposes the count for you. I added one line to your code (and a comment immediately before it). I also removed your check for result != null because your split() method will never return null. It returns a zero length array if there are no matches.
String toSplit = myThreadObject.GetInfo();
String del = DelimiterValue.getString();
char delimiter = del.charAt(0);
String[] result = split(toSplit, delimiter, false);
// add the line below:
System.out.println("There are " + result.length + " results");
for (int i = 0; i < result.length; i++) {
System.out.println("The elements are: " + result[i]);
}