binary to decimal converter without using parseint or arrays - java

Getting string index out of range but I don't understand why I've went through it about 50 times
import java.util.Scanner;
public class binary {
public static void main(String[] args) {
System.out.println("Enter the first binary number");
Scanner keyboard = new Scanner(System.in);
String num1 = keyboard.next();
//System.out.println("Enter the second binary number");
//String num2 = keyboard.next();
int total = 0;
for(int i = num1.length(); i>0;i--) {
if(num1.charAt(i) == 1) {
total += 2*i;
}
}
if(num1.charAt(3) == 1) {
total -= 1;
}
System.out.println(total);
}
}

Here's a complete solution to what you're trying to do, including a set of tests:
class binary {
private static int binaryToInt(String binary) {
int total = 0;
for (int i = 0 ; i < binary.length(); i++) {
total *= 2;
if (binary.charAt(i) == '1')
total += 1;
}
return total;
}
private static void test(String binary, int expected) {
int n = binaryToInt(binary);
String rightWrong = "right";
if (n != expected) {
rightWrong = String.format("WRONG! (should be %d)", expected);
System.out.printf("%s -> %d is %s\n", binary, n, rightWrong);
}
public static void main(String[] args) {
test("0", 0);
test("1", 1);
test("10", 2);
test("100", 4);
test("111", 7);
test("0000111", 7);
test("1010101010", 682);
test("1111111111", 1023);
System.out.println("");
// test sanity check
System.out.println("This last test should fail (we are just testing the test method itself here)...");
test("1010101010", 0);
}
}
Result:
0 -> 0 is right
1 -> 1 is right
10 -> 2 is right
100 -> 4 is right
111 -> 7 is right
0000111 -> 7 is right
1010101010 -> 682 is right
1111111111 -> 1023 is right
This last test should fail (we are just testing the test method itself here)...
1010101010 -> 682 is WRONG! (should be 0)
One significant problem in your code hasn't yet been addressed in the comments or earlier answers. Note this line vs the one in your code:
if (binary.charAt(i) == '1')
You were testing for the numeric value 1, which is never going to be true because you're getting back a character from charAt(), not a number.

While length() counts the number of elements, their indexes start at 0. For a string of "1111" the last character would be at index 3, not 4, so .length()-1. You would need to either change your for statement to for(int i = num1.length()-1; i>=0;i--) (notice also the condition change) or change the charAt statement to if(num1.charAt(i-1) == '1').
Also, based on what you are trying to do, I assume for total += 2*i you actually need something like total += Math.pow(2, i-length()) depending on what you decide to do with i first.

Related

is there some solution to reduce the time complexity of a program in java?

The question is
Given a number 'N'. The task is to find the Nth number whose each
digit is a prime number(<10) i.e 2, 3, 5, 7. In other words you have
to find nth number of this sequence : 2, 3, 5, 7, 22, 23 ,.. and so
on.
I'm trying the below code which exceeds the time bound.
import java.io.*;
import java.util.*;
class Main {
public static boolean AlldigitsPrime(int m){
for(; m>0;){
int dig=m%10;
if(dig!=2 && dig!=3 && dig!=5 && dig!=7){
return false;
}
m/=10;
}
return true;
}
public static void main (String[] args) {
Scanner sc=new Scanner(System.in);
int t=sc.nextInt();
for(int i=0; i<t; i++){
int n=sc.nextInt();
int count=0;
for(int j=2; j>=2 ; j++){
if(AlldigitsPrime(j)){
count++;
if(count==n){
System.out.println(j);
break ;
}
}
}
}
}
}
You can calculate the n-th number almost directly. The idea is to convert n into a new number system in which no number contains a 0 digit (apart from the leading ones which are ignored) but consists only of digits 1 to 4. That is: 1 -> 1, 4 -> 4, 5 -> 11, 6 -> 12, 9 -> 21 and so on. The last step is to replace each digit (1 to 4) by its correspondig prime number (2, 3, 5 or 7).
Although I usually refrain from giving example code for homework, but because it's a bit complicated, I'll show the solution:
public int convert(int n) {
if (n < 1) throw new IllegalArgumentException("n must be positive but was " + n);
int[] primes = {2,3,5,7};
int result = 0;
int power = 1;
do {
int digit = (n-1) % 4 + 1; // we don't want 0es
result += primes[digit - 1] * power;
power *= 10;
n = (n-1) / 4; // take the 'removed' 0es into consideration
} while (n > 0);
return result;
}
Of course, addition and subtraction of 1 in the first two lines of the loop is not necessary but I kept it there to highlight the 'removal' of 0es while calculating the digits.

Find the smallest binary number without continous 1

So here is the thing.
I have to write code to show a binary number X's next smallest "code-X number" which is bigger than binary number X.
code-X number is a binary number which have no continuously 1. For example: 1100 is not a code X number because it has 11, and 1001001001 is a code-X number
Here is my code
String a = "11001110101010";
String b = "";
int d = 0;
for(int i = a.length()-1; i>0;i--){
if(a.charAt(i) == '1' && a.charAt(i-1)=='1'){
while(a.charAt(i)=='1'){
b = b + '0';
if(i!=0){i--;}
d++;
}
}
b = b + a.charAt(i);
}
StringBuffer c = new StringBuffer(b);
System.out.println(c.reverse());
I plan on copy the binary string to string b, replace every '1' which next i is '1' into '0' and insert an '1'
like:
1100 ---> 10000
but i have no idea how to do it :)
May you help me some how? Thanks
Try this. This handles arbitrary length bit strings. The algorithm is as follows.
Needed to conditionally modify last two bits to force a change if the number is not a codeEx number. This ensures it will be higher. Thanks to John Mitchell for this observation.
Starting from the left, find the first group of 1's. e.g 0110
If not at the beginning replace it with 100 to get 1000
Otherwise, insert 1 at the beginning.
In all cases, replace everything to the right of the grouping with 0's.
String x = "10000101000000000001000001000000001111000000000000110000000000011011";
System.out.println(x.length());
String result = codeX(x);
System.out.println(x);
System.out.println(result);
public static String codeX(String bitStr) {
StringBuilder sb = new StringBuilder(bitStr);
int i = 0;
int len = sb.length();
// Make adjust to ensure new number is larger than
// original. If the word ends in 00 or 10, then adding one will
// increase the value in all cases. If it ends in 01
// then replacing with 10 will do the same. Once done
// the algorithm takes over to find the next CodeX number.
if (s.equals("01")) {
sb.replace(len - 2, len, "10");
} else {
sb.replace(len- 1, len, "1");
}
while ((i = sb.indexOf("11")) >= 0) {
sb.replace(i, len, "0".repeat(len - i));
if (i != 0) {
sb.replace(i - 1, i + 2, "100");
} else {
sb.insert(i, "1");
}
}
String str = sb.toString();
i = str.indexOf("1");
return i >= 0 ? str.substring(i) : str;
}
Prints
10000101000000000001000001000000001111000000000000110000000000011011
10000101000000000001000001000000010000000000000000000000000000000000
Using raw binary you can use the following.
public static void main(String[] args) {
long l = 0b1000010100000000010000010000000011110000000000110000000000011011L;
System.out.println(
Long.toBinaryString(nextX(l)));
}
public static long nextX(long l) {
long l2 = l >>> 1;
long next = Long.highestOneBit(l & l2);
long cutoff = next << 1;
long mask = ~(cutoff - 1);
return (l & mask) | cutoff;
}
prints
1000010100000000010000010000000010000000000000000000000000000000
EDIT: Based on #WJS correct way to find the smallest value just larger.
This is a slight expansion WJS' 99% correct answer.
There is just one thing missing, the number is not incremented if there are no consecutive 1's in the original X string.
This modification to the main method handles that.
Edit; Added an else {}. Starting from the end of the string, all digits should be inverted until a 0 is found. Then we change it to a 1 and break before passing the resulting string to WJS' codeX function.
(codeX version does not include sb.replace(len-2,len,"11");)
public static void main(String[] args) {
String x = "10100";
StringBuilder sb = new StringBuilder(x);
if (!x.contains("11")) {
for (int i = sb.length()-1; i >= 0; i--) {
if (sb.charAt(i) == '0') {
sb.setCharAt(i, '1');
break;
} else {
sb.setCharAt(i, '0');
}
}
}
String result = codeX(sb.toString());
System.out.println(x);
System.out.println(result);
}

How to print single number only once using nested loops in Java?

Everything runs fine in my Java code except at the very end of the code. So basically I can't figure out how to print out the User's Number if it is the same. For example I am prompt the User for a starting number and an ending number (integers). So say the user enters in the same integer "10" for starting number and "10" for ending number. I want the output to only be "10" to be printed only just once. I've tried everything I can think of with trying While Loop, Do-While Loop, and For Loops but I just can't figure it out?
------------------------JAVA CODE BELOW-------------------------------------------
import java.util.Scanner;
public class LoopsAssignment {
public static void main(String[] args) {
// input Scanner
Scanner input = new Scanner(System.in);
// ask user for a starting number and a ending number
System.out.println("Now I'll print whatever numbers you'd like!");
System.out.println("Give me a starting number: ");
startNum = input.nextInt();
System.out.println("Give me an ending number: ");
endNum = input.nextInt();
// count the users range of numbers
System.out.println("I counted your range of numbers: ");
int a = startNum;
int b = endNum;
while (a <= b) {
System.out.println(a);
a = a + 1;
}
while (a >= b) {
System.out.println(a);
a = a - 1;
}
while (a == b) {
System.out.println(a);
}
}
}
---------------------OUT PUT BELOW -----------------------------------------------------
Now I'll print whatever numbers you'd like!
Give me a starting number:
10
Give me an ending number:
10
I counted your range of numbers:
10
11
10
----jGRASP: operation complete.
You could restructure your code as follows:
while (a < b) {
System.out.println(a);
a = a + 1;
}
while (a > b) {
System.out.println(a);
a = a - 1;
}
if (a == b) {
System.out.println(a);
}
You can use for loop:
public static void printRange(int minInclusive, int maxInclusive) {
for (; minInclusive <= maxInclusive; minInclusive++)
System.out.println(minInclusive);
}
So you are either counting up, down or there's just one.
So
int step = endNum>startNum ? +1 : -1;
int a = startNum;
int b = endNum;
while (a != b) {
System.out.println(a);
a = a + step;
}
System.out.println(b);
Or put a break in the middle of a for loop. Also there's +=, and a few things we can make more conventional.
int step = endNum>startNum ? +1 : -1;
for (int i=startNum; ; i+=step) {
System.out.println(i);
if (i == endNum) {
break;
}
}
The issue is in your first two while loops where you are using ">=" and "<=". You can remove "=" from the condition.
However you can improve your code as suggested in other comments.

How does this prime number test in Java work?

The code snippet below checks whether a given number is a prime number. Can someone explain to me why this works? This code was on a study guide given to us for a Java exam.
public static void main(String[] args)
{
int j = 2;
int result = 0;
int number = 0;
Scanner reader = new Scanner(System.in);
System.out.println("Please enter a number: ");
number = reader.nextInt();
while (j <= number / 2)
{
if (number % j == 0)
{
result = 1;
}
j++;
}
if (result == 1)
{
System.out.println("Number: " + number + " is Not Prime.");
}
else
{
System.out.println("Number: " + number + " is Prime. ");
}
}
Overall theory
The condition if (number % j == 0) asks if number is exactly divisible by j
The definition of a prime is
a number divisible by only itself and 1
so if you test all numbers between 2 and number, and none of them are exactly divisible then it is a prime, otherwise it is not.
Of course you don't actually have to go all way to the number, because number cannot be exactly divisible by anything above half number.
Specific sections
While loop
This section runs through values of increasing j, if we pretend that number = 12 then it will run through j = 2,3,4,5,6
int j = 2;
.....
while (j <= number / 2)
{
........
j++;
}
If statement
This section sets result to 1, if at any point number is exactly divisible by j. result is never reset to 0 once it has been set to 1.
......
if (number % j == 0)
{
result = 1;
}
.....
Further improvements
Of course you can improve that even more because you actually need go no higher than sqrt(number) but this snippet has decided not to do that; the reason you need go no higher is because if (for example) 40 is exactly divisible by 4 it is 4*10, you don't need to test for both 4 and 10. And of those pairs one will always be below sqrt(number).
It's also worth noting that they appear to have intended to use result as a boolean, but actually used integers 0 and 1 to represent true and false instead. This is not good practice.
I've tried to comment each line to explain the processes going on, hope it helps!
int j = 2; //variable
int result = 0; //variable
int number = 0; //variable
Scanner reader = new Scanner(System.in); //Scanner object
System.out.println("Please enter a number: "); //Instruction
number = reader.nextInt(); //Get the number entered
while (j <= number / 2) //start loop, during loop j will become each number between 2 and
{ //the entered number divided by 2
if (number % j == 0) //If their is no remainder from your number divided by j...
{
result = 1; //Then result is set to 1 as the number divides equally by another number, hergo
} //it is not a prime number
j++; //Increment j to the next number to test against the number you entered
}
if (result == 1) //check the result from the loop
{
System.out.println("Number: " + number + " is Not Prime."); //If result 1 then a prime
}
else
{
System.out.println("Number: " + number + " is Prime. "); //If result is not 1 it's not a prime
}
It works by iterating over all number between 2 and half of the number entered (since any number greater than the input/2 (but less than the input) would yield a fraction). If the number input divided by j yields a 0 remainder (if (number % j == 0)) then the number input is divisible by a number other than 1 or itself. In this case result is set to 1 and the number is not a prime number.
Java java.math.BigInteger class contains a method isProbablePrime(int certainty) to check the primality of a number.
isProbablePrime(int certainty): A method in BigInteger class to check if a given number is prime.
For certainty = 1, it return true if BigInteger is prime and false if BigInteger is composite.
Miller–Rabin primality algorithm is used to check primality in this method.
import java.math.BigInteger;
public class TestPrime {
public static void main(String[] args) {
int number = 83;
boolean isPrime = testPrime(number);
System.out.println(number + " is prime : " + isPrime);
}
/**
* method to test primality
* #param number
* #return boolean
*/
private static boolean testPrime(int number) {
BigInteger bValue = BigInteger.valueOf(number);
/**
* isProbablePrime method used to check primality.
* */
boolean result = bValue.isProbablePrime(1);
return result;
}
}
Output: 83 is prime : true
For more information, see my blog.
Do try
public class PalindromePrime {
private static int g ,k ,n =0,i,m ;
static String b ="";
private static Scanner scanner = new Scanner( System.in );
public static void main(String [] args) throws IOException {
System.out.print(" Please Inter Data : ");
g = scanner.nextInt();
System.out.print(" Please Inter Data 2 : ");
m = scanner.nextInt();
count(g,m);
}
//
//********************************************************************************
private static int count(int L, int R)
for( i= L ; i<= R ;i++){
int count = 0 ;
for( n = i ; n >=1 ;n -- ){
if(i%n==0){
count = count + 1 ;
}
}
if(count == 2)
{
b = b +i + "" ;
}
}
System.out.print(" Data : ");
System.out.print(" Data : \n " +b );
return R;
}
}

How do I format a number left-padded without using String.format in Java 6?

For example, I need to grab an unknown number, let's say 3, and find the binary (2^3) - 1 times, from 0 to 111 (0-7). Obviously, the number of digits I need depends on whatever number 'n' in 2^n.
So, if the number is 3, I would need the output to be:
000
001
010
011
100
101
111
Now obviously I can do this manually with a String.format("%03d", NumberInBinary) operation, but that's hardcoding it for 3 digits. I need to do the equivalent code with an unknown number of digits, how can I do that? (as in String.format("%0nd", yournumber) where n is the number of digits.)
if n = 4, NumberInBinary = 101;
String.format("%0"+n+"d", NumberInBinary);
with output
0101
Why not make use of the already built-in Integer.toBinaryString() and just manually add the zeros using a StringBuilder ?
public static void main(String[] args) {
int max = 5;
for (int i = 0; i < Integer.MAX_VALUE; i++) {
String binary = Integer.toBinaryString(i);
if (binary.length() > max) {
break;
}
System.out.println( prefixWithZeros(binary, max) );
}
}
static String prefixWithZeros(String binary, int n) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < n - binary.length(); i++) {
sb.append('0');
}
return sb.append(binary).toString();
}
You could use recursion:
public static void enumerate(String prefix, int remaining) {
if (remaining == 0) {
System.out.println(prefix);
} else {
enumerate(prefix + "0", remaining - 1);
enumerate(prefix + "1", remaining - 1);
}
}
and then call enumerate("", numberOfDigits);
faster, using StringBuffer:
public static void enumerate(StringBuffer prefix, int remaining) {
if (remaining == 0) {
System.out.println(prefix.toString());
} else {
enumerate(prefix.append('0'), remaining - 1);
prefix.deleteCharAt(prefix.length() - 1);
enumerate(prefix.append('1'), remaining - 1);
prefix.deleteCharAt(prefix.length() - 1);
}
}
and then call enumerate(new StringBuffer(), numberOfDigits);

Categories