Java - Natural number counting with various bases - java

I seen this question posted but got stuck and need a bit help to finish. The program is used to count from one number to another using any base the user inputs.
Example: If the user inputs 5 & 10 with a base of 0123456789 it will output
5 6 7 8 9 10
From what I have so far I can enter 5 and get the next number 6. But 9 to 10 does no work and only gives me 0. When i enter 19 i get 20. When i enter 99 i only get 00.
So what i need is to fix 9 to 10 and 99 to 100
static String nextNum(String base, String n) {
int i = n.length() - 1;
char digit = n.charAt(i)
int pos = base.indexOf(digit);
if (pos + 1 < base.length()) {
n = n.substring(0, i) + base.charAt(pos + 1);
} else if (i > 0) {
n = nextNum(base, n.substring(0, i)) + base.charAt(0);
} else if (pos == base.length() - 1) {
n = n.substring(0, i) + base.charAt(0) + n.substring(i + 1);
} else {
n = "" + base.charAt(1) + base.charAt(0);
}
return n;
}
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.print("Please enter base: ");
String base = input.nextLine();
System.out.print("Please enter first number: ");
String n = input.nextLine();
System.out.print("Please enter second number: ");
String m = input.nextLine();
System.out.println(nextNum(base, n));
}

You're almost there, but your thinking got fuzzy around the base case. Assuming that you're working with base 10 and the digits 0123456789, your algorithm so far does this:
(first if) If the last digit is not 9, adds one to the last digit
(first else if) If the last digit is 9 and the length of the string is at least 2, use recursion to add one to the string without the last 9, and append a 0 at the end.
So far, great. If neither of these two is true, there is only one possibility left (assuming the input is valid): the string is "9". Given that there's only one possible string at that point, you shouldn't have another else if; the problem should be much simpler than you made it. I'll let you work out the rest.

I recall having posted a concept of adding 2 numbers represented in strings a little while back. I am adding a simplified version of what I mentioned in that answer. User ajb's remarks are spot on about the approach you were taking. So, I won't repeat the same thing.
static String nextNum(String base, String n) {
// 2 cases
// one requires carry over
if(n.charAt( n.length() - 1 ) == base.charAt( base.length()-1 ) ) {
// note: carry is set to 1
int last = n.length() - 1, carry = 1;
int systemBase = base.charAt(base.length() - 1) - '0';
systemBase++; // equals 10 for base=0123456789
// equals 4 for base=0123
String newString = "";
int curIndx = n.length() - 1;
while(curIndx >= 0) {
int digit = n.charAt(curIndx) - '0';
// add carry over value
digit += carry;
carry = digit / systemBase;
digit = digit % systemBase;
newString = digit + newString;
curIndx--;
}
//if there is something left in carry
if(carry != 0)
newString = carry + newString;
return newString;
}
// no carry over
else {
// just need to add one to last character
// increment last character by 1
int last = n.charAt(n.length() - 1) - '0'; // actual value of last
last++; // increment by 1
return ( n.substring(0, n.length()-1) + last );
}
}
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.print("Please enter base: ");
String base = input.nextLine();
System.out.print("Please enter first number: ");
String n = input.nextLine();
System.out.println(nextNum(base,n));
}
If base = 0123456789, num = 99, then nextNum = 100. If base = 0123456789, num = 9, then nextNum = 10.

Related

(java) convert a decimal number to binary without using parseint

I am new to java and I was learning how to convert from binary to decimal and vice versa. In the case of binary to decimal, I found out that I could use parseint, but I saw other methods that didn't use it, so I tried to implement them into my code, but it didn't work for me and I got stumped.
How would I be able to use a different method for calculating binary to decimal and implement it into my code?
Here is my code:
import java.util.Scanner;
class BinaryToDecimal {
public static void main(String args[]) {
Scanner sc = new Scanner(System.in);
String binaryString;
char choice;
String nextLine = "Empty";
int i = 0;
choice = 'Y';
try {
do {
System.out.print("Enter a binary number: ");
binaryString = sc.nextLine();
//Find the string count
int count = binaryString.length();
for (int j = 0; j< count; j++)
{
if (binaryString.charAt(j) != '1' && binaryString.charAt(j) != '0')
{
System.out.print("Enter a binary number: ");
binaryString = sc.nextLine();
count = binaryString.length();
j=0;
}
}
i = Integer.parseInt(binaryString);
if (i>0)
System.out.println("The decimal number is: " + Integer.parseInt(binaryString, 2));
System.out.println("Continue using the calculator? Only input Y or N");
String ln = sc.next();
if(ln.length()==1){
choice = ln.charAt(0);
}
else{
choice = 'N';
}
if (sc.hasNextLine()) {
nextLine = sc.nextLine();
}
} while (choice == 'Y');
} catch (NumberFormatException nfe) {
System.out.println("Invalid input");
}
}
}
Binary math involves adding 1 and multiplying by 2. I would use a regular expression to test if the input is valid. I would use an infinite loop and break when the user gives an answer besides y when prompted to continue. Putting that together, gives a simplified
Scanner sc = new Scanner(System.in);
while (true) {
System.out.println("Enter a binary number: ");
String binaryString = sc.nextLine();
// An int value consists of up to 32 0 and 1s.
if (!binaryString.matches("[01]+") || binaryString.length() > 32) {
continue;
}
int v = 0;
for (int i = 0; i < binaryString.length(); i++) {
v *= 2;
if (binaryString.charAt(i) == '1') {
v++;
}
}
System.out.println("The decimal number is: " + v);
System.out.println("Continue using the calculator? Only input Y or N");
String ln = sc.nextLine();
if (!ln.equalsIgnoreCase("Y")) {
break;
}
}
It looks like your missing you're missing the radix which the default I use is 2. Try this and let me know what happens
i = Integer.parseInt(binaryString,2);
There may be a nicer way of doing this, however this is the solution that I came up with. I took into account that the number can both be a positive and negative number and added checks for those cases. I also made sure to add exceptions for when an invalid binary number is entered.
public static int numberFromBinary(String binaryNumber) {
char[] array = binaryNumber.toCharArray();
boolean isNegative = false;
int result = 0;
if (array.length > 32) {
throw new NumberFormatException("An integer cannot be more than 32 bits long.");
}
if (array.length == 32) {
isNegative = array[0] == '1';
if (isNegative) {
result -= 1;
}
}
for (int i = 0; i < array.length && i != 31; i++) {
int worth = (int) Math.pow(2, i);
if (array[array.length - 1] != '1' && array[array.length - 1] != '0') {
throw new NumberFormatException("Binary bits can only be a '1' or a '0'.");
}
if (isNegative) {
if (array[array.length - 1] == '0') {
result -= worth;
}
} else {
if (array[array.length - 1] == '1') {
result += worth;
}
}
}
return result;
}
Here's a solution for converting a string representation of a binary number to a decimal number, without using Integer.parseInt(). This is based on
your original question text:
How would I be able to use a different method for calculating binary to decimal and implement it into my code?
And also a comment you added:
Also i did not want to use parseint
If you take a binary number and work your way from right to left, each digit is an increasing power of 2.
0001 = 2^0 = 1
0010 = 2^1 = 2
0100 = 2^2 = 4
1000 = 2^3 = 8
You can follow this same pattern: inspect each character position of a binary string input, and raise 2 to some power to get the decimal value represented by that bit being set to 1. Here's a simple bit of code that:
prompts for user input as a binary string
starting from right and working toward the left, it checks each character, comparing against '1'
if the character is in fact 1: take note of the position, raise 2 to the next power, and add that to the running total
Here's the code:
System.out.print("enter a binary number: ");
String binaryInput = new Scanner(System.in).next();
int decimalResult = 0;
int position = 0;
for (int i = binaryInput.length() - 1; i >= 0; i--) {
if (binaryInput.charAt(i) == '1') {
decimalResult += Math.pow(2, position);
}
position++;
}
System.out.println(binaryInput + " --> " + decimalResult);
And a few sample runs:
enter a binary number: 1111
1111 --> 15
enter a binary number: 101010101
101010101 --> 341
enter a binary number: 100000000000
100000000000 --> 2048

How to grab individual digits from a 4 digit interger

I am trying to create a program where the user inputs a four digit code. I then need to separate the individual digits and apply some basic math separately.
For example user input: 1234
I need to grab numbers 1, 2, 3, 4, apply basic math to them, then return them as output as integers.
This is what I have so far:
public static void main(String[] args) {
int fourDigitPin;
int firstDigit;
int secondDigit;
int thridDigit;
int forthDigit;
Scanner keyInput = new Scanner(System.in);
System.out.print("Enter your 4 digit pin number: ");
fourDigitPin = keyInput.nextInt();
firstDigit = fourDigitPin.charAt(0);
As you can see, I havent gotten to the math portion yet. I am attempting to use charAt to grab the numbers, but cannot as they are integers. Should I set the set input variable "fourDigitPin" as a string or char? Any help would be greatly appreciated.
1st method:
public static void main(String[] args) {
String fourDigitPin;
int firstDigit;
int secondDigit;
int thirdDigit;
int forthDigit;
Scanner keyInput = new Scanner(System.in);
System.out.print("Enter your 4 digit pin number: ");
fourDigitPin = keyInput.next();
firstDigit = fourDigitPin.charAt(0) - '0';
secondDigit = fourDigitPin.charAt(1) - '0';
thirdDigit = fourDigitPin.charAt(2) - '0';
forthDigit = fourDigitPin.charAt(3) - '0';
System.out.println(firstDigit + " " + secondDigit + " " + thirdDigit + " " + forthDigit);
}
2nd method:
public static void main(String[] args) {
String[] fourDigitPin;
int firstDigit;
int secondDigit;
int thirdDigit;
int forthDigit;
Scanner keyInput = new Scanner(System.in);
System.out.print("Enter your 4 digit pin number: ");
fourDigitPin = keyInput.next().split("");
firstDigit = Integer.parseInt(fourDigitPin[0]);
secondDigit = Integer.parseInt(fourDigitPin[1]);
thirdDigit = Integer.parseInt(fourDigitPin[2]);
forthDigit = Integer.parseInt(fourDigitPin[3]);
System.out.println(firstDigit + " " + secondDigit + " " + thirdDigit + " " + forthDigit);
}
3rd method:
public static void main(String[] args) {
int fourDigitPin;
int firstDigit;
int secondDigit;
int thirdDigit;
int forthDigit;
Scanner keyInput = new Scanner(System.in);
System.out.print("Enter your 4 digit pin number: ");
fourDigitPin = keyInput.nextInt();
forthDigit = fourDigitPin % 10;
fourDigitPin /= 10;
thirdDigit = fourDigitPin % 10;
fourDigitPin /= 10;
secondDigit = fourDigitPin % 10;
fourDigitPin /= 10;
firstDigit = fourDigitPin % 10;
fourDigitPin /= 10;
System.out.println(firstDigit + " " + secondDigit + " " + thirdDigit + " " + forthDigit);
}
You should convert it to a string because you're expecting it to be four characters (not one).
Also, minor UI point: right now you don't verify that the user actually entered a four-digit number. You should do so before you get the individual digits so that you don't get an exception.
One more thing to be careful of: make sure that you don't "directly" cast the char back to an integer at any point because then it'll be cast to the equivalent ASCII value (not the actual value of the number).
Take the input as a String rather than an int.
String number = keyInput.next();
Then
firstDigit = number.charAt(0);
secondDigit = number.charAt(1);
thirdDigit = number.charAt(2);
fourDigit = number.charAt(3);
For this, you would have to use as many variables as individual digits.
Or you can use a loop.
for(int i=0;i<number.length();i++){
digit = number.charAt(i);
//More code
}
But a better soln would be to take modulo.
int n = keyInput.nextLine();
while(n>0){
lastDigit=n%10;
n/=10;
} //you get digits from the rear end as modulo returns remainder
You better use "modulo" operator approach to get individual digit and then perform math on that digit. This operator will give you reminder.
Example:
int remainder = a % b;
Refer javadoc operators for more details.
Other approaches like charAt might work in this case, because you know the pin is of size 4, but if the size is not known upfront and want to use your code for 5 digits or 3 digits, it will fail.
final char[] chars = String.valueOf(fourDigitPin).toCharArray();
int firstDigit = Integer.parseInt(String.valueOf(chars[0]));
int secondDigit= Integer.parseInt(String.valueOf(chars[1]));
int thridDigit=Integer.parseInt(String.valueOf(chars[2]));
int forthDigit= Integer.parseInt(String.valueOf(chars[3]));
tl;dr
String
.valueOf( 1_234 ) // Convert `int` to `String`.
.codePoints() // `IntStream` of Unicode code points, one integer for each character.
.filter( Character :: isDigit ) // Remove any non-digit.
.mapToObj( Character :: toString ) // Convert code point back to character of that digit.
.map( Integer :: valueOf ) // Parse that textual digit back to an integer. In this case, an `Integer` object.
.toList() // Make a list of our `Integer` objects, each element being a single digit from our original number.
.toString()
[1, 2, 3, 4]
Code points
The char type in Java is legacy, and is essentially broken. As a 16-bit value, it cannot represent most characters.
Instead, use code point integer numbers.
Convert your int to a String.
String inputString = String.valueOf( inputInt ) ;
Verify the length.
if( inputString.length() != 4 ) { … }
Get an IntStream of code point numbers.
IntStream codePoints = inputString.codePoints() ;
Loop those code point numbers, verifying it is a digit. If so, get the character. Convert that character to an int. Add it to our collection of integers.
List< Integer > digits =
codePoints
.filter( Character :: isDigit )
.mapToObj( Character :: toString )
.map( Integer :: valueOf )
.collect( Collectors.toList() ) // In Java 16+, replace with .toList()
;
See this code run live at IdeOne.com.
[1, 2, 3, 4]
It will be easy to improve your code's robustness by reading a string and testing its worthiness for further processing. Additionally, it will probably be easier to read your code if you store the digits in an array instead of enumerating each digit in a separate variable name. One indication that an array is more appealing is the fact that you have fewer variable names to misspell. You misspelled "third" as "thrid". Another is the fact that you have fewer parameters to pass if you have to pass parameters to some function. Yet another benefit is "rectangularization", which I'll define (redefine?) as being vertically aligned so as to spot typos more easily.
import java.util.Scanner;
public class Test {
public static void main(String[] args) {
int digit[] = new int[4];
Scanner keyInput = new Scanner(System.in);
String pinstr;
do {
System.out.print("Enter your 4 digit pin number: ");
pinstr = keyInput.next();
if (pinstr.matches("^[0-9]{4}$"))
break;
System.err.println("You did not enter precisely 4 decimal digits");
} while (true);
digit[0] = pinstr.charAt(0) - '0';
digit[1] = pinstr.charAt(1) - '0';
digit[2] = pinstr.charAt(2) - '0';
digit[3] = pinstr.charAt(3) - '0';
for (int i=0; i<4; i++)
System.out.println(String.format("Digit at offset %d is %d", i, digit[i]));
}
}

The sum of all odd digits of an input [duplicate]

This question already has answers here:
How do I find the sum of all odd digits of user input numeric string?
(5 answers)
Closed 2 years ago.
How to compute the sum of all 'odd digits of an input' using 'loop'. (For example, if the input is 32677, the sum would be 3 + 7 + 7 = 17.)
I can't quite figure out how to do that, can someone please help me out. This is what I have done so far, I don't know how to complete it or whether I have its right or wrong.
Any help would be appreciated!
System.out.println("Enter a number: ");
String input = in.nextLine();
int length = input.length();
int sum = 0;
int digits = 0;
for (int i = 0; i < length; i++) {
if (length % 2 == 1) {
digits += i;
sum = digits++;
}
}
System.out.println(sum);
Here comes a Java8-based solution:
final int result = input.chars()//make a stream of chars from string
.mapToObj(String::valueOf) // make every character a String to be able to use parseInt later
.mapToInt(Integer::parseInt) // transform character in int
.filter(i -> i % 2 == 1) // filter out even numbers
.sum();
You don't need to use String if your input is not so long.
also for safe side use long datatype.
Here is the working code with comments (explain each step).
long sumOddDigits(long value){
long temp = value; // copy in temp variable
long sum = 0;
while(temp > 0){
int digit = temp%10; // get last digit of number. example: 227 gives 7.
temp = temp / 10; // remove that last digit from number.227 will be 22.
if(digit % 2 == 1){
sum += digit;
}
}
return sum;
}
Your interpretation of the digits inside of input is not working this way.
System.out.println("Enter a number: ");
String input = in.nextLine();
int length = input.length();
int sum = 0;
for (int i = 0; i < length; i++) {
int digit = input.charAt(i) - '0';
if (digit % 2 == 1) {
System.out.println("Add digit: " + digit);
sum += digit;
}
}
System.out.println(sum);
In your loop, use Integer.parseInt(input.charAt(i)) to get the number at position i.
if(length%2==1){ that doesn't make sense here. You want to check if your number is odd, not the length of your string.

Adding individual digits from a string

I'm trying to add 13 individual digits from a string together. I thought using a while loop would be the best way to do this, but I think I messed something up. Here's my code:
import java.util.Scanner;
public class ISBNChecker{
public static void main(String [] args){
String isbnNumber;
int isbnTotal= 0;
int index = 0;
Scanner scnr = new Scanner(System.in);
System.out.println("Enter a 13 digit ISBN Number:");
isbnNumber = scnr.nextLine();
if (isbnNumber.length() != 13) {
System.out.println("Error- 13 numerical digits required");
}
char num = isbnNumber.charAt(index);
while (index <13) {
if (index % 2 == 0) {
isbnTotal = isbnTotal + num;
index =index + 1;
}
else {
isbnTotal = isbnTotal + (3 * num);
index = index + 1;
}
}
System.out.println(isbnTotal);
if (isbnTotal % 10 == 0) {
System.out.println("Valid ISBN Number");
}
else {
System.out.println("Invalid ISBN Number");
}
}
}
I'm using the input 9780306406157, which should be an invalid ISBN Number. The value of isbnTotal at the end of the program should be 100, but instead, it is 1425. Any help in figuring out how to fix it would be appreciated.
Also, the formula I'm using for the problem is x1 + 3x2 + x3 + 3x4 ... +x 13 for reference!
I found your bug, you made some mistake.
int index = 0;
while (index < 13) {
char num = (char) (isbnNumber.charAt(index) - '0');
if (index % 2 == 0) {
isbnTotal = isbnTotal + num;
} else {
isbnTotal = isbnTotal + (3 * num);
}
index++;
}
Problem #1
The code
char num = isbnNumber.charAt(index);
Was not in your while loop, causing your code to always run with the same character.
Problem #2
When doing
char num = isbnNumber.charAt(index);
You are actually getting the ASCII value of the character. What you cant to get is the value of the number right ? So you have to do:
char num = (char) (isbnNumber.charAt(index) - '0');
Notice that the zero is between two single quote, that because we want the value of the ZERO ASCII CHARACTER (which is 38).
'1' - '0' = 1
'9' - '0' = 9
EDIT: I forgot to mention that you should check before if the character is a number, else you will maybe try to do something like 'A' - '0' which will be equal to 17
Here is a detailed working code for your ISBN checker
import java.util.Scanner;
public class ISBNChecker{
public static void main(String [] args){
String isbnNumber;
int isbnTotal= 0;
int index = 0;
Scanner scnr = new Scanner(System.in);
System.out.println("Enter a 13 digit ISBN Number:");
isbnNumber = scnr.nextLine();
if (isbnNumber.length() != 13) {
System.out.println("Error- 13 numerical digits required");
}
//Perform other operations if it's length is 13
else{
//initiliizing num for 1st time + convert the character at index to
number
int num = Character.getNumericValue(isbnNumber.charAt(index));
while (index <13) {
if (index % 2 == 0) isbnTotal = isbnTotal + num;
else isbnTotal = isbnTotal + (3 * num);
//increment outside of if else - less code
index = index + 1;
//verify if index is not out of bounds for charAt()
//then change num value + conversion
if(index<13 )
num = Character.getNumericValue(isbnNumber.charAt(index));
}
System.out.println(isbnTotal);
if (isbnTotal % 10 == 0) System.out.println("Valid ISBN Number");
else System.out.println("Invalid ISBN Number");
}
}
}
As mentioned in the answer below, nextLine() gets input in ASCII characters and it is important to convert that into numbers when there are numerical calculations involved.
Well, it seems that you do allow string inputs longer or shorter than 13.
Then you should return after this line:-
System.out.println("Error- 13 numerical digits required");
Otherwise, the code will run even if it's not at the wanted length

Java - How to check if a 13 digit isbn number is valid

I need to write a program that allows the user to enter a 13-digit ISBN as a single integer.
The program should then determine and show whether the number is valid according to the formula above. It also needs to print an error message if the user tries to enter a number longer than 13 digits.
Below is the code I am working on.
I'm new to java and I don't understand where it went wrong. I also don't seem to figure out how to get the length of a long variable.
import java.util.Scanner;
public class ISBNChecker{
public static void main(String [] args){
long isbnNumber;
long isbnTotal;
long x;
Scanner scnr = new Scanner(System.in);
isbnNumber = scnr.nextLong();
while (isbnNumber > 0) {
x = isbnNumber % 10;
isbnTotal = total + x;
isbnNumber = isbnNumber / 10;
x = isbnNumber % 10;
isbnTotal = total + (3 * x);
isbnNumber = isbnNumber / 10;
}
if (isbnTotal % 10 = 0) {
System.out.println("Number is valid!");
}
else {
System.out.println("Number is invalid.");
}
}
}
Fix your (own) current code
In your original code, you have a couple of tiny errors:
isbnTotal = total + x;
total is not declared anywhere, and isbnTotal is not initialized.
if (isbnTotal % 10 = 0) {
You need to compare with double =, a single one is for assignation, double == is for comparison.
Separate your code into modules to improve it
... determine and show whether the number is valid according to the formula above.
I think that you forgot to write the formula, but according to Wikipedia, is this one:
So, you need to check if the sum of all digits multiplied by their weight (alternating 1 and 3) is a multiple of 10.
So, first of all we need to get the sum of all digits and multiply each digit by 1 or 3 alternating (backwards as we're gonna be using the modulo operator).
So, we need something like this:
private static int getSum(long isbn) {
int count = 0;
int sum = 0;
do {
sum += count % 2 == 0 ? isbn % 10 : 3 * (isbn % 10);
count++;
isbn /= 10;
} while (isbn > 0);
return sum;
}
Let me explain what the above code does, is make use of the ternary operator (CTRL-F on the page to read about it), to determine if we need to multiply by 1 or 3, in the formula it starts with 1, so the easiest way to do it is by checking if the current index is even or odd, if even, multiply by 1, otherwise multiply by 3, and adds that number to the sum.
Then it divides the current number by 10.
Then all we have to do is check if the sum of all digits multiplied by their respective weights is a multiple of 10.
private static boolean isAValidISBN(long isbn) {
return getSum(isbn) % 10 == 0;
}
And just before that, if the given number doesn't have 13 digits, we say that it isn't.
So, in the end our program should be something like:
public class ISBNChecker {
public static void main(String[] args) {
String isbnNumber = "978030640615";
if (isbnNumber.length() != 13) {
System.out.println("ISBN Number is invalid");
return;
}
if (isAValidISBN(Long.parseLong(isbnNumber))) {
System.out.println(isbnNumber + " is a valid ISBN");
} else {
System.out.println(isbnNumber + " is not a valid ISBN");
}
}
private static int getSum(long isbn) {
int count = 0;
int sum = 0;
do {
sum += count % 2 == 0 ? isbn % 10 : 3 * (isbn % 10);
count++;
isbn /= 10;
} while (isbn > 0);
return sum;
}
private static boolean isAValidISBN(long isbn) {
return getSum(isbn) % 10 == 0;
}
}
And if we take the Wikipedia value, we get this output:
9780306406157 is a valid ISBN
I don't understand your question clearly, but I suppose what you want to do is validate if the number provided by the user has 13 digits or not, you could do this:
public static void main(String[] args) {
String userNumber;
Scanner scnr = new Scanner(System.in);
System.out.println("Enter ISBN number, 13 digit");
userNumber = scnr.nextLine();
/*regular expression to verify that it contains only 13 digits*/
if(userNumber.matches("^[0-9]{13}$")) {
System.out.println("Number is valid");
} else {
System.out.println("Number is invalid");
}
}
First of all, what do you mean with:
according to the formula above.
What formula do you mean? And Second, to get the length of an long or integer just do:
int length = ("" + isbnNumber).length()
And btw, when you are doing an if statement do "==" instead of "=".
if (isbnTotal % 10 = 0) {
…should be:
if (isbnTotal % 10 == 0) {
Or better, reverse so compiler would have caught your typo.
if (0 == isbnTotal % 10) {

Categories

Resources