I am getting this error when I enter the String "s" after entring an integer.
Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 0
at java.lang.String.charAt(Unknown Source)
at oneB.change(oneB.java:4)
at oneB.main(oneB.java:26)
Following is the code: (Please note that the code is still complete and I have entered some print statements for checking)
import java.util.Scanner;
public class oneB {
public static String change(int n, String s, String t) {
if (s.charAt(0) == 'R') {
return onetwo(s);
}
return s;
}
private static String onetwo(String one) {
int c = one.indexOf('C');
System.out.print(c);
char[] columnarray = new char[one.length() - c - 1];
for (int i = c + 1; i < one.length(); i++) {
columnarray[i] = one.charAt(i);
}
int columnno = Integer.parseInt(new String(columnarray));
System.out.print(columnno);
return one;
}
public static void main(String[] args) {
Scanner in = new Scanner(System. in );
int n = in .nextInt();
String s = in .nextLine();
String t = in .nextLine();
System.out.print(change(n, s, t));
}
}
The call in.nextInt() leaves the endline character in the stream, so the following call to in.nextLine() results in an empty string. Then you pass an empty string to a function that references its first character and thus you get the exception.
Here's how I debugged it:
You are getting a StringIndexOutOfBoundsException with index zero at line 4.
That means that the String you are operating on when you call s.charAt(0) is the empty String.
That means that s = in.nextLine() is setting s to an empty String.
How can that be? Well, what is happening is that the previous nextInt() call read an integer, but it left the characters after the integer unconsumed. So your nextLine() is reading the remainder of the line (up to the end-of-line), removing the newline, and giving you the rest ... which is an empty String.
Add an extra in.readLine() call before you attempt to read the line into s.
One another solution to the problem would be instead of nextLine(), use just next().
int n = in .nextInt();
String s = in .next();
It looks like s is an empty String "".
for (int i = c + 1; i < one.length(); i++) {
columnarray[i] = one.charAt(i); // problem is here.
}
You need to start array index from 0. But you are starting from c + 1
for (int i = c + 1,j=0; i < one.length(); i++,j++) {
columnarray[j] = one.charAt(i);
}
The problem is that when you hit enter, your int is followed by a '\n' character. Just modify the code like this :
public static void main(String[] args) {
Scanner in = new Scanner(System. in );
int n = in .nextInt();
in.nextLine(); //This line consume the /n afer nextInt
String s = in .nextLine();
String t = in .nextLine();
System.out.print(change(n, s, t));
}
Related
I have a method that extracts a certain substring from a string. This substring consists of the numbers in the string. Then this is parsed to an integer.
Method:
protected int startIndex() throws Exception {
String str = getWorkBook().getDefinedName("XYZ");
String sStr = str.substring(10,13);
return Integer.parseInt(sStr) - 1;
}
Example:
String :
'0 DB'!$B$460
subString :
460
Well, I manually entered the index range for the substring. But I would like to automate it.
My approach:
String str = getWorkBook().getDefinedName("XYZ");
int length = str.length();
String sStr = str.substring(length - 3, length);
This works well for this example.
Now there is the problem that the numbers at the end of the string can also be 4 or 5 digits. If that is the case, I naturally get a NullPointerException.
Is there a way or another approach to find out how many numbers are at the end of the string?
You can use the regex, (?<=\D)\d+$ which means one or more digits (i.e. \d+) from the end of the string, preceded by non-digits (i.e. \D).
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Main {
public static void main(String[] args) {
// Test
System.out.println(getNumber("'0 DB'!$B$460"));
}
static String getNumber(String str) {
Matcher matcher = Pattern.compile("(?<=\\D)\\d+$").matcher(str);
if (matcher.find()) {
return matcher.group();
}
// If no match is found, return the string itself
return str;
}
}
In your case I would recommend to use regex with replaceAll like this:
String sStr = str.replaceAll(".*?([0-9]+)$", "$1");
This will extract the all the digits in the end or your String or any length.
Also I think you are missing the case when there are no digit in your String, for that I would recommend to check your string before you convert it to an Integer.
String sStr = str.replaceAll(".*?([0-9]+)$", "$1");
if (!sStr.isEmpty()) {
return Integer.parseInt(sStr) - 1;
}
return 0; // or any default value
If you just want to get the last number, you can go through the entire string on revert and get the start index:
protected static int startIndex() {
String str = getWorkBook().getDefinedName("XYZ");
if(Character.isDigit(str.charAt(str.length() - 1))) {
for(int i = str.length() - 1; i >= 0; i--){
if(!Character.isDigit(str.charAt(i)))
return i+1;
}
}
return -1;
}
and then print it:
public static void main(String[] args) {
int start = startIndex();
if(start != -1)
System.out.println(getWorkBook().getDefinedName("XYZ").substring(start));
else
System.out.println("No Number found");
}
You will have to add the
Simple and fast solution without RegEx:
public class Main
{
public static int getLastNumber(String str) {
int index = str.length() - 1;
while (index > 0 && Character.isDigit(str.charAt(index)))
index--;
return Integer.parseInt(str.substring(index + 1));
}
public static void main(String[] args) {
final String text = "'0 DB'!$B$460";
System.out.println(getLastNumber(text));
}
}
The output will be:
460
If I were going to do this I just search from the end. This is quite efficient. It returns -1 if no positive number is found. Other return options and the use of an OptionalInt could also be used.
String s = "'0 DB'!$B$460";
int i;
for (i = s.length(); i > 0 && Character.isDigit(s.charAt(i-1)); i--);
int vv = (i < s.length()) ? Integer.valueOf(s.substring(i)) : -1;
System.out.println(vv);
Prints
460
If you know that there will always be a number at the end you can forget the ternary (?:) above and just do the following:
int vv = Integer.valueOf(s.substring(i));
I'm trying print a given String char by char:
public static void main(String[] args) {
char c;
Scanner scaner = new Scanner(System.in);
int length = scaner.next().length();
System.out.println(length);
int i = 0;
while (i < length) {
c = scaner.next().charAt(i);
System.out.println(c);
i++;
}
}
Once this code has reached int length = scaner.next().length(); it doesn't continue. What's causing this?
You should store the scanned value in the temporary variable.
char c;
Scanner scaner = new Scanner(System.in);
// Storing scanned value
String nextStr = scaner.next();
int length = nextStr.length();
System.out.println(length);
int i = 0;
while(i < length){
c = nextStr.charAt(i);
System.out.println(c);
i++;
}
In your original code you call next repeatedly in a loop, but this does not return the original scanned value, but the next line of input.
You need to enter something after calling next().
As addition too Alexander's answer.
The line: int length = scaner.next().length(); gets the next line and then checks the length.
So you already got the next line and calling next() again asks for different input.
That's the reason why you should always store the return value of next() in a variable!
I need help with decompressing method. I have a working Compress method. Any suggestions as far as what I need to consider? Do I need parseInt or else....? Appreciate the advice. Here is what I have so far. If s = "ab3cca4bc", then it should return "abbbccaaaabc", for example of decompress.
class RunLengthCode {
private String pText, cText;
public RunLengthCode () {
pText = "";
cText = "";
}
public void setPText (String newPText) {
pText = newPText;
}
public void setCText (String newCText) {
cText = newCText;
}
public String getPText () {
return pText;
}
public String getCText () {
return cText;
}
public void compress () { // compresses pText to cText
String ans = "";
for (int i = 0; i < pText.length(); i++) {
char current = pText.charAt(i);
int cnt = 1;
String temp = "";
temp = temp + current;
while (i < pText.length() - 1 && (current == pText.charAt(i + 1))) {
cnt++;
i++;
temp = temp + current;
}
if (cnt > 2) {
ans = ans + current;
ans = ans + cnt;
}
else
ans = ans + temp;
setCText(ans);
}
}
public void decompress () {
}
}
public class {
public static void main(String [] args) {
Scanner in = new Scanner(System.in);
RunLengthCode myC = new RunLengthCode();
String pText, cText;
System.out.print("Enter a plain text consisting of only lower-case alphabets and spaces:");
pText = in.nextLine();
myC.setPText(pText);
myC.compress();
System.out.println(pText+" => "+myC.getCText());
System.out.print("Enter a compressed text consisting of only lower-case alphabets, spaces and digits:");
cText = in.nextLine();
myC.setCText(cText);
myC.decompress();
System.out.println(cText+" => "+myC.getPText());
}
}
You could create break the string into regx groups and combine them.
The following pattern works
(([A-Za-z]+[\d]*))
This will break your string "ab3cca4bc" into groups of
"ab3", "cca4", "bc"
So in a loop if the last character is a digit, you could multiply the character before it that many times.
Ok, so you've got an input string that looks like ab3cca4bc
1.) Loop over the length of the input String
2.) During each loop iteration, use the String.charAt(int) method to pick up the individual character
3.) The Character class has an isDigit(char) function that you can use to determine if a character is a number or not. You can then safely use Integer.parseInt(String) (you can use myChar+"" to convert a char into a String)
4.) If the char in question is a number, then you'll need to have an inner loop to repeat the previous character the correct number of times. How will you know what the last character was? Maybe have a variable that's instantiated outside the loop that you update each time you add a character on the end?
I tried to count the occurrence of alphabets in a string, but I substitue them with numbers to make it clearer. Then when I run that code, it doesnt display the results I want.I dont really know why...Please help!! Thank you so much!!
Scanner Scanner1 = new Scanner(System.in);
out.println("Please type in a string below.");
String UserInput = Scanner1.nextLine();
String Index = "12345";
int length = 2;//Modified
int[] count = new int[length];
int length2 = 5; //Modified
int n1 = 0;
int n2 = 0;
out.println(UserInput.charAt(n1));//Modified
out.println(Index.charAt(n2));//Modified
for (int i = 0; i < length; i++) {
if (UserInput.charAt(n1) == Index.charAt(n2)) {
n1++;
count[length - (length - n1)]++;
} else {
n2++;
if(n2==length2)
{
n2 = n2-length2;
}
}
}
A relatively short and neat way to count a specific character in a string is using the return value of the replaceAll method:
public static int countChar(final String str, final char c) {
return str.replaceAll("[^" + c + "]","").length();
}
The pattern [^x] (x can be replaced with any char (or amount of different chars)) will match everything in a given String except x. So [^T] of TEST would replace E and S with the given replacement (which is "" (nothing)) and keeps the Ts. The method would return TT. If you count that length, you'll receive the count of the searched character of the given string.
The example
System.out.println(countChar("TEST", 'T'));
System.out.println(countChar("TEST", 'E'));
System.out.println(countChar("TEST", 'S'));
prints
2
1
1
(keep in mind that is method is case sensitive)
use collections like Hashmap. Here Character stores every unique character encountered and Integer stores the count of every character whenever it is encountered.
I've got this bit of code here:
public class Project1 {
public static void main(String args[])
{
Scanner input = new Scanner(System.in);
System.out.println("Input a binary number");
String binary = input.nextLine();
System.out.println(Conversion(binary));
}
public static int Conversion(String binary)
{
StringTokenizer st = new StringTokenizer(binary, " ");
int n = st.countTokens() - 1; // Used as the power number in b^n for conversion
int result = 0;
while(st.hasMoreTokens()){
int binaryInt = Integer.parseInt(st.nextToken());
result += binaryInt * (1 << n);
n--;
}
return result;
}
}
And it works beautifully... if the input has spaces in between the binary numbers. For example, if the input is 1 1 1 1, then it will rightfully return 15. Cool, but how do I change the tokenizer to not require spaces to split each digit? I tried doing StringTokenizer(binary, ""); and StringTokenizer(binary);, but neither properly split each digit into it's own token.
You will notice that, while StringTokenizer obviously only works with Strings, I've converted the Strings into ints inside my conversion method before returning the result.
# Tony I think you tried to add the ascii values of the digits here
for input value 10
for first run
int binaryInt = binary.char(i) ; so binaryInt would get the value = 49(aski value of char '1')
hence result = 49*2 = 98
in second run
result = 98 + 48 *1 = 146
following function will serve your purpose, for input String "1101" , it returns 13
public int getDecimal(String binaryString){
//binaryString = "1101";
int result = 0;
int n = binaryString.length()-1;
for(int i=0;i<binaryString.length();i++)
{
int num = binaryString.charAt(i);
if(num>=48 && num <=57){
result+=(num-48) * Math.pow(2, n) ;
n --;
}
}
return result;
}
}
How about something like this:
// remove everything that is not a digit
String digitsOnly = binary.replaceAll("[^\\d]","");
//iterate over every digit
for(char digit:digitsOnly.toCharArray()) {
int n = Character.getNumericValue(digit);
// do stuff...
}
If you get a string like "10011010", you don't need a tokenizer, you can just iterate over the string and use charAt:
for (int i = 0; i < s.length(); i++) {
char currentDigit = s.charAt(i);
// Do stuff with the digit
}