keep leading zeros only while reversing a number in java - java

I am doing my assignment question which is to "reverse a number keep the leading zeros and remove the trailing zeros also keep the sign as it is".
If I reverse it taking as a integer, it will remove leading as well as trailing zeros and if I reverse it taking as a string, it will keep all the zeros.
Can anyone help me only keeping the leading zeros.
For example "-00360" should be "-6300".
problem-
Write a Java function to accept a number and return the reverse of the same. If the number ends with one or more zeros, then in the reversed number those zeros will not be present (since those zeros become leading zeros). If the input number is negative, the sign should be retained. ##Examples Input: -123 Output: -321 Input: 1123400 Output: 43211

In below codes, you can reverse the negative and positive numbers. On method reversedString(String num), you can reverse your numbers. String reverseNumKeeper() helps you to keep your new reversed number. With using for loop, you reverse the number, 123 => 321. Then, you should check if the new reversed String has a negative sign, if has, you should add it in front of number, else, just return new reversed number.
import java.util.Scanner;
public class Reverse {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("Enter number");
//input
String number = scanner.next();
System.out.println(Reverse.reversedString(number));
}
private static String reversedString(String num) {
String reverseNumKeeper = "";
//reverse number with and without negative sign
for (int i = num.length(); i > 0; i--) {
reverseNumKeeper += num.charAt(i - 1);
}
//check if reverseNumKeeper has a negative sign or not
if (reverseNumKeeper.contains("-")) {
return "-" + Integer.parseInt(reverseNumKeeper.replace("-", ""));
} else {
return "" + Integer.parseInt(reverseNumKeeper);
}
}
}

Well as YCF_L said you can just use a StringBuilder having a negative there does not make to much difference. You can include a check for it.
public class FunWithNumbers {
public static int numberReverser(String number) {
System.out.println("Input: " + number);
int returnVal;
String returnString;
boolean negative = false;
//If minus is always at the start if it is there
if(number.substring(0, 1).equals("-")) {
negative = true;
}
if(negative) {
returnString = new StringBuilder(number.substring(1, number.length() - 1)).reverse().toString().replaceFirst("^[0]+", "");
returnString = "-" + returnString;
} else {
returnString = new StringBuilder(number).reverse().toString().replaceFirst("^[0]+", "");
}
try {
returnVal = Integer.parseInt(returnString);
} catch (NumberFormatException nFE) {
System.out.println("There was a number format exception");
returnVal = -1;
}
System.out.println("Output: " + returnVal + "\n");
return returnVal;
}
public static int numberReverser(int number) {
return numberReverser(Integer.toString(number));
}
public static void main(String[] args) {
//Usage
FunWithNumbers.numberReverser("003600");
FunWithNumbers.numberReverser("-003600");
FunWithNumbers.numberReverser((int)0036000D);
FunWithNumbers.numberReverser((int)-003600D);
}
}
Output
Input: 003600
Output: 6300
Input: -003600
Output: -6300
Input: 36000
Output: 63
Input: -3600
Output: -63
You might notice that there are two ways of inputting it here, but only one will give you the correct output you are after.
The first way if with a String. This provides the expected output. The second method, with an int does not provide the expected output. This is because an int will not store the leading zeros. Similarly, if you attempt to input an int with leading zeros, you can actually convert it to octal. To avoid this you can use (int)<int>D or (int)<int>F. See the example in the code

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 leave only 4 decimals after number bigger than 0?

I don't know how to explain this well, but for example I have a number:
0.00000548347554 and want to make 0.000005483 from it, or
0.0683453248 to 0.06843, etc.
This assumes your number is a string:
String tmp = "0.0683453248";
String[] tmpA = tmp.split("");
ArrayList<String> res = new ArrayList<>();
for(int i = 0; i < tmpA.length; i++){
res.add(tmpA[i]);
if(!tmpA[i].equals(".") && Integer.parseInt(tmpA[i]) > 0){
res.add(tmpA[i + 1]);
res.add(tmpA[i + 2]);
res.add(tmpA[i + 3]);
break;
}
}
String result = String.join("",res);
Using the solution from this answer, you can convert the given number into a string and then use the regex replacement to get the required string out of it.
Demo:
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
// Test
System.out.println(doubleToString(0.00000548347554));
System.out.println(doubleToString(0.0683453248));
}
static String doubleToString(double n) {
DecimalFormat df = new DecimalFormat("0", DecimalFormatSymbols.getInstance(Locale.ENGLISH));
df.setMaximumFractionDigits(340);
return df.format(n).replaceAll("(\\d*\\.0*[1-9]{4})\\d*", "$1");
}
}
Output:
0.000005483
0.06834
ONLINE DEMO
Explanation of the regex:
(: Start of capturing group#1
\\d*\\.: Digit(s) followed by .
0*: Any number of zeros
[1-9]{4}: Non-zero four digits
): End of capturing group#1
\d* : Any digit any number of times
For small numbers BigDecimal can be used:
BigDecimal significant(double number, int count) {
if (count < 1)
throw new IllegalArgumentException("invalid count: " + count);
BigDecimal big = BigDecimal.valueOf(number);
if (big.precision() <= count) {
return big;
} else {
return big.setScale(big.scale()-big.precision()+count, RoundingMode.HALF_EVEN);
}
}
precision() returns the number of significant digits;
the method changes the scale so only the desired number of digits is present.
The if is used to avoid more zeros than the input if this has less than count digits.
Use doubleValue() to convert the result to double if needed (may suffer from rounding error).
To get a string, use toPlainString(), which will transform the result to string without using the exponential notation.
Rounding mode can also be changed if desired.
Note: it can also be used with larger numbers, it basically will replace digits by zero like in significant(12345,2) -> 12000 (or 1.2E+4)

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;
}

Flipping binary numbers using recursion

I am working on a project that the user enters an odd binary number ex: 10101 and I am supposed to have a recursive method that will flip the 1's and 0's ex: 101 = 010. For some reason my code is getting rid of the leading zero making the number an even number which crashes the program. Any and all help is appreciated, below is my Recursive class that is supposed to do the work of flipping the binary digits.
public class Recursive2 {
// int digit;
String temp;
public Recursive2(int d){
//digit = d;
temp = recursive(Integer.toString(d));
//System.out.print(recursive(temp));
}
public String toString(){
return temp;
}
public String recursive(String a){
String tempStr = "";
if(a.length() % 2 == 0){
System.out.println("Even number");
return "";
}
else if(a.length() == 1){
if(a.equals("1")){
tempStr = "0";
// tempStr += d;
}
else if(a.equals("0")){
tempStr= "1";
}
//System.out.println("Flipped d to" + tempStr);
}
else{
tempStr += new Recursive2(Integer.parseInt(a.substring(0,1))).toString();
tempStr += new Recursive2(Integer.parseInt(a.substring(1, a.length() - 1))).toString();
tempStr += new Recursive2(Integer.parseInt(a.substring(a.length()-1, a.length()))).toString();
}
return tempStr;
}
Here is my main class that tests the recursion.
public static void main(String[] args){
String num;
Scanner in = new Scanner(System.in);
System.out.println("Please enter a Binary number with an odd amount of digits: ");
num = in.nextLine();
System.out.println(num);
int num2 = Integer.parseInt(num);
System.out.println(num2);
Recursive2 test = new Recursive2(num2);
System.out.println(test);
}
You made several mistakes:
Deciding if the number is odd or even should be done before calling recursive method. Currently, your code will stop after at most one invocation, because you check the number of bits.
There is no need to parse int and making it String again. The entire process can be done entirely with strings.
Constructing the result should consist of appending the result of recursive invocation without the last bit to the string representing the inverse of the last bit.
The base case should be a situation when the string is empty, not when the string has exactly one digit.
Fixing these mistakes will produce a correct implementation.
The current algorithm is beyond repair.
Here's a recursive algorithm that's very simple and that will work:
if the string is empty, return it
if the first char is 0, return "1" + recurse(s.substring(1))
otherwise (the first char is 1), return "0" + recurse(s.substring(1))
Leading zeros are ignored because you're converting the input binary number to integer. For an integer leading zeros don't mean anything. You should be working with String only.
Also Integer.parseInt(num); would assume that you want to parse a decimal number not binary. If you do want to parse a binary number then you'll have to use another overloaded method Integer.parseInt(String s, int radix)
However as I said, because of the leading zeros you should work only with the Strings.
Integer.parseInt(i) converts the String to its Integer value.
However the Integer value of 010 is 10, leading 0's are dropped.
Work with the input as a String to avoid this.
Use StringBuilder to avoid creating new String or you can use char array
public static void main(String[] args) {
int no = 1234; // some no
String in = Integer.toBinaryString(no);
System.out.println("Original " + in);
System.out.println("Flipped " + flipBits(in));
}
public static String flipBits(String in) {
if (in.length() % 2 == 0)
return "even length";
return new String(flipBits(in.toCharArray(), in.length() - 1));
}
private static char[] flipBits(char[] ch, int index) {
if (index < 0) {
return ch;
} else {
ch[index] = Character.forDigit(49 - ch[index], 2); //flip
return flipBits(ch, index - 1);
}
}
output
Original 10011010010
Flipped 01100101101
The problem is that you are converting to integer values, which will throw away leading zeros. Just deal with strings:
public static void main(String[] args){
String num;
Scanner in = new Scanner(System.in);
System.out.println("Please enter a Binary number with an odd amount of digits: ");
num = in.nextLine();
System.out.println(num);
String flipped;
if (num.length() % 2 == 0) {
flipped = "Even number";
else {
flipped = Recursive2.recursive(num);
}
System.out.println(flipped);
}
And the Recursive2 class can just have static methods:
public class Recursive2 {
private static String flip(char c) {
if (c == '0') return "1";
return "0"; // assumes characters are all 0 or 1
}
public static String recursive(String a) {
STring tempStr;
if (a.length() == 0) {
tempStr = "";
} else {
tempStr = flip(a.charAt(0)) + recursive(a.substring(1));
}
return tempStr;
}
}
You might want to throw an exception if you detect a character other than 0 or 1.
EDIT: Based on your comment, the recursive method can be written as:
public static String recursive(String a) {
String tempStr = flip(a.charAt(0));
final int len = a.length();
if (len > 1) {
tempStr += recursive(a.substring(1, len - 1)) + flip(a.charAt(len - 1));
}
return tempStr;
}
This assumes that the argument is an odd-length string. That check should be done outside the recursive method, since if it is true once, it is true at every subsequent recursion.
I'd advise you to instead, remove one digit from the String that the user has imputed, and convert it (from the 1 to 0 vise versa), then use sub-string as the pass for the recursive function with one less.
Hint-> the base case would be a.length() == 0; because if you remove one digit of the string you will eventually have the length be 0.
Good Luck!

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

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]+", "");

Categories