I'm trying to reverse a sentence. (if the sentence is "i am a cat", then the result should be "cat a am I") The problem is that I'm getting an index out of bounds error, I'm not sure how to fix the problem. Not sure if my index is wrong or if the substring part is wrong. I'm just a beginner in Java, so any help is really appreciated. error: String index out of range: -1
Thanks
public class ReverseWords {
public static void main(String [] args){
Scanner in = new Scanner(System.in);
System.out.print("Enter File Name: ");
String fileName = in.nextLine();
File f = new File(fileName);
try {
Scanner input = new Scanner(f);
int x = 1;
int n = input.nextInt();
while (x<n) {
String line = input.nextLine();
Queue<String> q = new LinkedList<String>();
q.add(line);
int ws = line.indexOf(" ");
String word = line.substring(0,ws);
ArrayList<String> a = new ArrayList<String>();
while (line.length() > 0) {
a.add(word);
q.remove(word);
}
System.out.println("Case #" + x);
for (int i = a.size(); i != 0; i--) {
System.out.print(a.get(i));
}
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
From the Java documentation of String:
public int indexOf(int ch)
...
If no such character occurs in this string, then -1 is returned.
are you prepared for that there is no more whitespace?
For example at the last iteration...
But it looks like there are other bugs, too.
Your problem would be with a line like the following:
int ws = line.indexOf(" ");
String word = line.substring(0,ws);
whenever indexOf doesn't find what it's looking for, it will return -1. If you ever try to use that index on the string, you'll be indexing at -1 which is out of bounds.
it looks like you're trying to find the space in a line that has no space.
Related
I need to take a file that a user chooses and scan that file for a letter that a user chooses, and then output how many times the user's letter appeared in the file.
I know how to get the user input and get the user to select a file, as well as scanning the file, but I cannot figure out a way to check each character within a file for a specific letter. The closest I have been able to come is this:
public class FileLetterCounter
{
public static void main(String[] args) throws IOException
{
int count = 0, stringLength;
String file, a = "a";
Scanner fileScanner, letterScan;
ArrayList<String> line = new ArrayList<String>();
fileScanner = new Scanner(new File("lab6.txt"));
while (fileScanner.hasNext())
{
line.add(fileScanner.next());
for (int index = 0; index < line.length(); index ++)
{
if (line.get(index).contains(a));
{
count++;
}
}
}
}
}
This doesn't work because the length() method does not work on an ArrayList, and I am unsure of how to approach the problem. I am asking this question because I found a similar one, but the recommended solution was to use what I have right now in my for loop (line.length()), but this won't work.
Instead of adding it to the list, just scan the text into a string, iterate each character of the string to check if the character matches with the search character, and increase the value of count for each match.
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class Main {
public static void main(String[] args) throws FileNotFoundException {
int count = 0;
Scanner keyboard = new Scanner(System.in);
System.out.println("Enter the char to search: ");
char searchChar = keyboard.next().charAt(0);
Scanner fileScanner = new Scanner(new File("lab6.txt"));
while (fileScanner.hasNext()) {
String text = fileScanner.next();
for (int index = 0; index < text.length(); index++) {
if (text.charAt(index) == searchChar) {
count++;
}
}
}
System.out.println("The character " + searchChar + " appears " + count + " times in the file.");
fileScanner.close();
}
}
Look at this implementation with Streams. Looks pretty nice to me. Additionally do not forget to provide Charset, otherwise you could get unexpected results.
public static long countCharacterInFile(Path file, char ch, Charset charset) throws IOException {
try (Stream<String> stream = Files.lines(file, charset)) {
return stream.map(String::codePoints)
.flatMap(IntStream::boxed)
.filter(c -> c == ch)
.count();
}
}
Output:
Path file = Paths.get("lab6.txt");
System.out.println(countCharacterInFile(file, 'e', StandardCharsets.UTF_8)); // 666
Assuming you are trying to search a character in the whole file. Modified the code by removing all those unnecessary variables. Also I don't see any use of adding each line to a list of strings.
Idea is to scan through each line and increment count if the current character character matches your character
public class FileLetterCounter
{
public static void main(String[] args) throws IOException
{
int count = 0;
char targetLetter = 'a'; //define whatever you want or take it from user input
Scanner fileScanner = new Scanner(new File("lab6.txt"));
while (fileScanner.hasNext()) {
String line = fileScanner.nextLine();
for(int i=0; i<line.length(); i++) {
if(line.charAt(i) == targetLetter) {
count++;
}
}
}
System.out.println(count);
}
}
i'm fairly new to java and i'm trying to use indexOf to check if a persons name ends with the letters in the array and output a word it rhymes with. Where am i going wrong? e.g. Dean ends in "ean" so it rhymes with green. Thanks guys
String [] first = new String [3];
first [0] = "eem";
first [1] = "een";
first [2] = "ean";
for (int i = 0; i < first.length; i++) {
if (first[i].indexOf(first.length) != -1){
System.out.println("That rhymes with green");
}
}
To check with weather the input contains any array given element's, you should receive input and then iterate over your array to look at. For ex
String personname = "Dean";
String [] first = new String [3];
first [0] = "eem";
first [1] = "een";
first [2] = "ean";
for (int i = 0; i < personname.length; i++) {
if (input.indexOf(first[i]) != -1){ // check my input matched
System.out.println("That rhymes with green");
}
}
You should use endsWith instead of indexOf. indexOf will return the index where the passed string exactly matches the current string and, as the name suggests, endsWith will check if the current string ends with the passed string.
Take a look at the following code:
String personName = "Dean";
String[] suffix = {"eem", "een", "ean"};
String[] names = {"greem", "green", "grean"};
for(int i = 0; i < suffix.length; i++) {
if (personName.endsWith(suffix[i])){
System.out.println("That rhymes with " + names[i]);
}
}
Also, ideally, you would want to keep a map of suffix -> name for maintainability, but for simplicity/exploring this should be fine.
I have tested and ran it on the compiler. This is working fine. Please comment for any quesions. Thanks
import java.util.*;
public class HelloWorld
{
public static void main(String []args)
{
String [] first = new String [3];
first [0] = "eem";
first [1] = "een";
first [2] = "ean";
/* I am trying to get the input from user here */
String s;
Scanner in = new Scanner(System.in);
System.out.println("Enter the string:");
s = in.nextLine();
/* Now, String.indexOf(substring) will check the condition if the match happens it will print the output, if it doesn't it returns -1 */
for (int i = 0; i <s.length(); i++)
{
if (s.indexOf(first[i]) != -1)
{
System.out.println("That rhymes with green");
}
}
}
}
I am having difficulty in the following, replacing certain characters from the string
There will be two inputs, first will be character and second will be string
then I need to replace all those characters from the string with it's position
for example ,
the input and output of my program are as follows which is absolutely correct as per the requirement
Input : i this is Ignite
( Here "i" is the first input and "this is Ignite" is the second input
Output : th2s 5s 8gn11te
Input : i this is ignite and i am pratik
Output : th2s 5s 8gn11te and 20 am prat30k
The replacement should not be case-sensitive.
I had written the following program but it's having some bugs, Bugs in the sense that I am actually doing some project online and the automated sytem is not accepting the program because of some logical error.The automated system does some test cases with different inputs and check the output ( not exceptions or invalid inputs) can someone help me identify it ?
import java.util.*;
import java.io.*;
class rplc
{
public static void main(String args[])
{
String str,temp="";
char ch, ch2;
int arr[]=new int[100];
int len,i,x=0;
Scanner input=new Scanner(System.in);
ch=input.next().charAt(0);
str=input.nextLine();
str=str.replaceAll("^\\s+","");
ch2=ch;
if(Character.isUpperCase(ch))
ch2=Character.toLowerCase(ch);
else if(Character.isLowerCase(ch))
ch2=Character.toUpperCase(ch);
len=str.length();
temp=str;
for(i=0;i<len;i++)
{
if(str.charAt(i)==(int)ch || str.charAt(i)==(int)ch2)
{
arr[x]=i;
x=x+1;
}
}
x=0;
for(i=0;i<len;i++)
{
if(str.charAt(i)==(int)ch || str.charAt(i)==(int)ch2)
{
temp=str.substring(0,i);
temp=temp+(arr[x]);
temp=temp+str.substring(i+1,len);
str=temp;
len=temp.length();
x=x+1;
}
}
System.out.print(temp);
}
}
Seems like your code should work. Just in case I tried writing a simpler program:
Scanner input=new Scanner(System.in);
char ch = Character.toLowerCase(input.next().charAt(0));
String str = input.nextLine().trim().toLowerCase();
input.close();
StringBuffer buf = new StringBuffer();
for (int i = 0; i < str .length(); i++) {
if (str.charAt(i) == ch) {
buf.append(i);
}
else {
buf.append(str.charAt(i));
}
}
System.out.println(buf.toString());
And the output seems to be same.
Perhaps your function should return the value instead of printing it?
From the comments I understand that there will be only 1 input from the user.
The following input:
i this is ignite and i am pratik
Where the first 'i' is the charcter which needs to be replaced in 'this is ignite and i am pratik'.
Modify following:
str=input.nextLine();
str=str.replaceAll("^\\s+","");
to
str = input.nextLine();
str = str.substring(1);
str = str.replaceAll("^\\s+", "");
Try Something like this,
Scanner s = new Scanner(System.in);
String Line = s.nextLine();
String ch = Line.substring(0,Line.indexOf(" ")).trim();
Line = Line.substring(Line.indexOf(" ")).trim();
String[] x= Line.split(ch);
String y="";
for(String t:x){
y=y.equals("")?t:y+y.length()+t;
}
System.out.println(y);
I did some code cleaning but the most important steps were to use a list of dynamic size instead of a fixed size array and a while-loop with dynamic termination instead of a for-loop. This is because the length of the output String will change (increase) when there a characters to be replaced at positions >9 and thus in your code the execution can stop in the middle of the result string and there are characters not being replaced.
There is even a special case, when the replaced character is a number itself. To avoid problems there I added this line
i = i + Integer.toString(list.get(pos)).length()-1;
in order to step over newly added number characters in the output String.
import java.util.*;
import java.io.*;
class rplc
{
public static void main(String args[])
{
List<Integer> list = new ArrayList<Integer>();
Scanner input=new Scanner(System.in);
char ch = input.next().charAt(0);
String str=input.nextLine().trim();
int len=str.length();
for(int i=0;i<len;i++)
{
if(str.charAt(i)==Character.toLowerCase(ch) || str.charAt(i)==Character.toUpperCase(ch))
{
list.add(i);
}
}
int pos = 0;
int i = 0;
while(i<str.length())
{
if(str.charAt(i)==Character.toLowerCase(ch) || str.charAt(i)==Character.toUpperCase(ch))
{
String start = str.substring(0,i)+Integer.toString(list.get(pos));
String end = i<=str.length() ? str.substring(i+1) : "";
i = i + Integer.toString(list.get(pos)).length()-1;
pos++;
str = start.concat(end);
}
i++;
}
System.out.print(str);
}
}
I can't see any special bugs. Could be that I lost sight of something. This is my first answer here and English is not my mother tongue, so please excuse any formal errors.
I liked the problem so I made my own answer. apologies for the dirty looking code. :)
Scanner input=new Scanner(System.in);
String firstInput=input.nextLine().charAt(0) + "";
//ensure its lower case
firstInput=firstInput.toLowerCase();
String secondInput=input.nextLine();
//ensure char in secondInput is lower cased too.
secondInput=secondInput.replaceAll(firstInput.toUpperCase(),firstInput);
String[] splitted=secondInput.split(firstInput);
String output="";
int current=0;
for(int i=0;i<splitted.length;i++){
String s=splitted[i];
current=current+ s.length();
if(i==splitted.length-1){
output=output+s;
}else{
output=output+s;
output=output+ current;
current++;
}
}
//edited part, as split doesn't split if firstinput is the last character of the string
if(secondInput.endsWith(firstInput)){
output=output+secondInput.length();
}
System.out.println(output);
This is what I have so far, if the string has two integers I need to pull them out and use them in the acker function that takes in two integers as parameters.
public static void main(String []args)
{
String nextLine = "";
BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
AckerFunction x = new AckerFunction();
System.out.println("Input two integers separated by a space character (enter q to quit):");
try {
nextLine = input.readLine();
}
catch (IOException e) {
e.printStackTrace();
}
if (nextLine.matches("[0-9]+") && nextLine.length() > 2)
{
x.acker(m, n)
}
I suppose you want to get two integers from console. Use nextInt() method like in the code shown below.
public static void main(String[] args) {
AckerFunction x = new AckerFunction();
Scanner input = new Scanner(System.in);
System.out.println("Input two integers separated by a space character");
try {
int m = input.nextInt();
int n = input.nextInt();
x.acker(m,n);
}
catch(InputMismatchException e) {
System.out.println("Incorrect input, please enter integers");
}
finally {
input.close();
}
}
First, you can use .Split() method to split the string into an array to have direct access to any of the elements/numbers. Just an example:
String str = "123 456";
char c = ' ';
String[] s = str.Split(c);
double[] nums = new double[str.Length]
for(int i=0; i<s.Length; i++)
{
double d;
if(Double.TryParse(s[i], out d))
nums[i] = d;
}
Just added some check so you won't have errors. If it's not a number, it'd stay null.
This will extract the first two integers from a string and ignore all other characters. If you only want to get two numbers from the console prudhvi has the right answer.
String regex = "-?\\d+";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(nextLine);
int i = 0;
int[] val = new int[2];
while( matcher.find() && i++ < 2 )
val[i-1] = Integer.valueOf(matcher.group());
if( i == 2 )
x.acker(val[0], val[1]);
So the code I have is for a homework assignment where the user inputs a sentence (string) and I need to search through the string and return the smallest word. However, there must be a number inputted at the first spot in the string. Ex: "4 WHAT IS THIS". Output should be "IS" and ignore the number. The only way I figured out how to ignore the number is to make the loop skip over the first spot where the number would be. It works by itself but whenever I put it into the rest of my program it stops working. Is there anyway to make this program cleaner?
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
// Lexicographically smallest word
String TheSentence = sc.nextLine();
String[] myWords = TheSentence.split(" ");
int shortestLengths, shortestLocation;
shortestLengths = (myWords[1]).length();
shortestLocation = 1;
for (int i = 1; i < myWords.length; i++) {
if ((myWords[i]).length() < shortestLengths) {
shortestLengths = (myWords[i]).length();
shortestLocation = i;
}
}
System.out.println(myWords[shortestLocation]);
}
Inside your for loop (that should start at i = 0), add code like this:
try {
double value = Double.parseDouble(myWords[i]);
} catch (NumberFormatException e) {
// add the rest of your code here
}
The idea is that you try to transform your word to a number and if you fail, it means it's not a number, so you can use the length logic on the word.
The first thing you should do is to create the function you want to use instead of mixing the relevant code for the exercice with things like reading a line from the input stream.
You can test whether a character is a letter using Character.isLetter(char).
A good exercice is to build a solution using only that function and looking at each character separately (String.charAt(int) method) in a loop.
The solution is to remember where the currently shortest word starts and how long it is.
In practice, I would just use regexes like this:
public static String shortestWord(String sentence) {
String shortest = null;
Pattern word = Pattern.compile("\\w+");
Matcher m = word.matcher(sentence);
while (m.find()) {
String candidate = m.group();
if (shortest == null || shortest.length() > candidate.length())
shortest = candidate;
}
return shortest;
}
You could try using substring, e.g.
String result=inputString.substring(1)
'1' being the second letter in the string, substring returning every value save for the first.
The below basically just shortens up your code..other than that it doesn't change much. That being said..it would be much better to create all this in a method called shortestWord() or something. There is really no reason the code below shouldn't work though.
Revised Code:
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String[] myWords = (sc.nextLine()).split(" ");
int shortestLocation = 1
for (int i = 2; i < myWords.length; i++) { // No reason to start at 1 as you have
// already made shortestLocation = 1
if (myWords[i].length() < myWords[shortestLocation].length()) {
shortestLocation = i;
}
}
System.out.println(myWords[shortestLocation]);
}
Suggested Code:
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String[] myWords = (sc.nextLine()).split(" ");
System.out.println("The shortest word is: " + shortestWord(myWords));
}
public static String shortestWord(String[] myWords) {
int shortestLocation = 1
for (int i = 2; i < myWords.length; i++) { // No reason to start at 1 as you have
// already made shortestLocation = 1
if (myWords[i].length() < myWords[shortestLocation].length()) {
shortestLocation = i;
}
}
return myWords[shortestLocation];
}