I have the following code, but keep getting an error but the file builds ok, Im fairly new at all this.
Like I said the file builds ok, it accepts the inputs 1 & 2 and gives the options but keeps giving me an exception. It will ask for the keyword, and the plaintext but when it goes to decrypt or encrpt the error below appears.
Sorry about my first attempt at a queston.. Hopefully this is a bit better...
Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 3 at
java.lang.String.charAt(String.java:695) at
playfair.format(playfair.java:123) at
playfair.Divid2Pairs(playfair.java:135) at
playfair.Encript(playfair.java:187) at
playfair.main(playfair.java:332)
import java.util.Scanner;
public class playfair {
private String KeyWord=new String();
private String Key=new String();
private char matrix_arr[][]= new char[5][5];
public void setKey(String k){
// This function will take the input key from the user
// Then it'll remove duplication of letters from the key
// Will add it to the private KeyWord for matrix generation
String K_adjust=new String();
boolean flag = false;
K_adjust = K_adjust + k.charAt(0);
for(int i=1; i<k.length();i++){
for(int j=0;j<K_adjust.length(); j++){
if(k.charAt(i)==K_adjust.charAt(j))
{
flag = true;
}
}
if(flag == false){
K_adjust = K_adjust + k.charAt(i);
}
flag = false;
}
KeyWord=K_adjust;
}
public void KeyGen()
{
// This function adjust the alphabetical letters adding the
// KeyWord on the beginning of them & then it calls the matrix function
boolean flag=true;
char current;
Key=KeyWord;
for ( int i=0 ; i<26 ; i++){
current=(char)(i+97);
if(current=='j')
continue;
for(int j=0 ; j< KeyWord.length() ; j++ ){
if (current == KeyWord.charAt(j)){
flag=false;
break;
}
}
if(flag)
Key=Key+current;
flag=true;
}
System.out.println(Key);
matrix ();
}
private void matrix ()
{
int counter=0;
for (int i=0 ; i<5 ;i++){
for (int j=0 ; j<5 ; j++){
matrix_arr[i][j]=Key.charAt(counter);
System.out.printf("%s ",matrix_arr[i][j]);
counter++;
}
System.out.println("\n");
}
}
private String format(String old_text)
{
// This function is to adjust the Text to encrypt
// It changes all the 'j' letters to 'i' & add 'x' character
// between repeatable pairs.
int i = 0;
int j = 0;
int len = 0;
String text = new String();
len = old_text.length();
//System.out.println(old_text);
/*** Change all j's into i's *****/
for (int tmp = 0; tmp < len; tmp++)
{
if (old_text.charAt(tmp) == 'j')
{
text = text + 'i';
}
else
text = text+old_text.charAt(tmp);
}
/**********************************/
len = text.length();
/*** Assign 'x' to letters that repeat in a diagram ***/
for (i = 0; i < len; i = i + 2){ //run for half of string length
if (text.charAt(i+1) == text.charAt(i)){ //if char = previous char
text = text.substring(0, i+1) + 'x' + text.substring(i+1);
}else{ //not a repeat character, move along
}
}
return text;
}
private String [] Divid2Pairs (String new_string)
{
String Original = format(new_string);
int size= Original.length();
if(size%2!=0){
size++;
Original = Original+'x';
}
String x[]= new String[size/2];
int counter=0;
for ( int i=0 ; i<size/2 ;i++){
x[i]=Original.substring(counter, counter+2);
System.out.println(x[i]);
counter=counter+2;
}
return x;
}
public int[] GetDiminsions(char letter){
int []key=new int[2];
if ( letter == 'j')
letter='i';
for (int i=0 ; i<5 ;i++)
{
for (int j=0 ; j<5 ; j++){
if(matrix_arr[i][j] == letter){
key[0]=i;
key[1]=j;
break;
}
}
}
return key;
}
public String Encript(String Source)
{
System.out.println("Encription Start");
String src_arr[]=Divid2Pairs(Source);
String Code=new String();
char one;
char two;
int part1[]=new int[2];
int part2[]=new int[2];
//start on pair by pair
for (int i=0 ; i< src_arr.length ;i++ ){
one = src_arr[i].charAt(0);//get first char
two = src_arr[i].charAt(1);//get second char
part1 = GetDiminsions(one);//get position of the first char
part2 = GetDiminsions(two);//get position of the second char
//check for special cases
if(part1[0]==part2[0]){//same row
if (part1[1]<4)
part1[1]++;
else
part1[1]=0;
if(part2[1]<4)
part2[1]++;
else
part2[1]=0;
}
else if (part1[1]==part2[1]) //same column
{
if (part1[0]<4)
part1[0]++;
else
part1[0]=0;
if(part2[0]<4)
part2[0]++;
else
part2[0]=0;
}
else
{
int temp=part1[1];
part1[1]=part2[1];
part2[1]=temp;
}
Code= Code + matrix_arr[part1[0]][part1[1]] + matrix_arr[part2[0]][part2[1]];
}
System.out.println(Code);
return Code;
}
public String Decript (String Code){
System.out.println("Decription Start");
String Original=new String();
String src_arr[]=Divid2Pairs(Code);
char one;
char two;
int part1[]=new int[2];
int part2[]=new int[2];
//start on pair by pair
for (int i=0 ; i< src_arr.length ;i++ ){
one = src_arr[i].charAt(0);//get first char
two = src_arr[i].charAt(1);//get second char
part1 = GetDiminsions(one);//get position of the first char
part2 = GetDiminsions(two);//get position of the second char
//check for special cases
if(part1[0]==part2[0]){//same row
if (part1[1]>0)
part1[1]--;
else
part1[1]=4;
if(part2[1]>0)
part2[1]--;
else
part2[1]=4;
}
else if (part1[1]==part2[1]) //same column
{
if (part1[0]>0)
part1[0]--;
else
part1[0]=4;
if(part2[0]>0)
part2[0]--;
else
part2[0]=4;
}
else
{
int temp=part1[1];
part1[1]=part2[1];
part2[1]=temp;
}
Original =Original + matrix_arr[part1[0]][part1[1]] + matrix_arr[part2[0]][part2[1]];
}
System.out.println(Original);
return Original;
}
/**
* #param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
playfair x=new playfair();
Scanner sc = new Scanner(System.in);
System.out.println("Enter a lower case keyword:");
String keyword = sc.next();
x.setKey(keyword);
x.KeyGen();
System.out.println("To Encrypt enter 1 \nTo Decript enter 2\nTesting both enter anything else:");
int choosen_value = sc.nextInt();
if(choosen_value==1)
{
System.out.println("Enter a lower case word to encrypt:");
String key_input = sc.next();
String Encripted= x.Encript(key_input);
}else if(choosen_value==2){
System.out.println("Enter a lower case word to decrypt:");
String decripted = sc.next();
x.Decript(decripted);
}else{
System.out.println("Enter a lower case word to encrypt & decrypt:");
String key_input = sc.next();
String Encripted= x.Encript(key_input);
x.Decript(Encripted);
}
}
}
Again Many thanks in advance
In the format method, in the below loop
for (i = 0; i < len; i = i + 2)
text.charAt(i+1) is the line causing the problem.
You need to traverse till the len-1 instead of len.
This is because when i is exactly 1 than len, it'd still execute the for loop, but i+1 in the charAt() method will try to fetch the char present at the index len(since i+1 is now equal to len), which throws the StringIndexOutOfBoundsException as the maximum accessible index in a String is str.length()-1.
(i = 0; i < len; i = i + 2) is causing exception
you might need to do i<len-1 here.
Related
I was getting this error while running the following code. I couldn't find out what was wrong with the code.
As far as I can see, there's some issue with my second character array. But couldn't find out what was wrong. First tried running the last loop before temp_count. Then also tried temp_count±1. Yet, I failed. I have also tried taking different array size. still no luck
import java.util.Scanner;
public class oop2
{
public static void main(String[] args)
{
Scanner sc = new Scanner(System.in);
String str = new String();
int temp_count = 0;
//New input of string
str=sc.nextLine();
char[] c = str.toCharArray();
char[] temp = new char[temp_count];
//Converting uppercase to lower case for convenience
for(int i=0; i<str.length(); i++)
{
if (Character.isUpperCase(c[i]))
{
c[i]=(char) (c[i]+32);
}
}
//verifying whether the alphabet exists
for(char x = 'a'; x<='z'; x++)
{
int count=0;
for(int i=0; c[i]!='\0'; i++)
{
if (c[i]==x)
{
count++;
}
}
//if the alphabet is not found, then putting the alphabet in
if (count==0)
{
temp[temp_count]=x;
temp_count++;
}
}
//Verifying whether it's a pangram or not
if (temp_count==0)
{
System.out.println("Pangram");
}
else
{
//if not pangram then this part will execute
System.out.println("Not Pangram");
System.out.printf("Missing Characters: ");
//printing out the missing character
for(int i=0; i<temp_count-1; i++)
{
System.out.print(temp[i]+", ");
}
}
sc.close();
}
}
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String str = new String();
int temp_count = 0;
//New input of string
str = sc.nextLine();
char[] c = str.toCharArray();
char[] temp = new char[0];
//Converting uppercase to lower case for convenience
for (int i = 0; i < str.length(); i++) {
if (Character.isUpperCase(c[i])) {
c[i] = (char)(c[i] + 32);
}
}
//verifying whether the alphabet exists
for (char x = 'a'; x <= 'z'; x++) {
int count = 0;
for (int i = 0; c[i] != '\0'; i++) {
if (c[i] == x) {
count++;
}
}
//if the alphabet is not found, then putting the alphabet in
if (count == 0) {
char [] copy = new char[temp.length+1];
for (int i = 0; i < temp.length; i++) {
copy[i]=temp[i];
}
copy[copy.length-1] = x;
temp=copy;
}
}
//Verifying whether it's a pangram or not
if (temp_count == 0) {
System.out.println("Pangram");
} else {
//if not pangram then this part will execute
System.out.println("Not Pangram");
System.out.printf("Missing Characters: ");
//printing out the missing character
for (int i = 0; i < temp_count - 1; i++) {
System.out.print(temp[i] + ", ");
}
}
sc.close();
}
}
Blockquote
I am working on question 1.5 from the book Cracking The Coding interview. The problem is to take a string "aabcccccaaa" and turn it into a2b1c5a3.
If the compressed string is not smaller than the original string, then return the original string.
My code is below. I used an ArrayList because I would not know how long the compressed string would be.
My output is [a, 2, b, 1, c, 5], aabc, []. When the program gets to the end of string, it doesn't have a character to compare the last character too.
import java.util.*;
import java.io.*;
public class stringCompression {
public static void main(String[] args) {
String a = "aabcccccaaa";
String b = "aabc";
String v = "aaaa";
check(a);
System.out.println("");
check(b);
System.out.println("");
check(v);
}
public static void check(String g){
ArrayList<Character> c = new ArrayList<Character>();
int count = 1;
int i = 0;
int h = g.length();
for(int j = i + 1; j < g.length(); j++)
{
if(g.charAt(i) == g.charAt(j)){
count++;
}
else {
c.add(g.charAt(i));
c.add((char)( '0' + count));
i = j;
count = 1;
}
}
if(c.size() == g.length()){
System.out.print(g);
}
else{
System.out.print(c);
}
}
}
In the last loop you're not adding the result to the array. When j = g.length() still needs to add the current char and count to the array. So you could check the next value of j before increment it:
for(int j = i + 1; j < g.length(); j++)
{
if(g.charAt(i) == g.charAt(j)){
count++;
}
else {
c.add(g.charAt(i));
c.add((char)( '0' + count));
i = j;
count = 1;
}
if((j + 1) = g.length()){
c.add(g.charAt(i));
c.add((char)( '0' + count));
}
}
I would use a StringBuilder rather than an ArrayList to build your compressed String. When you start compressing, the first character should already be added to the result. The count of the character will be added once you've encountered a different character. When you've reached the end of the String you should just be appending the remaining count to the result for the last letter.
public static void main(String[] args) throws Exception {
String[] data = new String[] {
"aabcccccaaa",
"aabc",
"aaaa"
};
for (String d : data) {
System.out.println(compress(d));
}
}
public static String compress(String str) {
StringBuilder compressed = new StringBuilder();
// Add first character to compressed result
char currentChar = str.charAt(0);
compressed.append(currentChar);
// Always have a count of 1
int count = 1;
for (int i = 1; i < str.length(); i++) {
char nextChar = str.charAt(i);
if (currentChar == nextChar) {
count++;
} else {
// Append the count of the current character
compressed.append(count);
// Set the current character and count
currentChar = nextChar;
count = 1;
// Append the new current character
compressed.append(currentChar);
}
}
// Append the count of the last character
compressed.append(count);
// If the compressed string is not smaller than the original string, then return the original string
return (compressed.length() < str.length() ? compressed.toString() : str);
}
Results:
a2b1c5a3
aabc
a4
You have two errors:
one that Typo just mentioned, because your last character was not added;
and another one, if the original string is shorter like "abc" with only three chars: "a1b1c1" has six chars (the task is "If the compressed string is not smaller than the original string, then return the original string.")
You have to change your if statement, ask for >= instead of ==
if(c.size() >= g.length()){
System.out.print(g);
} else {
System.out.print(c);
}
Use StringBuilder and then iterate on the input string.
private static string CompressString(string inputString)
{
var count = 1;
var compressedSb = new StringBuilder();
for (var i = 0; i < inputString.Length; i++)
{
// Check if we are at the end
if(i == inputString.Length - 1)
{
compressedSb.Append(inputString[i] + count.ToString());
break;
}
if (inputString[i] == inputString[i + 1])
count++;
else
{
compressedSb.Append(inputString[i] + count.ToString());
count = 1;
}
}
var compressedString = compressedSb.ToString();
return compressedString.Length > inputString.Length ? inputString : compressedString;
}
I am trying to reverse every 2nd words of every single sentence like
If a given string is :
My name is xyz
The desired output should be :
My eman is zyx
My current output is:
Ym eman s1 zyx
I am not able to achieve my desired output.Don't know what I am doing wrong here
Here is my code
char[] sentence = " Hi my name is person!".toCharArray();
System.out.println(ReverseSentence(sentence));
}
private static char[] ReverseSentence(char[] sentence)
{
//Given: "Hi my name is person!"
//produce: "iH ym eman si !nosrep"
if(sentence == null) return null;
if(sentence.length == 1) return sentence;
int startPosition=0;
int counter = 0;
int sentenceLength = sentence.length-1;
//Solution handles any amount of spaces before, between words etc...
while(counter <= sentenceLength)
{
if(sentence[counter] == ' ' && startPosition != -1 || sentenceLength == counter) //Have passed over a word so upon encountering a space or end of string reverse word
{
//swap from startPos to counter - 1
//set start position to -1 and increment counter
int begin = startPosition;
int end;
if(sentenceLength == counter)
{
end = counter;
}
else
end = counter -1;
char tmp;
//Reverse characters
while(end >= begin){
tmp = sentence[begin];
sentence[begin] = sentence[end];
sentence[end] = tmp;
end--; begin++;
}
startPosition = -1; //flag used to indicate we have no encountered a character of a string
}
else if(sentence[counter] !=' ' && startPosition == -1) //first time you encounter a letter in a word set the start position
{
startPosition = counter;
}
counter++;
}
return sentence;
}
If you want to reverse the alternate word you can try something like splitting the whole String into words delimited by whitespaces and apply StringBuilder reverse() on every second word like :-
String s = "My name is xyz";
String[] wordsArr = s.split(" "); // broke string into array delimited by " " whitespace
StringBuilder sb = new StringBuilder();
for(int i = 0 ; i< wordsArr.length; i++){ // loop over array length
if(i%2 == 0) // if 1st word, 3rd word, 5th word..and so on words
sb.append(wordsArr[i]); // add the word as it is
else sb.append(new StringBuilder(wordsArr[i]).reverse()); // else use StringBuilder revrese() to reverse it
sb.append(" ");// add a whitespace in between words
}
System.out.println(sb.toString().trim()); //remove extra whitespace from the end and convert StringBuilder to String
Output :- My eman is zyx
You can solve your problem vary easy way! Just use a flag variable which will indicate the even or odd position, more precisely whether any word will gonna be reversed or not!
Look at the following modification I made in your code, just added three extra line:
private static boolean flag = true;// added a variable flag to check if we reverse the word or not.
private static char[] ReverseSentence(char[] sentence)
{
//Given: "Hi my name is person!"
//produce: "iH ym eman si !nosrep"
if(sentence == null) return null;
if(sentence.length == 1) return sentence;
int startPosition=0;
int counter = 0;
int sentenceLength = sentence.length-1;
//Solution handles any amount of spaces before, between words etc...
while(counter <= sentenceLength)
{
if(sentence[counter] == ' ' && startPosition != -1 || sentenceLength == counter) //Have passed over a word so upon encountering a space or end of string reverse word
{
flag = !flag; // first time (odd position) we are not going to reverse!
//swap from startPos to counter - 1
//set start position to -1 and increment counter
int begin = startPosition;
int end;
if(sentenceLength == counter)
{
end = counter;
}
else
end = counter -1;
char tmp;
//Reverse characters
while(end >= begin & flag){ //lets see whether we are going to reverse or not
tmp = sentence[begin];
sentence[begin] = sentence[end];
sentence[end] = tmp;
end--; begin++;
}
startPosition = -1; //flag used to indicate we have no encountered a character of a string
}
else if(sentence[counter] !=' ' && startPosition == -1) //first time you encounter a letter in a word set the start position
{
startPosition = counter;
}
counter++;
}
return sentence;
}
Input
My name is xyz
Output:
My eman is zyx
The following code does this "special reverse" which reverses any other word in the sentence:
public static void main(String[] args) {
String sentence = "My name is xyz";
System.out.println(specialReverse(sentence)); // My eman is zyx
}
private static String specialReverse(String sentence) {
String result = "";
String[] words = sentence.split(" ");
// we'll reverse only every second word according to even/odd index
for (int i = 0; i < words.length; i++) {
if (i % 2 == 1) {
result += " " + reverse(words[i]);
} else {
result += " " + words[i];
}
}
return result;
}
// easiest way to reverse a string in Java in a "one-liner"
private static String reverse(String word) {
return new StringBuilder(word).reverse().toString();
}
Just for completeness here's Java-8 solution:
public static String reverseSentence(String input) {
String[] words = input.split(" ");
return IntStream.range(0, words.length)
.mapToObj( i -> i % 2 == 0 ? words[i] :
new StringBuilder(words[i]).reverse().toString())
.collect(Collectors.joining(" "));
}
reverseSentence("My name is xyz"); // -> My eman is zyx
package com.eg.str;
// Without using StringBuilder
// INPUT: "Java is very cool prog lang"
// OUTPUT: Java si very looc prog gnal
public class StrRev {
public void reverse(String str) {
String[] tokens = str.split(" ");
String result = "";
String k = "";
for(int i=0; i<tokens.length; i++) {
if(i%2 == 0)
System.out.print(" " + tokens[i] + " ");
else
result = tokens[i];
for (int j = result.length()-1; j >= 0; j--) {
k = "" + result.charAt(j);
System.out.print(k);
}
result = "";
}
}
public static void main(String[] args) {
StrRev obj = new StrRev();
obj.reverse("Java is very cool prog lang");
}
}
//reverse second word of sentence in java
public class ReverseSecondWord {
public static void main(String[] args) {
String s="hello how are you?";
String str[]=s.split(" ");
String rev="";
for(int i=0;i<str[1].length();i++)
{
char ch=str[1].charAt(i);
rev=ch+rev;
}
str[1]=rev;
for(int i=0;i<str.length;i++)
{
System.out.print(str[i]+" ");
}
}
}
I am trying to solve a HackerRank challenge, but I am running into a problem. Obviously the brute force solution of O(n^2) will not cut if for the performance requirements (I tried), so I began searching for a more elegant solution. That is when I landed on KMP. And following this tutorial I implemented it.
However, the challenge states that you can actually have one mismatch in the strings, so I tried to add that functionality in my code. However, I am getting results that are not correct and I am completely clueless as to why. Could someone please take a look at my solution and point me in the right direction?
import java.io.*;
import java.util.*;
import java.text.*;
import java.math.*;
import java.util.regex.*;
public class Solution {
//This failure function creates an array of integers
//that indicate if there is a prefix that is both a
//prefix and a suffix of the word and at what position
//the prefix ends
private static int[] failureFunction(char[] p){
int i = 0;
int j = -1;
int len = p.length;
int[] f = new int[len+1];
f[i] = j;
int potentialWrong = 0;
while(i<len){
// if(j>=0 && p[i] != p[j]){
// potentialWrong++;
// }
// if(potentialWrong > 1){
// potentialWrong = 0;
while(j>=0 && p[i] != p[j]){
//if there is a mismatch consider the
//next widest border. The borders to be
//examined are obtained in decreasing order
// from the values f[i], f[f[i]] etc.
j=f[j];
}
// }
i++;
j++;
f[i]=j;
}
// for(int k : f){
// System.out.print(k+" ");
// }
return f;
}
private static LinkedList<Integer> searchKMP(char[] text, char[] ptrn){
int[] b = failureFunction(ptrn);
int j=0;
int i=0;
// pattern and text lengths
int ptrnLen = ptrn.length;
int txtLen = text.length;
int potentialWrong = 0;
LinkedList<Integer> list = new LinkedList<Integer>();
while(i<txtLen){
// System.out.println("i: "+i +", j: " +j);
if(text[i] != ptrn[j]){
potentialWrong++;
}
System.out.println("txt: " +text[i] +", ptrn: "+ptrn[j]);
System.out.println("Num wrong: " + potentialWrong);
if(potentialWrong > 1){
potentialWrong = 0;
while (j >= 0 && text[i] != ptrn[j]) {
j = b[j];
}
}
i++;
j++;
// a match is found
if (j == ptrnLen) {
list.add(i - ptrnLen);
j = b[j];
}
}
return list;
}
// private static boolean isValidMatch(String maybe, String virus){
// int numWrong = 0;
// // System.out.println(maybe +"vs."+ virus);
// for(int i=0;i<maybe.length();i++){
// if(maybe.charAt(i) != virus.charAt(i)){
// numWrong++;
// }
// if(numWrong > 1 ) return false;
// }
// return true;
// }
// private static LinkedList<Integer> getMatches(String patient, String virus){
// LinkedList<Integer> indices = new LinkedList<Integer>();
// for(int i=0;i<patient.length();i++){
// if(i+virus.length()-1 < patient.length()){
// if(isValidMatch(patient.substring(i, i+virus.length()), virus)){
// indices.add(i);
// }
// }
// else{
// break;
// }
// }
// return indices;
// }
public static void main(String[] args) {
Scanner scn = new Scanner(System.in);
int T = scn.nextInt();
String patient;
String virus;
for(int i =0;i<T;i++){
scn.nextLine(); //for empty line
patient = scn.nextLine();
virus = scn.nextLine();
LinkedList<Integer> list = searchKMP(patient.toCharArray(), virus.toCharArray());
for(int k : list){
System.out.print(k+" ");
}
System.out.println("");
}
}
}
public class KMPStringSearch {
/**
* Searches for all occurances of the word in the sentence. Runs in O(n+k)
* where n is the word length and k is the sentence length.
*
* #param word The word that is being searched
* #param sentence The collections of word over which the search happens.
* #return The list of starting indices of the matched word in the sentence.
* Empty list in case of no match.
*/
public List<Integer> searchString(final String word, final String sentence) {
final List<Integer> matchedIndices = new ArrayList<>();
final int sentenceLength = sentence.length();
final int wordLength = word.length();
int beginMatch = 0; // the starting position in sentence from which the match started
int idxWord = 0; // the index of the character of the word that is being compared to a character in string
final List<Integer> partialTable = createPartialMatchTable(word);
while (beginMatch + idxWord < sentenceLength) {
if (word.charAt(idxWord) == sentence.charAt(beginMatch + idxWord)) {
// the characters have matched
if (idxWord == wordLength - 1) {
// the word is complete. we have a match.
matchedIndices.add(beginMatch);
// restart the search
beginMatch = beginMatch + idxWord - partialTable.get(idxWord);
if (partialTable.get(idxWord) > -1) {
idxWord = partialTable.get(idxWord);
} else {
idxWord = 0;
}
} else {
idxWord++;
}
} else {
// mismatch. restart the search.
beginMatch = beginMatch + idxWord - partialTable.get(idxWord);
if (partialTable.get(idxWord) > -1) {
idxWord = partialTable.get(idxWord);
} else {
idxWord = 0;
}
}
}
return Collections.unmodifiableList(matchedIndices);
}
/**
* Creates the Partial Match Table for the word. Runs in O(n) where n is the
* length of the word.
*
* #param word The word whose Partial Match Table is required.
* #return The table as a list of integers.
*/
public List<Integer> createPartialMatchTable(final String word) {
if (StringUtils.isBlank(word)) {
return Collections.EMPTY_LIST;
}
final int length = word.length();
final List<Integer> partialTable = new ArrayList<>(length + 1);
partialTable.add(-1);
partialTable.add(0);
final char firstChar = word.charAt(0);
for (int idx = 1; idx < word.length(); idx++) {
final int prevVal = partialTable.get(idx);
if (prevVal == 0) {
if (word.charAt(idx) == firstChar) {
partialTable.add(1);
} else {
partialTable.add(0);
}
} else if (word.charAt(idx) == word.charAt(prevVal)) {
partialTable.add(prevVal + 1);
} else {
partialTable.add(0);
}
}
return Collections.unmodifiableList(partialTable);
}
}
StackOverflow. I am attempting to make a program that uses a text menu to to a multitude of things to manipulate a single string. One of the methods turns the string into an array of strings. This works fine. However, all of the methods that manipulate it as an array(one prints it out, one reverses the word order, and one sorts them using an exchange sorting method) return a NullPointerException when called. I have looked all through the code and do not see where it is coming from. Here is the .Java file containing all of the code. My problem is only happening when I call the printArray(), reverse(), and sort() methods, near the bottom. Any and all help is appreciated. Sorry for the sloppy code, I have not cleaned it up yet.
Code:
/*
Computer Programming Lab 11
Jim Kimble
3 Mar 2013
Work with strings and implementing a menu.
Acknowledgements:
Uses main structure of HUTPanel as designed at UMU, 2002-2012
*/
import java.io.*;
import java.awt.*;
import javax.swing.*;
public class HUTPanel extends JPanel
{
/***************************************************
* Class-level data members should be declared here.
***************************************************/
int numVowels;
String[] words;
String str;
String vowels;
String menuChoice;
String oString = "A tong lime ago, a daggy shog bossed a cridge over a pillmond,\n"
+"When in the course of human events\n"
+"Mary had a little lamb.\n"
+"The girls' basketball team repeated as tournament champion this weekend.";
public HUTPanel(JFrame frame)
{
// Set panel background color
setBackground(Color.WHITE);
setLayout(null);
setPreferredSize(new Dimension(810, 410));
/***************************
* Now add your code below:
***************************/
// Create a frame around this panel.
frame.setTitle("Computer Programming Lab/Program # 11");
frame.getContentPane().add(this);
str = "A tong lime ago, a daggy shog bossed a cridge over a pillmond,\n"
+"When in the course of human events\n"
+"Mary had a little lamb.\n"
+"The girls' basketball team repeated as tournament champion this weekend.";
System.out.println("Lab 11: Text Manipulation");
//getTheText();
System.out.println("The string is: '"+str+"'.");
handleTheMenu();
} // end of constructor
/*************************
* Add your methods here:
*************************/
// Get a text sequence from the keyboard and put it in str
public void getTheText()
{
Boolean inputDone = false;
while (!inputDone)
{
System.out.print("Enter your text: ");
inputDone = grabText();
}
}
private Boolean grabText()
{
try {
BufferedReader inputReader = new BufferedReader(new InputStreamReader(System.in));
menuChoice = inputReader.readLine();
return true;
}
catch(IOException e)
{
System.out.println("Error reading input. Please try again.");
}
return false;
}
public void handleTheMenu()
{
int choice = -1;
Boolean OK;
while (choice != 0)
{
choice = -1;
System.out.println("Menu:");
System.out.println();
System.out.println(" 1. Count the vowels"); //"There are ... vowels in the text."
System.out.println(" 2. Remove all letter e's"); //then print it.
System.out.println(" 3. Replace all t's with '+'"); //then print it
System.out.println(" 4. Search for a requested word (will reset the string)"); //Does 'word' exist in the text?
System.out.println(" 5. Print the words on individual lines");
System.out.println(" 6. Reset the string.");//Reset the string to the original
System.out.println(" 7. Put the words in an array"); //then print it
System.out.println(" 8. Reverse the text word order"); //then print it
System.out.println(" 9. Sort the words in an array"); //Once the words are put into an array
System.out.println();
System.out.print(" 0 to quit --> ");
OK = grabText();
if (OK)
{
try
{
choice = Integer.parseInt(menuChoice);
}
catch(NumberFormatException e)
{
System.out.println("Not a number; please try again.");
System.out.println();
}
switch(choice)
{
case 0: System.out.println();
System.out.println("Thank you.");
break;
case 1: countVowels();
break;
case 2: removeAllEs();
break;
case 3: changeTToPlus();
break;
case 4: find();
break;
case 5: listWords();
break;
case 6: reset();
break;
case 7: makeArray();
break;
case 8: reverse();
break;
case 9: sort();
break;
default: System.out.println("Not a valid choice; please try again.");
}
}
}
}
private void countVowels() {
//count the vowels in str
vowels = "aeiouAEIOU";
numVowels = 0;
for( int i = 0; i < vowels.length(); i ++) {
for(int j = 0; j < str.length(); j++) {
if (str.charAt(j) == vowels.charAt(i)) {
numVowels += 1;
}
}
}
System.out.println("The string has " + numVowels + " vowels in it.");
}
private void removeAllEs() {
String str3 = str.replace('e', ' ');
System.out.print(str3);
str = str3;
}
private void changeTToPlus() {
String str2 = str.replace('t', '+');
System.out.println(str2);
str = str2;
}
private void find() {
str = oString;
getTheText();
if(str.indexOf(menuChoice) != -1)
{
System.out.println("The word " +menuChoice+ " is at index " +str.indexOf(menuChoice));
}
else
{
System.out.println("The word " +menuChoice+ " is not in the string.");
}
}
private void listWords() {
int pos = 0;
int i = 0;
while(i > -1)
{
i = str.indexOf(' ', pos);
if (i > -1)
{
System.out.println(str.substring(pos, i));
pos = i + 1;
}
}
}
private void reset() {
str = oString;
System.out.println();
System.out.println("String reset.");
System.out.println();
}
private void makeArray() {
int n = 1;
String[] words = new String[n];
int pos = 0;
int i = 0;
int j = 0;
while(j > -1)
{
for (i = 0; i < 1000; i++)
{
n += 1;
j = str.indexOf(' ', pos);
if (j > -1)
{
words[i] = str.substring(pos, j);
pos = j + 1;
}
}
}
//printArray();
}
//***FIX***
private void printArray() {
for (int k = 0; k < words.length -1; k++){
System.out.println(words[k]);
}
}
//***FIX***
private void reverse() {
int i = 0;
int j = words.length - 1;
String temp;
while (i < j){
temp = words[i];
words[i] = words[j];
words[j] = temp;
i++;
j--;
}
}
private void sort() {
String temp = "";
for (int i = 1; i < words.length - 1; i++) {
for (int j = i + 1; j < words.length; j++) {
int x = words[i].compareTo(words[j]);
if (x > 0) {
temp = words[i];
words[i] = words[j];
words[j] = temp;
}
}
}
for (int p = 0; p < words.length -1; p++) {
System.out.println(words[p]);
}
}
}
You Error is here:
private void makeArray() {
int n = 1;
String[] words = new String[n];//At This line you are creating local array words.The instance variable words is still null.
int pos = 0;
int i = 0;
int j = 0;
while(j > -1)
{
for (i = 0; i < 1000; i++)
{
n += 1;
j = str.indexOf(' ', pos);
if (j > -1)
{
words[i] = str.substring(pos, j);
pos = j + 1;
}
}
}
use:
words = new String[n]; instead of String[] words = new String[n];
As mentioned by Luiggi Mendoza in the comment section, the local variable words defined within makeArray method is shadowing the instance variable words defined within HUTPanel class.
As side note I want to point out the unnecessary creation of new BufferedReader objects in method grabText() each time you are calling it in getTheText(). It would be much efficient if your make inputReader an instance variable in your class , and instantiate it once within the constructor using inputReader = new BufferedReader(new InputStreamReader(System.in));. This way your grabText method becomes like this :
private Boolean grabText()
{
try {
//No more new object creation for BufferedReader for each call of this method.
menuChoice = inputReader.readLine();
return true;
}
catch(IOException e)
{
System.out.println("Error reading input. Please try again.");
}
return false;
}
Make sure you always you always start with option 7, so your words array gets initialized. This is in fact not something that the user should do. The application should handle it so that the user either can't select other options, or does it automatically.
Update: Vishal K is correct, but this is still a weak point in your application.