Getting out of bounds error - java

so I'm testing out this piece of code, and when I read a file, the output when being printed halts and I get java.lang.ArrayIndexOutOfBoundsException: -1
at WordLengths.countWordLengthsWithIsLettermethod(WordLengths.java:126)
at WordLengths.testWordLengths(WordLengths.java:152).
I'm wondering if somewhere I inadvertently added a limit to how many results I get, otherwise I can't think of what could be wrong.
This is the bit that's causing trouble (max = freqs[i];):
public int maxIndex(int[] freqs) {
int max = freqs[0];
for (int i = 1; i < freqs.length; i++) {
if (freqs[i] > max) {
max = freqs[i];
}
}
System.out.println("max number of words of certain lengths: "+max);
return freqs[max];
//return max;
}
Here's the whole code with the problem area included:
import edu.duke.FileResource;
public class WordLengths {
public void countWordLengths(FileResource resource, int[] counts) {
String abc = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
for (String word : resource.words()) {
String trim = word.trim();
int wordSize = trim.length();
//System.out.println("word" + "\t" + trim);
int lastInd = trim.length()-1;
//System.out.println("lastIndexOf word" + "\t" + lastInd);
//abc.contains(trim.charAt(lastInd));
char firstChar = trim.charAt(0);
char endChar = trim.charAt(trim.length()-1);
//System.out.println("firstChar" + "\t" + firstChar + "\t" + "endChar" + "\t" + endChar);
int idx = abc.indexOf(firstChar);
int idx_e = abc.indexOf(endChar);
int edx_sum = idx + idx_e;
//System.out.println("indexes abc" + "\t" + edx_sum);
//int idx_s = small.indexOf(firstChar);
//int idx_s_e = small.indexOf(endChar);
//int edx_s_sum = idx_s + idx_s_e;
//System.out.println("indexes small" + "\t" + edx_s_sum);
//System.out.println("indexes" + "\t" + idx + "\t" + idx_e + "\t" + idx_s + "\t" + idx_s_e);
//System.out.println("indexes" + "\t" + idx + "\t" + idx_e + "\t");
if (idx == -1 && idx_e == -1) {
wordSize -= 2;
} else
if (idx == -1 || idx_e == -1) {
wordSize -= 1;
}
if(wordSize>=counts.length) {
counts[counts.length-1] += 1;
} else
//right algorithm
if( counts[wordSize] != 0) {
counts[wordSize] += 1;
} else {
counts[wordSize] = 1;
}
}
//test
/*for(int i : counts) {
System.out.println(i);
}*/
}
/**
* the method countWordLengths(FileResource resource, int[] counts) with isLetter method
*
* #param resource
* #param counts
*/
public void countWordLengthsWithIsLettermethod(FileResource resource, int[] counts) {
for (String word : resource.words()) {
String trim = word.trim();
int wordSize = trim.length();
char firstChar = trim.charAt(0);
char endChar = trim.charAt(trim.length()-1);
if (!Character.isLetter(firstChar) && !Character.isLetter(endChar)) {
wordSize -= 2;
} else
if (!Character.isLetter(firstChar) || !Character.isLetter(endChar)) {
wordSize -= 1;
}
if(wordSize>=counts.length) {
counts[counts.length-1] += 1;
} else
//right algorithm
if( wordSize> 0 && counts[wordSize] != 0 ) {
counts[wordSize] += 1;
} else if ( wordSize> 0) {
counts[wordSize] = 1;
}
System.out.println(counts[wordSize] + " words with length " + wordSize + ": " + word);
}
//test
/*for(int i : counts) {
System.out.println(i);
}*/
}
public int maxIndex(int[] freqs) {
int max = freqs[0];
for (int i = 1; i < freqs.length; i++) {
if (freqs[i] > max) {
max = freqs[i];
}
}
System.out.println("max number of words of certain lengths: "+max);
return freqs[max];
//return max;
}
public void testWordLengths() {
WordLengths wl = new WordLengths();
FileResource fr = new FileResource();
int counts[] = new int[100];
//wl.countWordLengths(fr, counts);
wl.countWordLengthsWithIsLettermethod(fr, counts);
wl.maxIndex(counts);
}
}

What do think would happen if the word was empty (or just filled with blanks)
String trim = word.trim();
int wordSize = trim.length();
char firstChar = trim.charAt(0);
char endChar = trim.charAt(trim.length()-1);

Related

Return a two array confusion matrix

I'm trying to create a confusion matrix however I'm not sure how to properly return my method where I can index both predicted and actual values, here's what I have tried thus far:
int[][] matrixConfusion(int[] predicted, int[] actual){
int[] count = new int [10];
int counts = 0;
int counts1 = 0;
int counts2 = 0;
int counts3 = 0;
for(int i = 0; i < count.length; i++) {
if(actual[i] == count[i] && predicted[i] == count[i]) {
counts++;
}else if(actual[i] != count[i] && predicted[i] != count[i]) {
counts1++;
}else if(actual[i] != count[i] && predicted[i] == count[i]) {
counts2++;
}else if(actual[i] == count[i] && predicted[i] != count[i]) {
counts3++;
}
}
System.out.println("\t"+ "Actual = 0:"+"\t"+"Actual = 1:"+"\n" + "Predic = 0:" + "\t" + counts + "\t" + counts2 + "\n" + "Predic = 1:" + "\t" + counts3 + "\t" + counts1);
return null;
}
The code works by printing out the statements above however, I cannot find a way to properly return the values from print,so that I can return the values rather than print them.

How to insert a "," in between each char of a string

Im at a point in my program where I need to set marks in a string before I pass it through another method, I have it so that every 4th char will have a "|" inserted, this is to mark a row break. Not I want to take each char in between the outter marks "|" and put a ",". that two char array method wont work here otherwise I would have tryed to use that but I'm not looking for a char array.
public static String matrixFormatter(String x){
x = x.substring(0, 4) + "|" + x.substring(4, x.length());
return x;
}
this works so far, now I want to add a "," between each char, I thought the code below would work and this would be easy but I was wrong.
public static String matrixFormatter(String x){
for(int i = 0; i<=x.length(); i+=4){
for(int j = 0; j<=x.length(); i++){
x = x.substring(0, i) + "|" + x.substring(i, x.length());
x = x.substring(0, j) + "|" + x.substring(j, x.length());
}
}
return x;
}
The code below adds a "," between characters in the string.
public static String matrixFormatter(String x){
String result;
for(int i = 0; i<x.length()-1; i++){
result += x.substring(i, i+1) + ",";
}
return result+",";
}
try this regex
s = s.replaceAll("(?<=.)(?=.)", ",");
It can be done with StringBuffer and also with Joiner of Guava library:
public static void main(String[] args) {
String s = "example";
System.out.println(withBuilder(s));
System.out.println(withJoiner(s));
}
private static String withJoiner(String s) {
return Joiner.on(",").join(Chars.asList(s.toCharArray()));
}
private static String withBuilder(String s)
{
StringBuilder builder = new StringBuilder(s);
int index = 1;
for (int i = 0; i < s.length() ; i++)
{
builder.insert(index, ",");
index +=2;
}
return builder.toString();
}
Output is:
e,x,a,m,p,l,e,
e,x,a,m,p,l,e
It can be done in one method:
public static String matrixFormatter(String x) {
List<String> chars = Arrays.asList(x.split(""));
String result = chars.get(0);
for (int i = 1; i < chars.size(); i++) {
if (i % 4 == 0)
result += "|" + chars.get(i);
else
result += "," + chars.get(i);
}
return result;
}
calling with:
System.out.println(matrixFormatter("12345678"));
outputs:
1,2,3,4|5,6,7,8
public static String matrixFormatter(String x) {
resultstr = "";
int i = 0;
while(i < x.length()) {
// If end of string: only add character.
if (i == x.length() - 1) {
resultstr += x.substring(i, i + 1);
} else {
if ( ((i + 1) % 4) == 0) {
resultstr += x.substring(i, i + 1) + "|";
} else {
resultstr += x.substring(i, i + 1) + ",";
}
}
i++;
}
return resultstr;
}
Haven't got Java installed but tested the concept via PHP-code:
function matrixFormatter($x) {
$resultstr = "";
$i = 0;
while($i < strlen($x)) {
if ($i == strlen($x) - 1) {
$resultstr .= $x[$i];
} else {
if ( (($i + 1) % 4) == 0) {
$resultstr .= $x[$i] . "|";
} else {
$resultstr .= $x[$i] . ",";
}
}
$i++;
}
return $resultstr;
}
matrixFormatter("abcdefghijklmnopq") returns "a,b,c,d|e,f,g,h|i,j,k,l|m,n,o,p|q".
I'm not sure I understand you question correctly, you should probably add some input and expected output to be more clearer.
String a = "abcdefghijklmnop";
String a2 = "";
for (int i = 0; i < a.length(); i++) {
if (i != 0) {
if(i % 4 == 0){
a2 += "|";
} else{
a2 += ",";
}
}
a2 += a.charAt(i);
}
System.out.println(a2);
This will produce the output a,b,c,d|e,f,g,h|i,j,k,l|m,n,o,p

Printing a polynomial

I am trying to print a polynomial from a given number.
I did the example below, but for something like 100 it will print 1x^2+, when I want just x^2. What I'm looking for is how can I make it to not print + and at the same time get rid of coefficients that are 1.
Edit: I did it, it prints perfectly. Feel free to use it.
private static String S_frumos(int poli) {
String s = "";
for (int i = 0; i < String.valueOf(poli).length(); i++) {
int nr = Character.getNumericValue(S_GetCoefs(poli, i));
if (nr != 0) {
if (i == String.valueOf(poli).length() - 1) {
s = s + nr;
} else if (i == String.valueOf(poli).length() - 2) {
if ((S_zero(poli, i + 1) == 1)) {
if (nr != 1) {
s = s + nr + "x";
} else {
s = s + "x";
}
} else {
if (nr != 1) {
s = s + nr + "x" + "+";
} else {
s = s + "x" + "+";
}
}
} else if ((S_zero(poli, i + 1) == 1)) {
if (nr != 1) { s = s + nr + "x^" + (String.valueOf(poli).length() - i - 1);}
else { s = s + "x^" + (String.valueOf(poli).length() - i - 1);}
} else {
if (nr != 1){ s = s + nr + "x^" + (String.valueOf(poli).length() - i - 1) + "+";}
else { s = s + "x^" + (String.valueOf(poli).length() - i - 1) + "+";}
}
}
}
return s;
}
private static int S_GetCoefs(int poli, int x) {
return String.valueOf(java.lang.Math.abs(poli)).charAt(x);
}
To store something of an unknown length... then you can still use an int/double array, just gets slightly more complicated.
public static void main(String[] args)
{
// Say the size is given in a command line argument.
int coefficientNumber = Integer.parseInt(args[0]);
int[] poly = new int[coefficientNumber];
for (int i = 0; i < poly.length; i++)
{
poly[i] = 0;
}
// Set the highest coeffient to 1 (if there is 3 coefficients, this is coefficient
// of x^2, if 4 coefficients, this is coefficient of x^3
poly[0] = 1;
printPoly(poly);
}
// To print a polynomial of unknown length.
// If the coefficient is 0, don't print it.
private static void printPoly(int[] poly)
{
String output = "";
for (int index = 0; index < poly.length; index++)
{
if (poly[index] != 0)
{
// If this is the first coefficient with a value
if (output.length() == 0)
output = poly[index] + "x^" + (poly.length - (index + 1));
// Else if there is already some coefficient with values printed.
else
output += " + " + "x^" + (poly.length - (index + 1));
} // if
} // for
System.out.println(output);
} // printPoly
First of all, storing a polynomial in one variable isn't a great idea as if you have coefficients of more than 9 you'll get confused.
A better method imo (without making a polynomial class) is to store the polynomial in an int/double array.
public static void main(String[] args)
{
// To store the polynomial x^2, you could do the following:
int[] poly = new int[3];
poly[0] = 1;
poly[1] = 0;
poly[2] = 0;
printPoly(poly);
}
// To print it:
private static void printPoly(int[] poly)
{
String output = "";
if (poly[0] != 0)
output += poly[0] + "x^2"
if (poly[1] != 0)
{
if (output.size() > 0)
output += " + " + poly[1] + "^x";
else
output += poly[1] + "x";
}
if (poly[2] != 0)
{
if (output.size() > 0)
output += " + " + poly[2];
else
output += poly[2];
}
}

puzzling recursion with java

Given a string and a non-empty substring sub, compute recursively the largest substring which starts and ends with sub and return its length.
strDist("catcowcat", "cat") → 9
strDist("catcowcat", "cow") → 3
strDist("cccatcowcatxx", "cat") → 9
my solution
public int strDist(String str, String sub) {
int i = sub.length();
int j = str.length();
int count = 0;
if (str.length() == 1 && str.equals(sub)) {
return 1;
} else if (str.length() < sub.length() || str.length() <= 1) {
return 0;
}
if (str.substring(0, i).equals(sub)) {
if (str.substring(str.length() - i, str.length()).equals(sub)) {
return str.length();
} else {
strDist(str.substring(0, str.length() - i), sub);
}
} else {
strDist(str.substring(1, str.length()), sub);
}
return 0;
}
tell me how to correct my code?
Why does this need to be done with recursion?
Edit: fixed code to handle case where sub is not present in str, or only present once.
public int strDist(String str, String sub) {
int last=str.lastIndexOf(sub);
if (last != -1) {
int first=str.indexOf(sub);
if (first != last)
return last - first + sub.length();
}
}
return 0;
}
Recursion is great, if it is suited to the problem. In this case, recursion doesn't add value, and writing it with recursion for the sake of recursion makes the code inefficient.
This will , "compute recursively the largest substring which starts and ends with sub and return its length" as you described.
public class PuzzlingRecursion {
static String substringFound = "";
public static void main(String[] args) {
String sentence = "catcowcat";
String substring = "cat";
int sizeString = findNumberOfStrings(sentence, substring, 0);
System.out.println("you are searching for: " + substring);
System.out.println("in: " + sentence);
System.out.println("substring which starts and ends with sub and return its length is:"+substringFound + ", " + sizeString);
}
private static int findNumberOfStrings(String subStringPassed,
String setenecePassed, int count) {
if (subStringPassed.length() == 0) {
return count + 0;
}
if (subStringPassed.length() < setenecePassed.length()) {
return count + 0;
}
count++;
String lastStringMiddle = subStringPassed.replaceAll("(.*?)" + "("
+ setenecePassed + ")" + "(.*?)" + "(" + setenecePassed + ")"
+ "(.*?.*)", "$3");
if (subStringPassed.contains(setenecePassed)
&& lastStringMiddle.length() != setenecePassed.length()) {
if (subStringPassed.contains(setenecePassed)
&& lastStringMiddle.contains(setenecePassed)) {
// only found one item no pattern but according to the example
// you posted it should return the length of one word/substring
count = setenecePassed.length();
substringFound = subStringPassed;
return count;
}
}
// makesure the lastSrtringMiddle has the key we are search
if (!lastStringMiddle.equals(subStringPassed)) {
subStringPassed = subStringPassed.replaceFirst(setenecePassed, "");
String lastString = subStringPassed.substring(0,
subStringPassed.lastIndexOf(setenecePassed));
if (null != lastString && !"".equals(lastString)) {
count = lastStringMiddle.length() + setenecePassed.length()
+ setenecePassed.length();
substringFound = setenecePassed + lastStringMiddle
+ setenecePassed;
subStringPassed = "";
}
return findNumberOfStrings(subStringPassed, setenecePassed, count);
}
return count;
}
}
I think this is much nicer recursive solution:
public int strDist(String str, String sub) {
if (str.length()==0) return 0;
if (!str.startsWith(sub))
return strDist(str.substring(1),sub);
if (!str.endsWith(sub))
return strDist(str.substring(0,str.length()-1),sub);
return str.length();
}

Count continuous repeated occurrence of characters from String

This is my code.
public static void countContinuosOccurence() {
String first = "ABBCDDDEFGGH";
StringBuffer result = new StringBuffer();
int count = 1;
for (int i = 1; i < first.length(); i++) {
if (first.charAt(i) == (first.charAt(i - 1))) {
count++;
} else {
if (count > 1) {
result.append(String.valueOf(count) + first.charAt(i - 1));
} else {
result.append(first.charAt(i - 1));
}
count = 1;
}
}
System.out.println("First String is:"+ first);
System.out.println("Result is:" + result);
}
The result is:
First String is:ABBCDDDEFGGH
Result is:A2BC3DEF2G
It is missing the last character? May someone help me to solve this?
Not top-performing, but simplest code:
final String in = "ABBCDDDEFGGH" + '\u0000';
final StringBuilder b = new StringBuilder();
char prev = in.charAt(0);
int rpt = 0;
for (int i = 1; i < in.length(); i++) {
final char curr = in.charAt(i);
if (curr == prev) rpt++;
else {
b.append(rpt == 0? prev : "" + (rpt + 1) + prev);
rpt = 0; prev = curr;
}
}
System.out.println(b);
After the for loop ends, you'll need to append the count and the character of the last run of character(s) to the result:
public static void countContinuosOccurence() {
String first = "ABBCDDDEFGGH";
StringBuffer result = new StringBuffer();
int count = 1;
int i;
for (i = 1; i < first.length(); i++) {
if (first.charAt(i) == (first.charAt(i - 1))) {
count++;
} else {
if (count > 1) {
result.append(String.valueOf(count) + first.charAt(i - 1));
} else {
result.append(first.charAt(i - 1));
}
count = 1;
}
}
// ADD THIS - to take care of the last run.
if (count > 1) {
result.append(String.valueOf(count) + first.charAt(i - 1));
} else {
result.append(first.charAt(i - 1));
}
System.out.println("First String is:"+ first);
System.out.println("Result is:" + result);
}
public static void countContinuosOccurence() {
String[] input = "ABBCDDDEFGGH".split("");
String out = "";
for (int i = 0; i < input.length; i++) {
int repeatedCharCount = 1;
String currentChr = input[i];
if (!(i == input.length - 1)) {
while (input[i].equals(input[i + 1])) {
repeatedCharCount++;
i++;
}
}
out = out + repeatedCharCount + currentChr;
}
System.out.println(out);
}
There is also a hidden problem, that is that if you are terminating with a sequence with more than one occurrence, you will not write anything.
The simplest way to solve this problem and the problem you detected is to add a final check after the for block
[...]
}
int l = first.length();
if (count > 1) {
result.append(String.valueOf(count) + first.charAt(l - 1));
} else {
result.append(first.charAt(l - 1));
}
}
System.out.println("First String is:"+ first);
System.out.println("Result is:" + result);
}
import java.util.*;
public class HelloWorld{
public static void main(String []args){
System.out.println("Hello World");
String first = "ABBCDDDEFGGHhhhhh456456456{{{67}}}";
StringBuffer result = new StringBuffer();
result.append(first);
System.out.println(result);
Map<Character,Integer> map = new HashMap<Character,Integer>();
for(int i = 0; i < first.length(); i++) {
char c = first.charAt(i);
if (map.containsKey(c)) {
int cnt = map.get(c);
map.put(c, ++cnt);
} else {
map.put(c, 1);
}
}
Set set = map.entrySet();
// Get an iterator
Iterator itr = set.iterator();
// Display elements
while(itr.hasNext()) {
Map.Entry me = (Map.Entry)itr.next();
System.out.print(me.getKey() + ": ");
System.out.println(me.getValue());
}
System.out.println("Hello World1");
}
}

Categories

Resources