Can't locate Java substring in for loop - java

I'm trying to make a calculator app and I have a string for the final equation inputted.
"983+388+12"
How I'm solving is by first identifying where the operator is. After this I loop backwards and forwards trying to find the 2 numbers and then I add them. So I would find the plus symbol then 983 and 388 and add them. I'm having trouble matching the previous/next numbers in relation to the add symbol.
public static void main(String[] args)
{
int plus=0;
String string="983+388+12";
//locating Plus symbol
for(int i=0;i<string.length();i++)
{
if(string.charAt(i)=='+')
{
plus=i;
}
}
//locating next number (should be 388)
for(int i=plus+1;i<string.length();i++)
{
if(string.charAt(i)=='+' || string.charAt(i)=='-')
{
String nextNumber=string.substring(plus+1, i-1);
System.out.println(nextNumber);
break;
}
}
I am not getting anything returned as a value for nextNumber

When you find the + in the first loop, you don't stop scanning the string. This results in plus marking the location of the last +, which is after the 388 and before the 12. The second loop never finds a + or a - after the last +, so nothing is ever printed. When you find the first +, break out of the loop.
Also, to avoid just 38 being found, correct your substring call, where the ending index is exclusive.
String nextNumber = string.substring(plus + 1, i);

Try using only one loop, see below (working example). I didn't break anything up into smaller methods.
public static void main(String[] args) {
String string="983+388+12";
String numberStr="0";
int lastSignPos = 0;
int signPos=0;
char sign = '+';
int total=0;
//locating Plus symbol
for(int i=0; i < string.length(); i++) {
if(string.charAt(i)=='+' || string.charAt(i)=='-') {
lastSignPos = signPos;
signPos = i;
numberStr = "0";
if (lastSignPos == 0){
// first number in series
numberStr = string.substring(0,signPos);
} else {
numberStr = string.substring(lastSignPos + 1, signPos);
}
sign = '+';
if (string.charAt(lastSignPos)=='-'){
sign = '-';
}
total += Integer.parseInt(sign + numberStr);
}
}
// take care last number
numberStr = string.substring(signPos+1);
sign = '+';
if (string.charAt(signPos)=='-'){
sign = '-';
}
total += Integer.parseInt(sign + numberStr);
System.out.println(total);
}

You can try something like this :
String example = "123+456+678";
String delim = "+";
StringTokenizer st = new StringTokenizer(example,delim);
while (st.hasMoreElements()) {
System.out.println("StringTokenizer Output: " + st.nextElement());
}

Related

Trying to find the numbers in a line of user input, and then save them to an array stack

For this problem, I am working on finding numbers within a formula (ex. 60 / 30) and save them to a stack. I am currently using the .isDigit method to determine whether a character is a digit or not, and then am checking each character after it to see if it is a multi-digit number or not (ex. 600 or 34). I use a substring method to cut each number from the formula and then a push method obviously to save it into the arraystack. I'm getting index out of bounds errors and don't know where I went wrong. here is the code:
public static void main (String[]args) {
System.out.println("input your formula ");
Scanner scan = new Scanner (System.in);
String input;
input = scan.nextLine();
scan.close();
System.out.println("input: " + input);
ArrayStack st = new ArrayStack();
for(int j = 0; j < input.length(); j++) {
if (Character.isDigit(input.charAt(j))) {
int cur = 0;
while (input.charAt(j + cur) != ' ') {
cur += 1;
String number = input.substring(j,cur);
st.push(number);
break;
}
}
}
while (!st.isEmpty())
{
System.out.println(st.peek());
st.pop();
}
}
}
I tried and expected to get the numbers out of the formula and put them into a stack, then print them out.

Getting java.lang.ArrayIndexOutOfBoundsException, looked, cannot find an example thats the same

I am writing a "tweet checker" code for my AP Computer Science Class. The code is supposed to check that the length of the tweet is within the 140 character limit and, if so, prints the amount of hashtags, #, and links used. I am using the .split method to put all the characters into an array, and then I am accessing the array with for loops to find the specific characters.
I keep encountering a java.lang.ArrayIndexOutOfBoundsException, which I know means that I am trying to access a nonexistent element in my string, such as element 46 for an array of 46 characters, but I do not know what the exact problem is here. I got harped on last time for not "looking hard enough" but I have searched for over 2 hours on only this subject, and I am simply a high school student.
I appreciate all the help.
import java.util.Scanner;
import java.lang.Math;
class Main{
public static void main(String[] args)
{
Scanner scan = new Scanner (System.in);
System.out.println("Please enter a tweet:");
String tweet = scan.nextLine();
int length = tweet.length ();
String[] tweetArray = tweet.split ("");
int c = 0;
int d = 0;
int e = 0;
int i = 0;
if (length > 140)
System.out.println("Excess Characters: " + (length - 140));
else
{
System.out.println("Length Correct");
for (i = 0; i < length; i++)
{
if (tweetArray[i].equals("#"))
{
if(!tweetArray[i+1].equals(" "))
{
c++;
}
}
}
System.out.println("Number of Hastags: " + c);
for (i = 0; i < length; i++)
{
if (tweetArray[i].equals("#"))
{
if(!tweetArray[i+1].equals(" "))
{
d++;
}
}
}
System.out.println("Number of Attributions: " + d);
for (i = 0; i < length; i++)
{
if((tweetArray[i].equals("h")) || (tweetArray[i].equals("H")))
{
if(tweetArray[i+1].equals("t") || tweetArray[i+1].equals("T"))
{
if(tweetArray[i+2].equals("t") || tweetArray[i+2].equals("T"))
{
if(tweetArray[i+3].equals("p") || tweetArray[i+3].equals("P"))
{
if(tweetArray[i+4].equals(":"))
{
if(tweetArray[i+5].equals("/"))
{
if(tweetArray[i+6].equals("/"))
{
if(!tweetArray[i+7].equals(" "))
{
e++;
}
}
}
}
}
}
}
}
}
System.out.println("Number of Links: " + e);
}
}
}
In your for loop, i correctly iterates from 0 to the maximum length. However you have code such as:
tweetArray[i+1]
...
tweetArray[i+7]
that will fail once i reaches (or gets close to) its maximum. That is, you are referencing past the end of the array.
In general, if you need to check something about the next character, you need to check that it exists first (as you only know that the current character exists).
You may wish to review your whole approach though. There does not appear to be any need to split your string into characters. You could instead use string based functions to count the number of # characters or check for the presence of a string (eg. http://). Check out the API.

Inserting dashes between two odd numbers

folks. In my program I take a user input of numbers of a String type and put dashes between two odd numbers. For example:
Input = 99946 Output = 9-9-946
Input = 56730 Output = 567-30
But in my code, if I, for example, write 9933444 then the ouput that I'm getting is: 9-9-9-3-3-3-344444. It correctly separates the odd numbers by dashes but also adds extra numbers. What could be causing this bug ?
import java.util.Arrays;
import java.util.Scanner;
public class DashInsert {
public static void main(String[] args)
{
Scanner kbd = new Scanner(System.in);
System.out.println("Enter the numbers: ");
String myString = kbd.nextLine();
char[] numbers = myString.toCharArray();
String result = "";
for(int i = 1; i < numbers.length; i++)
{
int value1 = Character.getNumericValue(numbers[i]);
int value2 = Character.getNumericValue(numbers[i-1]);
if(value1 % 2 != 0 && value2 % 2 != 0)
{
result += numbers[i-1] + "-" + numbers[i] + "-";
}
else
result += numbers[i-1] + "" + numbers[i];
}
System.out.println(result);
}
}
There is a trivial one-line solution:
str = str.replaceAll("(?<=[13579])(?=[13579])", "-");
This works by matching between odd numbers and replacing the (zero-width) match with a dash. The regex is a look behind and a look ahead.
It can be done without look arounds by capturing the odd digits and putting them back using a back reference:
str = str.replaceAll("([13579])([13579])", "$1-$2");
Both solutions achieve the same result.
The code can be simplified a bit (as well as solve the "double char" bug):
String str = "9933444";
char[] numbers = str.toCharArray();
String result = "";
for(int i = 1; i < numbers.length; i++)
{
int value1 = Character.getNumericValue(numbers[i-1]);
int value2 = Character.getNumericValue(numbers[i]);
result += value1;
if(value1 % 2 != 0 && value2 % 2 != 0) {
result += "-";
}
}
result += numbers[numbers.length - 1];
System.out.println(result);
OUTPUT
9-9-3-3444
The reason for the "double char" bug is that every loop prints both the items on the places i-1 and i. which means that i will be printed again on the next loop (where it will become i-1).
In case you're using Java 8 - you can use a Stream do something that looks more like what you were originally trying to do:
public static void main(String[] args){
String str = "9933444";
List<String> lst = Arrays.asList(str.split(""));
String res = lst.stream().reduce((a,b) -> {
if (isOdd(a) && isOdd(b)) {
return a + "-" + b;
}
else {
return a + b;
}
}).get();
System.out.println(res);
}
// grep the last digit from the string and check if it's odd/even
public static boolean isOdd(String x) {
if (x.length() > 1) {
if (x.substring(x.length()-1).equals("-")) {
x = x.substring(x.length()-3, x.length()-2);
}
else {
x = x.substring(x.length() - 1);
}
}
return Integer.parseInt(x) % 2 == 1;
}
OUTPUT
9-9-3-3444
The bug is caused by the fact that, even though you are looping through your list of numbers one at a time, you write out two numbers with each loop iteration. Logically, this design will always yield repeated numbers.
Either change your loop to iterate by twos, or print a single number in each loop iteration.
Don't bother concatenating two odd numbers with the "-" in between them, during the evaluation, just add the "-" after the number that you're checking in each iteration.
public static void main(String[] args) throws Exception {
Scanner kbd = new Scanner(System.in);
System.out.println("Enter the numbers: ");
String myString = kbd.nextLine();
char[] numbers = myString.toCharArray();
String result = "";
for(int i = 0; i < numbers.length; i++) {
int value1 = Character.getNumericValue(numbers[i]);
int value2 = i + 1 < numbers.length
? Character.getNumericValue(numbers[i + 1])
: 0;
if(value1 % 2 != 0 && value2 % 2 != 0) {
result += numbers[i] + "-";
} else {
result += numbers[i];
}
}
System.out.println(result);
}
Results:
Input: 99946 Output: 9-9-946
Input: 56730 Output: 567-30
Input: 9933444 Output: 9-9-3-3444

binary to base10 in java with main method and TWO classes/method (boolean and

I am a beginner programmer. This is what I have so far. The directions for the question are kind of difficult. Here is what I am trying to accomplish..
You will write a program that converts binary numbers to base 10 numbers. This program will ask the user to enter a binary number. You will have to verify that what is entered by the user only has 0s and 1s. In the case the user entered letters, you have to keep asking the user for another input. When the input is valid, you will convert the binary number to a base 10 number. Please use the Question1.java file provided in the A2.zip file.
Valid input - In order to check if the input is valid your program should call the CheckInputCorrect method, which takes a String as an input parameter and returns a boolean value. An input string is considered valid if it corresponds to a number in binary representation.
More specifically, in the CheckInputCorrect method, you should scan this string to make sure it only contains ‘0’ or ‘1’ characters. As soon as you find a character that is not ‘0’ or ‘1’, the method should returns false. If the method reaches the end of the input string (i.e. all characters are ‘0’ or ‘1’) the method should return true.
Converter - At this point we assume that the input string is valid (checked with the CheckInputCorrect method). To convert the input from binary to base 10, you must implement the BinaryToNumber method. The BinaryToNumber method should take as parameter a String and return an integer, which corresponds to converted value in base 10.
The binary conversion should work as follows. For each digit in the binary number, if the digit is ‘1’ you should add the corresponding decimal value ( 20 for the rightmost digit, 21 for the next digits to the left, 22 for the next one, and so on) to a variable that will hold the final result to be returned. This can be easily accomplished by using a loop.
1) Am I on the right path?
2) I don't exactly know what I am doing and need you to help me figure that out....
Update1:
When I run this vvvv: It says "Please enter a binary number for me to convert: and then a place for me to type in my answer but whatever i put it just returns another box for me to type in but stops and doesn't evaluated anything.
import java.util.Scanner;
public class Question1
{
public static void main(String[] args)
{
System.out.println("Please enter a binary number for me to convert to decimal: ");
Scanner inputKeyboard = new Scanner(System.in);
String inputUser = inputKeyboard.nextLine();
boolean BinaryNumber = false;
String inputString = "";
while (!BinaryNumber){
inputString = inputKeyboard.next();
BinaryNumber = CheckInputCorrect(inputString);
System.out.println("You have given me a " + BinaryNumber + "string of binary numbers.");
}
int finalNumber = BinaryToNumber(inputString);
System.out.println("Congratulations, your binary number is " + finalNumber + ".");
}
public static boolean CheckInputCorrect(String input)
{
for (int i = 0; i < input.length(); i++)
{
while (i < input.length());
if (input.charAt(i) != '0' && input.charAt(i) != '1')
{return false;}
i++;
}
return true;
}
public static int BinaryToNumber(String numberInput)
{
int total = 0;
for (int i = 0; i < numberInput.length(); i++){
if (numberInput.charAt(i)=='1')
{
total += (int)Math.pow(2,numberInput.length() - 1 - i);
}
}
return total;
}
}
Original:
import java.util.Scanner;
public class Question1
{
public static void main(String[] args)
{
int binarynumber;
int arraySize = {0,1};
int[] binaryinput = new int[arraySize];
Scanner input = new Scanner(System.in);
System.out.println("Please enter a binary number");
binarynumber = in.nextInt();
if (binarynumber <0)
{
System.out.println("Error: Not a positive integer");
}
if (CheckInputCorrect) = true;
{
System.out.print(CheckInputCorrect);
}
public static boolean CheckInputCorrect(String input);
{
boolean b = true;
int x, y;
x = 0
y = 1
b = x || y
while (b >= 0 {
System.out.print("Please enter a binary number")
for (int i = 0; i < binarynumber.length; i++)
{
binaryinput[i] = in.nextInt();
if (binaryinput[i] = b.nextInt();
System.out.printl("Binary number is:" + binaryinput);
break outer;
if (binarynumber != b)
{
System.out.println("Error: Not a binary number")
}
return true;
}
}
public static int BinaryToNumber(String numberInput)
{
int remainder;
if (binarynumber <= 1) {
System.out.print(number);
return; // KICK OUT OF THE RECURSION
}
remainder = number %2;
printBinaryform(number >> 1);
System.out.print(remainder);
return 0;
}
}
}
As mentioned in my comments, your updated code contains two errors
while (i < input.length()); is an infinite loop, because it has no body. Therefore i cannot be increased and will stay lower than input.length().
inputString = inputKeyboard.next(); request another input after the first one and the first input will be ignored.
This is a fixed and commented version of your updated code:
public class Question1 {
public static void main(String[] args) {
System.out.println("Please enter a binary number for me to convert to decimal: ");
Scanner inputKeyboard = new Scanner(System.in);
String inputUser = inputKeyboard.nextLine();
//boolean BinaryNumber = false; // not needed anymore
//String inputString = ""; // not needed too
while (!checkInputCorrect(inputUser)) { // there is no reason for using a boolean var here .. directly use the returned value of this method
System.out.println("You have given me an invalid input. Please enter a binary number: "); // changed this message a little bit
inputUser = inputKeyboard.nextLine(); // re-use the "old" variable inputUser here
}
int finalNumber = binaryToNumber(inputUser);
System.out.println("Congratulations, your decimal number is " + finalNumber + ".");
}
public static boolean checkInputCorrect(String input) { // method names should start with a lower case letter
for (int i = 0; i < input.length(); i++) {
//while (i < input.length()); // this loop is deadly. Please think about why
if (input.charAt(i) != '0' && input.charAt(i) != '1') {
return false;
}
//i++; // what is the purpose of this? The "for" loop will increment "i" for you
}
return true;
}
public static int binaryToNumber(String numberInput) { //method name ... lower case letter ;)
int total = 0;
for (int i = 0; i < numberInput.length(); i++) {
if (numberInput.charAt(i) == '1') {
total += (int) Math.pow(2, numberInput.length() - 1 - i);
}
}
return total;
}
}

out of bounds error with word count

I'm trying to write my own Java word count program. I know there may already be a method for this, but I'd like to get it work. I'm getting an out of bounds error at line 14. I'm trying to use an input word to count how many times it appears in an input string. So I'm looping up to stringlength - wordlength, but that's where the problem is.
Here is the code:
import java.util.Scanner;
public class wordcount {
public static void main(String[] args)
{
Scanner s = new Scanner(System.in);
System.out.print( "Enter word : " );
String word = s.nextLine();
Scanner t = new Scanner(System.in);
System.out.print("Enter string: ");
String string = t.nextLine();
int count = 0;
for (int i = 0; i < string.length()-word.length(); i = i+1){
String substring = string.substring(i,i+word.length());
if (match(substring, word)==true){
count += 1;
}
}
System.out.println("There are "+count+ " repetitions of the word "+word);
}
public static boolean match(String string1, String string2){
for (int i=0; i<string1.length(); i+=1){
if (string1.charAt(i)!=string2.charAt(i)){
return false;
}
}
return true;
}
}
First of all, two Scanners are not necessary, you can do many inputs with the same Scanner object.
Also, this if condition
if (match(substring, word) == true)
can be rewritten like
if (math(substring, word))
I would also recommend you to use i++ to increase the loop variable. Is not strictly necessary but is "almost" a convention. You can read more about that here.
Now, about theIndexOutOfBoundsException, I've tested the code and I don't find any input samples to get it.
Besides, there is an issue, you are missing one iteration in the for:
for (int i = 0; i < string.length() - word.length() + 1; i++) { // Add '+ 1'
String substring = string.substring(i, i + word.length());
// System.out.println(substring);
if (match(substring, word)) {
count++;
}
}
You can test it by putting a print statement inside the loop, to print each substring.
I'm not getting an out of bounds error, can you tell me what values you were using for word and string?
I have identified a bug with your program. If word is equal to string, it still returns count 0. I suggest adding one more iteration and using regionMatches instead. RegionMatches makes your match method obsolete and will return false if word.length() + i is equal or greater than string.length(), avoiding out of bounds issues.
As you can see I also moved the calculations to a seperate method, this will make your code more readable and testable.
And as Christian pointed out; you indeed do only need one Scanner object. I've adapted the code below to reflect it.
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.print("Enter word : ");
String word = sc.nextLine();
System.out.print("Enter string: ");
String string = sc.nextLine();
int count = calculateWordCount(word, string);
System.out.println("There are " + count + " repetitions of the word " + word);
}
private static int calculateWordCount(String word, String string) {
int count = 0;
for (int i = 0; i < string.length() - word.length() + 1; i++) {
if (word.regionMatches(0, string, i, word.length())) {
count++;
}
}
return count;
}

Categories

Resources