What's the best method of finding integers in a string? - java

Hello StackOverflow community! I'm student trying to solve this problem....
The main issue I am having with it is that I dont know the best way to find characters that are valid integers in Strings.
Note: I am only 1 month into learning Java, and I spent most of last year learning python. So compiler languages are new to me.
Write a program that reads in a product code and outputs whether it is valid or not based on some simple rules.
The rules:
1st part can contain only capital letters and 6 digits. 2nd part is alldigits and = the product of the first 6 digits taken in groups of two from the left.
eg: AX6BYU56UX6CV6BNT7NM 287430
is valid because 65*66*67 = 287430
This is what I have so far
import java.util.*; //import java utilities
public class Basic5{ //declares my class
public static void main(String[]args){
Scanner kb=new Scanner(System.in);//creates Scanner for user input
String userentry=kb.nextLine(); //Takes users input as a string
String result="Valid"; //Variable for if the code is Valid
int DoubleCounter=0; //Counter for number of ints
double newdouble;
List<Double> NumberList = new ArrayList<Double>(); //Creates Array List for tracking Doubles
for(int i=0;i<userentry.length();i++){ //checks length of Users input
if(Character.isLowerCase(userentry.codePointAt(i))){ //checks if its a Lowercase letter
result="Fail"; //Changes result variable
if(Integer.parseInt(userentry,i)){ //checks if character from input is a valid integer
DoubleCounter+=1; //Adds to DoubleCounter
newdouble=userentry.charAt(i); //Isolates character
NumberList.add(newdouble); //Adds it to List of doubles
}
}
}
}
}

You can use following methods to check whether the input is a char or digit :
Character.isDigit('A');
Character.isLetter('A');

Here's one way to do it:
#Test
public void testExample() {
assertTrue(isValid("AX6BYU56UX6CV6BNT7NM 287430"));
assertFalse(isValid("AX6BYU56UX6CV6BNT7NM 287431"));
}
private boolean isValid(String s) {
String[] parts = s.split(" ");
int[] ints = extractIntegers(parts[0]);
int target = Integer.parseInt(parts[1]);
return product(ints) == target;
}
private int[] extractIntegers(String s) {
String digits = s.replaceAll("\\D+", "");
int[] ints = new int[digits.length() / 2];
for (int i = 0; i < digits.length(); i += 2) {
ints[i / 2] = Integer.parseInt(digits.substring(i, i + 2));
}
return ints;
}
private int product(int[] ints) {
int result = 1;
for (int num : ints) {
result *= num;
}
return result;
}
It assumes that there are non-zero even number of digits in the first part of the string. If you need to handle other cases, it should be easy to do, based on this.

String str = "AX6BYU56UX6CV6BNT7NM 287430";
str = str.replaceAll("[^0-9]+", "");

Related

How does recursion work and how can recursion be used to manipulate integer digits?

I'm trying to learn java, and I can't seem to understand recursion. I can understand how recursion can be used to add and do other basic math operations but how can recursion be used to reverse manipulate integers and individual integer digits.
example:
a method takes a single positive integer argument and displays its base five equivalent. 231 returns 1411 but the code below returns 1141. how would I reverse the order of integers put out?
public void base5(int n){
int rem=n%5;
int vis=n/5;
if(n!=0){
// System.out.print(rem/*+"|"*/);
//
// rem=(rem+rem)*10;
// System.out.print("\n||"+n+"||\n");
System.out.print(rem);
base5(vis);
}
else{
return;
}
}
The algorithm for getting individual digits of an integer, from right to left, is well known. See How to get the separate digits of an int number?.
I won't "explain" recursion, but I'll give you one possible solution for first problem:
a method takes a single positive integer and displays it with commas
inserted every three digits
import java.util.Scanner;
class Main {
public static void main( String [] args) {
Scanner sc = new Scanner(System.in);
System.out.print("Enter your positive integer: ");
long number = sc.nextLong();
String result = addCommas(number);
System.out.println(result);
}
public static String addCommas(long num) {
return addCommas(num, 1);
}
public static String addCommas(long num, int counter) {
if (num == 0) {
return ""; // base case ends recursion
}
else {
long digit = num % 10;
num = num / 10;
String comma = (counter%3==0 && num>0) ? "," : "";
// recursive call below because we call addCommas() again
return addCommas(num, counter+1) + comma + digit;
}
}
}
Here's a compact solution to the second problem:
a method takes a single positive integer and displays the result of
reversing its digits
public static String reverseDigits(long num) {
if (num == 0) {
return "";
}
else {
return String.valueOf(num % 10) + reverseDigits(num / 10);
}
}

How to multiply different indexes by different values?

I am creating a scrabble game, where the characters get the same values as scrabble,(q & z =10),(k=5), etc, and the main issue that I am having is that I am asking the user to input 2 ints after the word, the first being the index of the bonus tile, and the second being the multiplier to multiply the word with. The value without the multiplier is correct, but the multiplier is not working.
public class Main {
public static void main(String[] args) {
Scanner kb = new Scanner(System.in);
String word = kb.next();
int bonusI = kb.nextInt();
int bonusMult = kb.nextInt();
int score=0;
for (int i=0; i<word.length();i++){
int letterScore;
String letter=word.substring(i,i+1);
if (letter.equals("d")||letter.equals("g")){
letterScore=2;
}
else if (letter.equals("k")) {
letterScore=5;
}
else if (letter.equals("j")||letter.equals("x")){
letterScore=8;
}
else if (letter.equals("q")||letter.equals("z")) {
letterScore=10;
}
else {
letterScore=1;
}
for (int j=0;j<1;j++){
if (word.substring(i,i+1).equals(bonusI)){
letterScore*=bonusMult;
}
}
score+=letterScore;
}
System.out.println(score);
}
}
For example, if the input is dog 2 3 then the correct output would be 9,(d is 2 points,o according to scrabble is 1 point, and g is 2 points, but since the 1st int inputted was 2, and g has an index of 2, it is then multiplied by the bonus of 3, which makes g=6, adding them 2+1+6=9) but instead my output is 5 because the multiplier for g is not working.
Looks like you have a mistake here.
word.substring(i,i+1).equals(bonusI)
word.substring(i,i+1) is String and gives one letter
bonusI is an int and tives one number
This will never be true
if (word.substring(i,i+1).equals(bonusI)) - This condition will be always false as you can't compare a string with int value.
Instead you can just replace the internal for loop with below code
if (bonusI == i)
{
letterScore*=bonusMult;
}

How do I convert a String into doubles to compute average in Java?

I need help with an assignment. There are many similar questions on here, but those answers are not working for me so I don't know what I'm doing wrong.
The assignment is "The program prompts the user for five to ten numbers, all on one line, and separated by spaces. Then the program calculates the average of those numbers, and displays the numbers and their average to the user."
We need to call to different methods to do this. The part that's giving me problems is converting the String to doubles and finding the average. We also need to validate that there are between 5-10 numbers in the String (I can validate it once I get it to count properly). I've tried a few things, including answers to similar questions on here (shown in code below), but the only output I get is 0.0.
Here is my code:
public static void main(String[] args) {
String getNumbers = "";
double calcAverage = 0;
getNumbers();
calcAverage(getNumbers);
System.out.println(calcAverage);
}
public static String getNumbers() {
Scanner scnr = new Scanner(System.in);
System.out.println("Please enter 5 to 10 numbers separated by spaces: ");
String getNumbers = scnr.next();
return getNumbers;
}
public static double calcAverage(String userNumbers){
double calcAverage = 0.0;
double i = 0;
double count = 0.0;
Scanner str = new Scanner(userNumbers);
while (str.hasNextDouble()){
count++;
i = i + str.nextDouble();
}
System.out.println("count=" + count); //test to check it is counting properly
calcAverage = i/count;
return calcAverage;
}
Thank you so much for any help!
It seems you have an error in your main method and need to set the getNumbers equal to the getNumbers method and the same with the calcaverage double with the calcaverage method.
public static void main(String[] args) {
String getNumbers = "";
double calcAverage = 0;
getNumbers();
calcAverage(getNumbers);
System.out.println(calcAverage);
}
should be
public static void main(String[] args) {
String getNumbers = "";
double calcAverage = 0;
getNumbers =getNumbers();
calcAverage =calcAverage(getNumbers);
System.out.println(calcAverage);
}
You can use streams to make it more readable and avoid and external iterations
import static java.util.Arrays.stream;
import java.util.OptionalDouble;
class Scratch {
public static void main(String[] args) {
OptionalDouble optAvg = calcAverage("2 5 6 7 8 9 0 1");
if (optAvg.isPresent()) {
System.out.println("optAvg.getAsDouble() = " + optAvg.getAsDouble());
}
}
public static OptionalDouble calcAverage(String userNumbers) {
String[] inputArr = userNumbers.split(" ");
int count = inputArr.length;
System.out.println("count = " + count);
if (count < 5 || count > 10) {
throw new IllegalArgumentException("Or do some other this here!");
}
return stream(inputArr)
.mapToDouble(
Double::parseDouble) // throws a NumberFormatException if it can't convert to Double
.average();
}
}
Or even simpler
import static java.util.Arrays.stream;
import java.util.DoubleSummaryStatistics;
class Scratch {
public static void main(String[] args) {
DoubleSummaryStatistics doubleSummaryStatistics = calcAverage("2 5 6 7 8 9 0 1");
System.out.println("count = " + doubleSummaryStatistics.getCount());
System.out.println("average = " + doubleSummaryStatistics.getAverage());
}
public static DoubleSummaryStatistics calcAverage(String userNumbers) {
return stream(userNumbers.split(" "))
.mapToDouble(Double::parseDouble)
.summaryStatistics();
}
}
Here you go:
public static void main(String[] args) {
String numberString = getNumbers();
double averageNum = calcAverage(numberString);
System.out.println(averageNum);
}
public static String getNumbers() {
Scanner scnr = new Scanner(System.in);
System.out.println("Please enter 5 to 10 numbers separated by spaces: ");
String getNumbers = scnr.nextLine();
return getNumbers;
}
public static double calcAverage(String userNumbers){
double calcAverage = 0.0;
double i = 0;
double count = 0.0;
Scanner str = new Scanner(userNumbers);
while (str.hasNextDouble()){
count++;
i = i + str.nextDouble();
}
System.out.println("count=" + count); //test to check it is counting properly
calcAverage = i/count;
return calcAverage;
}
A few changes, but you had it right for the most part. Going from the top of the file:
Removed getNumbers and calcAverage
Added numberString and averageNum (when you call functions with return, you need to store the value that it returns into a variable)
changed line:
String getNumbers = scnr.next();
to:
String getNumbers = scnr.nextLine();
Let me know if you have any questions.
Here is one way to do it with supplied values validation :
public static double calcAverage(String userNumbers) {
double calcAverage = 0.0;
double i = 0;
int count = 0;
Scanner str = new Scanner(userNumbers.trim().replaceAll("\\s+", " "));
while (str.hasNext()) {
String val = str.next();
// Is the supplied numerical value valid?
if (!val.matches("-?\\d+(\\.\\d+)?")) {
//No...
System.out.println("Supplied value of " + val +
" is ignored since it is not a valid numerical value!");
continue;
}
count++; // count now that we know the value is indeed valid.
i += Double.parseDouble(val);
}
System.out.println("count=" + count); //test to check it is counting properly
calcAverage = i / count;
return calcAverage;
}
Since you are processing a supplied whitespace delimited string of hopefully numerical values you can merely utilize the the Scanner#hasNext() method in conjunction with the Scanner#next() method.
Preparing the Scanner object:
Scanner str = new Scanner(userNumbers.trim().replaceAll("\\s+", " "));
Here we take the string contained within the supplied userNumbers string variable and trim off any possible leading and trailing white-spaces, we don't want these if there are any. We also replace any portion of the supplied string that may contain more than a single whitespace with just a single whitespace. We want to enforce this format before we proceed so as to help with eliminating any possible type of conflict later on in method code. You can't always rely on the User to provide everything perfectly all the time so if you can help then it's worth it.
Retrieving each supplied value from the supplied String:
while (str.hasNext()) {
String val = str.next();
// ... other code ...
}
The hasNext() method will allow the loop to continue for as long as there is another whitespace delimited string token to process. In this case we're hoping that each token will be a string representation of a numerical value.
Because the hasNext() method has let us get this far into the loop we know there is another String token available. The str.next() call retrieves that available token and in this case, is placing that string token into the string variable named val. This is done upon each iteration of the while loop until there are no more tokens remaining to process.
Validating a retrieved string token:
if (!val.matches("-?\\d+(\\.\\d+)?")) { ... }
Validation of each string token is done here utilizing the String#matches() method along with a specific Regular Expression (regex) of "-?\\d+(\\.\\d+)?". When passed in the matches() method, this regex checks to see if the string it is played against is indeed a string representation of a signed or unsigned integer or floating point numerical value:
-? Optional. Value is prefixed with '-'.
\\d+ One or more digits.
(\\.\\d+)? Optional. Value is post-fixed with a decimal point
and one or more digits.
In this case we're checking to see if the token is invalid and if it is we supply a message to the console window indicating as such and the fact that this token value will be ignored. We ignore it by using the continue keyword which forces the while loop into it's next iteration and bypassing the remaining code within the loop.
Converting a String numerical value to a Double data type:
count++; // count now that we know the value is indeed valid.
i+= Double.parseDouble(val);
We do the count after knowing the value provided is indeed valid. i was previously declared as a double type and sums the token numerical value after it is converted to double with the Double.parseDouble() method. Using i += is the very same as i = i +.
Another shorter way:
public static double calcAverage(String userNumbers) {
double calcAverage = 0.0;
double i = 0;
int count = 0;
Scanner str = new Scanner(userNumbers.trim().replaceAll("\\s+", " "));
while (str.hasNextDouble()) {
double val = str.nextDouble();
count++;
i+= val;
}
System.out.println("count=" + count); //test to check it is counting properly
calcAverage = i / count;
return calcAverage;
}

how do you split a string of numbers into separate integers and use those in a loop? (java)

i have a project wherein i have to create multiple classes that form the image of each (ex: Digit0, Digit1,...,Digit9) with a small and a large size. there are 10 different classes so i'll just simplify to what's important. (for example class Digit1 contains a print function that outputs a small number 1 or a big number 1). i have no problem creating the classes for these digits, where i'm stuck is in figuring out the tester program.
the tester program should allow the user to input a number (ex: 1, 25, 4354435454 etc.) and input a size (1 for small, and 2 for large) and print out the desired images. so far i have this code and it works but it only allows single digit numbers
import java.util.Scanner;
public class DigitDisplay
{
public static void main (String[] args)
{
Scanner scan = new Scanner(System.in);
int digits = scan.nextInt();
int segmentSize = scan.nextInt();
while ((digits!=0)&&(segmentSize!=0)) //terminates when 0 0 is input
{
if (digits==0)
{
if (segmentSize==1) //this is the small size
{
Digit0 small = new Digit0(1);
//this references the small sized 0 created as a method in class Digit0
System.out.println(small.toString());
//this prints the small digit 0
}
else //this is the large size
{
Digit0 big = new Digit0(2);
System.out.println(big.toString());
}
}
//...the other digits are placed as else ifs
}
}
}
i tried altering the scanner objects so that it takes in String digits instead of int digits. so that i could simply split it and use a for loop to go through each character of the string, but i can't seem to get it to work. i really hope i made sense here. i'm a beginner and would really appreciate the help
import java.util.Scanner;
public class DigitDisplay
{
public static void main (String[] args)
{
Scanner scan = new Scanner (System.in);
String digits = scan.next(); //takes in a string of numbers
digits.split(" "); //splits the string into its digits
//int segmentSize = scan.nextInt(); commenting this out because it works. just need to focus on the
digits themselves
while ((!digits.equals("0")) && (segmentSize!=0)) //terminates when input is 0 0
{
for (int i=0; i<digits.length(); i++) //goes through all digits of string
{
int num = digits.charAt(i);
switch (num)
{
case 0:
System.out.println("zero"); //there is a longer code referencing the two sizes but the sizes work but i simplified it again. this is just for me to know whether it is printing the right thing
break;
default:
System.out.println("other"); //these are the other digits, but i just condensed them together just to see if its printing right
break;
}
}
digits = scan.next();
digits.split(" ");
//segmentSize = scan.nextInt();
}
}
}
when i input 002, i want to ouput:
zero
zero
other
but instead, it just outputs "other" for all three.
Looking at the question, I think this is what you're looking for:
Scanner scan = new Scanner (System.in);
String digits = scan.nextLine(); //takes in a string of numbers.
int[] digits_split = new int[0]; //creates an int array to store split digits.
digits_split = digits.split(" "); //splits the string into the digits_split array.
By creating an int array it's now easier to validate the digits.
now you can use this loop to check your split digits:
note below is Pseudo Code and has not been tested...
for(int i = 1; i <= digits.length; i++)
{
if(digits_split[i]=0)
{
System.out.println("zero");
}
else
{
System.out.println("other");
}
}
Also ensure that when entering your digits you put a space in between each one so when the program requests for digits you type: 0 0 2
EDIT:
If your digits contain commas use:
digits = digits.replace(",","");
Also once you've split the string use trim:
digits = digits.trim();
It tidy's things up a little.
ALSO:
when i input 002, i want to ouput:
You need to input: (0[space]0[space]2) to get the output you want. As you're splitting on a " ". Otherwise use a symbol.
Hope this helps,
Rob.

Trying to write a simple compiler in java (I am using notepad++)

My question is how would I write a simple compiler ,that is like the compilers used in fax machines, that would convert something like aaaavvvvvddddddddddd to 4a5vBd.
Also, I get to "Assume" that any string entered will not contain uppercase letters and no numbers, and that any string will contain less than 61 of any type of character so, I get to assume no one will put in 64 continues a's in my program.
This is as far as I gotten
import java.util.*;
public class Program4
{
public static void main(String[] args)
{
Scanner scan = new Scanner(System.in);
int n;
char cn;
String word;
String numChars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
System.out.println("Hello, please enter a string");
word = scan.nextln();
if(n <= 61)
{
int n = ?;
cn = numChars.charAt(n);
}
}
}
I assume I need to use a loop, but I don't know what I should use to count the repeating letters and then tell how many letters of that type are in a row. Now I am only asking for advice and not so much for code, because I want to do it but, as a beginner my Java "Vocabulary" isn't very big right now.
Any advice/ tips would be greatly appreciated.
Sincerely,
Mr.Trips
Well I am back and it appears my code here likes to only print out 147. No matter what I type in I will always get 147. I have tried to hand trace all my variables, but when I do it I get exactly what I want, and I must have some error in my logic. Any thoughts?
import java.util.*;
public class Program4
{
public static void main(String[] args)
{
Scanner scan = new Scanner(System.in);
int n = 0;
int s = 0;
char a;
char b;
char c;
String word;
String numChars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
System.out.println("Please enter a string");
word = scan.nextLine();
while (n < word.length())
{
a = word.charAt(n);
b = a;
n = n ++;
a = word.charAt(n);
if (a == b)
{
s = (s + 1) ;
}
else if (a != b);
{
c = numChars.charAt(s);
System.out.print(b + c);
s = 0;
c = 0;
break;
}
}
}
}
Thank you again!
Since you don't want code this is logically how to do it. You are right you should loop through the string for each char. Store the last char in a variable and keep a counter variable. Compare current char to last char if it is equal then increment the counter. As soon as it is not equal to the last char then add counter + last char to result string and reset counter variable. Each iteration update last char variable.

Categories