Sounds Pretty Straightforward, but for me it's quite strange. I'm trying to import a data file (which I've done successfully), and use this and compare each and every word to see which one is the longest. So far, it is not working (index out of bounds), and when I did manipulate it to work (incorrectly), it gave me the wrong word as the longest one.
This is what I have so far...
Main File:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Scanner;
import java.util.Collections;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import static java.lang.System.*;
public class FancyWordsRunner
{
private static int max = 0;
public static void main( String args[] ) throws IOException
{
ArrayList<String> wordList = new ArrayList<String>();
{
String ray = "";
Scanner welcome = new Scanner(new File("fancywords.dat"));
while(welcome.hasNext())
{
ray = welcome.next();
wordList.add(ray);
for(int i = 0; i<wordList.size(); i++)
{
int j = i+1;
if(wordList.get(j).length()>wordList.get(i).length())
max = j;
}
}
}
String maximum = wordList.get(max);
out.println(maximum);
}
}
fancywords.dat:
2013 UIL STATE CONTEST
PROGRAMMING IS FUN
TODAY IS SATURDAY
Current Output:
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 1, Size: 1
at java.util.ArrayList.RangeCheck(ArrayList.java:547)
at java.util.ArrayList.get(ArrayList.java:322)
at FancyWordsRunner.main(FancyWordsRunner.java:35)
How about replacing your while loop with something like this.
String longestSoFar = "";
while (welcome.hasNext()) {
String current = welcome.next();
if (current.length() > longestSoFar.length()) {
longestSoFar = current;
}
}
I realize that your bug has been identified by other answers, but, you do realize that this problem can be solved in a much simpler way?
public static void main( String args[] ) throws IOException {
String max = "";
Scanner welcome = new Scanner(new File("fancywords.dat"));
while(welcome.hasNext()) {
String ray = welcome.next();
if (ray.length() > max.length()) {
max = ray;
}
}
System.out.println(max);
}
In your first iteration, you've only added one item to the list, so the size is 1 meaning only an index of 0;
int j = i+1;
if(wordList.get(j)
This is trying to access index 1
Walk through:
1)
ArrayList<String> wordList = new ArrayList<String>();
// wordlist.size() = 0; available indices - none
2)
wordList.add(ray);
// wordlist.size() = 1; available indices - 0
3)
int j = i+1; // i = 0; j = 1
if(wordList.get(j) // access index j
// oops!; There is no index j
This causes an IndexOutOfBoundsException.
EDIT: Alternative - you really don't need a list to perform this task
String maxWord = "";
String current = "";
while(welcome.hasNext()){
current = welcome.next();
if (current.length() > maxWord.length()){
maxWord = current;
}
}
System.out.println(maxWord);
for(int i = 0; i<wordList.size(); i++)
{
int j = i+1;
You're setting up your for loop to make sure i is never out of bounds, but then you set j equal to one larger than i, so on the last run of the loop, when i is at the last index, j is one larger than the last index (and out of bounds).
Try this:
for(int i=0; i<(wordList.size()-1); ++i)
Solution to the logic error:
for(int i = 0; i<wordList.size();++i) {
if(wordList.get(i).length() >= wordList.get(max).length()) {
max = i;
}
}
(This also gets rid of the j that was causing the IndexOutOfBoundsException in the first place.)
And as others have pointed out, there is some redundancy in your program. Changing your for loop to my suggestion will fix your logic problem and make your program output the correct result. The other answers all get rid of the ArrayList, which isn't totally necessary, but if you want to simplify your solution and keep the ArrayList, your while loop could look something like this:
String longestWord = "";
Scanner welcome = new Scanner(new File("fancywords.dat"));
while(welcome.hasNext()) {
ray = welcome.next();
wordList.add(ray);
if(ray.length() > longestWord.length()) {
longestWord = ray;
}
}
This solution simplifies your answer, saves some time in the program and keeps the ArrayList (you still have every word saved in memory).
Your for loop was running a LOT and checking every word numerous times. Once we know that CONTEST is the longest of the first four words, we don't need to see whether PROGRAMMING is longer than the first three or not, just whether it's longer than CONTEST, and we don't need to compare SATURDAY to any word other than PROGRAMMING, which was established as the longest word when it was read and continued to be the longest word between then and reading SATURDAY, etc. If all we care about is the longest word, we only need to compare each word to the current longest word.
And because your ArrayList is still in memory, you can recreate the original words you read in, find the shortest word, find the average word length, etc., whatever you want to do with it.
Related
In this question we need to find the number of "codechef" that we can form using the characters taken from input strings.
First line is number of test cases and next line is the number of
input string. The output is a single integer value representing the
number of "codechef" string that can be formed from the given
characters.
It throws NZEC error on submitting and when I use try catch block to avoid it, it shows wrong answer. This is a question from codechef beginners section.
Problem Link
My approach:
Store every character from the input string into a Hashmap with the frequency.
Create one character array containing the characters used in the word "codechef". And another integer array contains the frequency of these corresponding characters, here my arrays are
char[ ] c ={c,o,d,e,h,f}
int[ ] arr={2,1,1,2,1,1}
I run a loop traversing each character in hashmap and delete the character count needed for a word formation. Every complete traversal will give one increment in count.
Implementation:
import java.util.*;
import java.lang.*;
import java.io.*;
class Codechef
{
public static void main (String[] args) throws java.lang.Exception
{
Scanner sc = new Scanner(System.in);
int T = sc.nextInt();
while(T-->0){
int n = sc.nextInt();
sc.nextLine();
String s;
HashMap<Character,Integer> hmap = new HashMap<Character,Integer>();
for(int i = 0;i < n;i++){
s = sc.nextLine();
for(int j = 0;j < s.length();j++){
if(hmap.containsKey(s.charAt(j)))
hmap.put(s.charAt(j),hmap.get(s.charAt(j))+1);
else
hmap.put(s.charAt(j),1);
}
}
/* for(Map.Entry entry:hmap.entrySet()){
System.out.println(entry.getKey()+": "+entry.getValue());
}*/
int arr[] = {2,1,1,2,1,1};
char crr[] = {'c','o','d','e','h','f'};
int count = 0;
int i = 0;
boolean flag = true;
while(flag){
if(hmap.get(crr[i])>=arr[i])
hmap.put(crr[i],hmap.get(crr[i])-arr[i]);
else flag = false;
if(i==5 && flag)
{
count++;
i = 0;
}
else
i++;
}
System.out.println(count);
}
sc.close();
}
}
if(hmap.get(crr[i])>=arr[i])
This line contains an Exception what if hmap does not contain crr[i].
Try catch will always give wrong answer in these sites because these sites only checks what answer your code is producing.
I'm writing some code to read an input file of book titles, and putting the read lines into an array and trying to print out the array. But when I try to print out the array, it just returns 'null' for each read line. I'm not sure what I'm doing wrong or what my code is doing. Any suggestions? Thanks!
Code:
import java.io.*;
import java.util.*;
public class LibraryInputandOutputs {
public static void main(String args[]) throws IOException{
int lineCount = 0;
File inputFile = new File("bookTitles.inp.txt");
Scanner reader = new Scanner(inputFile);
while(reader.hasNextLine()) {
reader.nextLine();
lineCount++;
}
String[] bookArray = new String[lineCount];
while (reader.hasNextLine()) {
for (int i = 0; i < lineCount; i++) {
bookArray[i] = reader.next();
}
}
for (int k = 0; k < lineCount; k++) {
System.out.println(bookArray[k]);
}
reader.close();
inputFile.close();
}
}
My text file I'm reading from is 20 book titles, all on different lines.
My output on the terminal is 20 lines of null.
Lets break this down:
This reads every line of the input file, counts each one, and then discards them:
while(reader.hasNextLine()) {
reader.nextLine();
lineCount++;
}
You are now at the end of file.
Allocate a string array that is large enough.
String[] bookArray = new String[lineCount];
Attempt to read more lines. The loop will terminate immediately because reader.hasNextLine() will return false. You are already at the end of file.
So you the statement assigning to bookArray[i] won't be executed.
while (reader.hasNextLine()) {
for (int i = 0; i < lineCount; i++) {
bookArray[i] = reader.next();
}
}
Since bookArray[i] = ... was never executed above, all of the array elements will still be null.
for (int k = 0; k < lineCount; k++) {
System.out.println(bookArray[k]);
}
One solution is to open and read the file twice.
Another solution is to "reset" the file back to the beginning. (A bit complicated.)
Another solution would be to use a List rather than an array so that you don't need to read the file twice.
Another solution is to search the javadocs for a method that will read all lines of a file / stream as an array of strings.
(Some of these may be precluded by the requirements of your exercise. You work it out ... )
The nested loop in step 3 is also wrong. You don't need a for loop inside a while loop. You need a single loop that "iterates" the over the lines and also increments the array index (i). They don't both need to be done by the loop statement itself. You could do one or the other (or both) in the loop body.
Stephen C has already pointed out the main problems with your logic. You're trying to loop twice through the file but you've already reached the end of the file the first time. Don't loop twice. "Merge" both the while loops into one, remove that for loop inside the while loop and collect all the book titles. You can then use the size of the list to print them later on. My Java might be rusty but here it goes -
import java.io.*;
import java.util.*;
public class LibraryInputandOutputs {
public static void main(String args[]) throws IOException {
// int lineCount = 0; - You don't need this.
File inputFile = new File("bookTitles.inp.txt");
Scanner reader = new Scanner(inputFile);
// Use an array list to collect book titles.
List<String> bookArray = new ArrayList<>();
// Loop through the file and add titles to the array list.
while(reader.hasNextLine()) {
bookArray.add(reader.nextLine());
// lineCount++; - not needed
}
// Not needed -
// while (reader.hasNextLine()) {
// for (int i = 0; i < lineCount; i++) {
// bookArray[i] = reader.next();
// }
// }
// Use the size method of the array list class to get the length of the list
// and use it for looping.
for (int k = 0; k < bookArray.size(); k++) {
System.out.println(bookArray[k]);
}
reader.close();
inputFile.close();
}
}
I agree with Stephen C. In particular, using a List is usually better than an array because it's more flexible. If you need an array, you can always use toArray() after the List is filled.
Are your book titles on separate lines? If so you might not need a Scanner class, and could use something like a BufferedReader or LineNumberReader.
I need to write a program that let's the user write 3 words in the console, then the program reprints those 3 words (one in each line) but also fills out the remaining spaces in each line with dots (".") so the total number of characters in each lines becomes a total of 30 characters.
Example:
Input:
Hello
Me
Overflow
Output:
.........................Hello
............................Me
......................Overflow
This is the code that I currently have which generates an error. I have been given the code (at the bottom) as part of my assignment and need to write the repeatChar method to make it work.
The first thing I did was to add the following commands in the code, in order to save the 3 words into the array threeWord.
threeWord[1] = wordOne;
threeWord[2] = wordTwo;
threeWord[3] = wordThree;
Next, I had to write the method repeatChar, and I decided to use a for-loop to make it repeat dots for each individual line, but I'm having a hard time making it fit with the rest of the code. Any guidance would be much appreciated, thanks.
import java.util.*;
public class FillDots {
private static int LineLength = 30;
public static void main(String[] arg) {
String[] threeWord = new String [3]; // Defines 3 locations to place strings in the array "threeWord"
Scanner console = new Scanner(System.in);
System.out.println("Type in three words:");
String wordOne = console.next();
threeWord[1] = wordOne; // Saves first word to array "threeWord"
String wordTwo = console.next();
threeWord[2] = wordTwo; // Saves second word to array "threeWord"
String wordThree = console.next();
threeWord[3] = wordThree; // Saves third word to array "threeWord"
for(int i = 0; i < threeWord.length; i++) {
System.out.println(repeatChar('.', LineLength - threeWord[i].length()) + threeWord[i]);
}
}
public static String repeatChar(String LineLength) {
for(int j = 0; j < LineLength; j++) {
System.out.print(".");
}
}
}
Besides the index starts from 0, you need return the dots in the repeatChar method:
public static String repeatChar(char repeatChar, int repeatTimes) {
String result = "";
for(int j = 0; j < repeatTimes; j++) {
result += repeatChar;
}
return result;
}
You can use existing library for doing padding
for(String temp:threeWord)
system.out.println(org.apache.commons.lang.StringUtils.leftPad(temp, 10, ".") );
this might simplify your code
My method is supposed to print out all of the strings in between 2 strings in my ArrayList, exclusive of both the beginning string and the end string.
public void printRange(String beg, String end)
{
for(int i = 0; i < list.size(); i++)
{
}
}
String beg is the beginning string and String end is the last string. To further clear up, if I have an ArrayList containing the words "dog" "cat" "apple" "banana" "turtle", and I enter in "cat" and "turtle", the method should print out "apple" and "banana".
I know I should iterate through the list, but I'm lost as to where I go from there.
Edit: Sorry for posting 2 questions! I'll submit them differently next time.
Try using a flag to avoid one more N iteration.
public void printRange(String beg, String end)
{
boolean startPrinting = false;
for (int i = 0; i < list.size(); i++)
{
if (startPrinting) {
System.out.println(list.get(i));
}
if (list.get(i).equals(beg)) {
startPrinting = true;
} else if (list.get(i).equals(end)) {
break;
}
}
}
I would edit out the second question. You don't post two questions for one topic on SO.
Regarding your first question, you want to get the index of where the first string and the last string are found. Something like this:
public void printRange(String beg, String end)
{
int begIdx, endIdx;
for(int i = 0; i < list.size(); i++)
{
if (list[i].equals(beg)) {
begIdx = i;
}
if (list[i].equals(end)) {
endIdx = i;
}
}
for(int i = begIdx; i < endIdx; i++)
// Print range...
}
That's a quick and dirty implementation. You can do this in one traversal of the list.
You can also make use of the indexOf() method. I am not sure what you are up to, but bear in mind a List can contain duplicate keys. Consider using a Set instead.
package com.company;
import java.util.ArrayList;
import java.util.List;
public class Main {
private List<String> list = new ArrayList<String>();
{
list.add("dog");
list.add("cat");
list.add("apple");
list.add("banana");
list.add("turtle");
}
public void printRange(String beg, String end)
{
int start = list.indexOf(beg) + 1;
int finish = list.indexOf(end);
if (start <= 0 || start >= finish) return;
for(int i = start; i < finish; i++)
{
System.out.println(list.get(i));
}
}
public static void main(String[] args) {
new Main().printRange("cat", "turtle");
}
}
I'd use a tiny state machine -
state 0 = beginning not found
state 1 = beginning found, end not found
state 2 = end found (or could go back to 0 if you want to look for beginning again)
You need relevant checks to change the state and only have to print stuff out when you're in state 1.
This way you only have to go through the list once instead of going through it (partially) to find beginning and end, and then going through it (partially) again to output required fields.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
Getting NullPointerException when it tries to access stones[0].length.
Please Help. I have already Initialized Stones Object.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
public class Solution
{
public static void main(String args[]) throws IOException
{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
Scanner sc = new Scanner(System.in);
int times = sc.nextInt();
String stones[] = new String[times];
int score = 0;
int counter;
for(int tcase = 0; tcase < times; tcase++)
stones[tcase] = br.readLine();
int s = stones[0].length();
for (int i = 0; i < s ; i++) {
char j = stones[0].charAt(i);
counter = 0;
for (int k = 1; k < times; k++) {
char aa[] = stones[k].toCharArray();
for (int l = 0; l <aa.length ; l++) {
if(aa[l]==j)
{
counter++;
break;
}
}
if (counter==times-1) {
score++;
}
}
}
System.out.println(score);
}
}
Getting NullPointerException when I try to access stones[0].length(). Please help
When you submit your code through some automated service, it's running your code and it's failing because there's no System.in stream to provide any valid data. If you attempt to check for valid data before doing anything, it will catch this condition, and should let you submit, while still working properly on your laptop.
Try this:
Scanner sc = new Scanner(System.in);
int times = 0;
if ( sc.hasNext() ) { // check to make sure there's valid input first
times = sc.nextInt();
String stones[] = new String[times];
int score = 0;
int counter;
for(int tcase = 0; tcase < times; tcase++)
stones[tcase] = br.readLine();
if ( stones[0] != null ) { // check to make sure your array object exists
int s = stones[0].length();
for (int i = 0; i < s ; i++) {
char j = stones[0].charAt(i);
counter = 0;
for (int k = 1; k < times; k++) {
char aa[] = stones[k].toCharArray();
for (int l = 0; l <aa.length ; l++) {
if(aa[l]==j)
{
counter++;
break;
}
}
if (counter==times-1) {
score++;
}
}
}
}
}
The best way to make sense of these sort of problems is to use a debugger. But just for fun, let's do some code analysis...
int s = stones[0].length();
What can be generating a NullPointerException on this line? Well, the stones variable could be referring to null. We can easily rule this out, however, as the stones variable was assigned a new array instance further up in the code, and was never reassigned before reaching the problem line. The only other possibility is that the array component variable stones[0] refers to null.
Why might stones[0] be null? Well, for starters, it's initialized that way, so if you never assign to that component, then it will be null. However, the for loop that you have between array initialization and the problem line is iterating over all of the array components and initializing them, so every component will be assigned to. What else might be the problem?
The loop is assigning to each array component the value returned by br.readLine(). Could that return value possibly be null? Let's take a look at the javadocs...indeed, we find (emphasis added):
Returns: A String containing the contents of the line, not including any line-termination characters, or null if the end of the stream has been reached
And there you have it, it is certainly possible for stones[0] to be null! Now, if that is true, what does it mean? Well, it means that the very first call to br.readLine() returned null, signalling that it had reached the end of the stream. Which fits with what other answerers have noted - if System.in() is not available to provide any data, it would make sense to encounter the 'end of stream' condition right out of the gate.
It works with me, although I would not use two stream readers(a Scanner and a BufferedReader) for the same input.
What is the input that causes the exception?
PS. You should close the Scanner when it is not used.