I have bit representation like below
Bit 0(2^0 .= 1) - 1
Bit 1(2^1 .= 2) - 2
Bit 2(2^2 .= 4) - 4
Bit 3(2^3 .= 8) - 8
Bit 4(2^4 .= 16) - 16
A value of 7 means we have 1+2+4. But how do i get this array programmatically?
Continuosly divide by 2 and save the remainder
int n = 7;
StringBuilder sb = new StringBuilder();
while(n>0) {
sb.append(n%2);
n = n/2;
}
System.out.println(sb.reverse().toString());
You can store it anyway you want. Currently it is stored as string (Binary Representation of 7).
To convert back from the string to binary, start from LSB and add by powers of 2 of the bit position if the bit value is 1
Simple logic, works up to intmax (Very easy to change to max long by just changing type :))
public static void main(String[] args) {
int originalInt = 127;
toIntegerArray(originalInt);
}
private static List<Integer> toIntegerArray(int originalInt) {
String bits = Integer.toBinaryString(originalInt);
// Reversed, for easier logic when building string
StringBuilder s = new StringBuilder(bits).reverse();
char[] bitArray = s.toString().toCharArray();
List<Integer> result = new ArrayList<>();
for (int i = 0; i < bitArray.length; i++) {
if (bitArray[i] == '1') {
result.add((int) Math.pow(2, i));
}
}
System.out.println("Original int: " + originalInt);
System.out.println("Bit pattern: " + bits);
System.out.println(result);
return result;
}
I got below working, but for values below 31. Any suggestion on how to allow any value?
public static void Main(string[] args)
{
Console.WriteLine();
Console.WriteLine("[{0}]", string.Join(", ", log3(100)));
}
static int[] log3(int x) {
List<int> pow = new List<int>();
int val=x;
do{
if(x>= 1 << val){
if(1<<val>0){
pow.Add(1<<val);
}
x-=1<<val;
}
val-=1;
}while(val>=0);
return pow.ToArray();
}
Here is a recursive streaming option:
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
public class Class {
private static IntStream intToBinaryParts(final int input, final int count) {
int powerOf2 = (int) Math.pow(2, count);
if (count < 0) {
return IntStream.empty();
} else if (input < powerOf2) {
return intToBinaryParts(input, count - 1);
} else {
return IntStream.concat(intToBinaryParts(input - powerOf2, count - 1), IntStream.of(powerOf2));
}
}
public static List<Integer> intToBinaryParts(final int input) {
return intToBinaryParts(input, (int) Math.ceil(Math.log(input) / Math.log(2)))
.mapToObj(Integer::new)
.collect(Collectors.toList());
}
public static void main(String... args) {
System.out.println(intToBinaryParts(7));
System.out.println(intToBinaryParts(8));
System.out.println(intToBinaryParts(100));
System.out.println(intToBinaryParts(1234567890));
}
}
Related
I want to convert the decimal number into a binary number using recursion in java. I tried a lot but unable to do it. Here is my code:
public class DecimalToBinary {
public static void main(String[] args) {
System.out.println(conversion(2));
}
public static int conversion(int n) {
return reconversion(n);
}
public static int reconversion(int n) {
if(n <= 0)
return 0;
else {
return (int) (n/2 + conversion(n/2));
}
}
}
Integer values are already in binary. The fact that they appear as digits 0 thru 9 when you print them is because they are converted to a string of decimal digits. So you need to return a String of binary digits like so.
public static String conversion(int n) {
String b = "";
if (n > 1) {
// continue shifting until n == 1
b = conversion(n >> 1);
}
// now concatenate the return values based on the logical AND
b += (n & 1);
return b;
}
Problem Statement: Given a 32-bit signed integer, reverse digits of an integer.
Example 1:
Input: 123
Output: 321
Example 2:
Input: -123
Output: -321
My Solution:
class Solution7{
public int reverse(int x) {
if(x>Integer.MAX_VALUE || x<Integer.MIN_VALUE) {
return 0;
}
StringBuilder S_rev = new StringBuilder();
String S_r_v=S_rev.append(Math.abs(x)).reverse().toString();//.toString() String builder to String
double reverse_no=Double.parseDouble(S_r_v);
if (x < 0) {
return -(int)reverse_no;
}
return (int)reverse_no;
}
}
My Solution is ok for most of the test case. But it cannot pass one test case and I got a error
Error: Line 10: java.lang.NumberFormatException: For input string: "8463847412-"
If someone know what type of error it is please discuss.
Thank you in advance.
It seems like you are trying to pass in Integer.MIN_VALUE
When you pass in the minimum integer value, Math.abs seems to return a negative number as stated here
https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#abs-int-
Note that if the argument is equal to the value of Integer.MIN_VALUE, the most negative representable int value, the result is that same value, which is negative.
You can either check for x<=Integer.MIN_VALUE and return 0 if x is Integer.MIN_VALUE or handle the special case for Integer.MIN_VALUE
if(x== Integer.MIN_VALUE)
return -8463847412;
By converting number to String and reversing the sign symbol ended up on the end of the value. This makes the number invalid.
You don't have to convert to String or double. You can use module operator % to extract digits:
public int reverse(int x) {
long result = 0;
while (x != 0) {
result *= 10;
result += x % 10;
x /= 10;
}
if (result > Integer.MAX_VALUE || result < Integer.MIN_VALUE) {
throw new IllegalArgumentException(); // overflow
}
return result;
}
If you necessarily want to implement it using StringBuilder, here it is:
public static void main(String[] args) {
ReverseNum reverseNum = new ReverseNum();
System.out.println(reverseNum.reverse(-123));
System.out.println(reverseNum.reverse(123));
System.out.println(reverseNum.reverse(0));
}
public int reverse(int x) {
int res = 1;
String xStr = String.valueOf(x);
StringBuilder builder = null;
if (xStr.startsWith("-")) {
builder = new StringBuilder(xStr.substring(1));
res = -1;
} else {
builder = new StringBuilder(xStr);
}
return res * Integer.valueOf(builder.reverse().toString());
}
Output:
-321
321
0
P.S. If you want to avoid integer overflow, then you can simply use long instead of int, like this:
public long reverse(int x) {
long res = 1;
String xStr = String.valueOf(x);
StringBuilder builder = null;
if (xStr.startsWith("-")) {
builder = new StringBuilder(xStr.substring(1));
res = -1;
} else {
builder = new StringBuilder(xStr);
}
return res * Long.valueOf(builder.reverse().toString());
}
public class ReverseString {
public static void main(String args[]) {
ReverseString rs = new ReverseString();
System.out.println(rs.reverse(-84638));
System.out.println(rs.reverse(5464867));
}
public long reverse(int number) {
boolean isNegative = number < 0;
StringBuilder reverseBuilder = new StringBuilder();
String reversedString = reverseBuilder.append(Math.abs(number)).reverse().toString();
long reversedStringValue = Long.parseLong(reversedString);
if(isNegative) {
return reversedStringValue * -1;
} else {
return reversedStringValue;
}
}
}
This code provides the output you have mentioned in the requirement. And It also supports for integer overflow. Your requirement is to convert int values. It is okay to get the converted value in the higher format since converted value may not be in the range of int. I have changed the reverse method return type to long.
I have identified a few issues in your code.
public int reverse(int x) {
if(x>Integer.MAX_VALUE || x<Integer.MIN_VALUE) {
return 0;
}
Above code segment, not point of checking whether the value is inside the int range because it is already received in the param as a string. It should throw an error before executing your code lines since it is not able to fit the larger value to int variable.
Finally, the int number you have used is not in the int range. (-8463847412)
What about this?
public class ReverseNumber {
public static void main(String[] args) {
System.out.println(reverse(123456));
System.out.println(reverse(0));
System.out.println(reverse(-987654));
}
private static int reverse(int i) {
final int signum;
if(i < 0) {
signum = -1;
} else {
signum = +1;
}
int reversedNumber = 0;
int current = Math.abs(i);
while(0 < current) {
final int cipher = current % 10;
reversedNumber = Math.addExact(Math.multiplyExact(reversedNumber, 10), cipher);
current = current / 10;
}
return signum * reversedNumber;
}
}
Output:
654321
0
-456789
This solution avoids strings and can handle negative numbers.
It throws an Arithmetic exception if an integer overflow happens.
I'm stuck on a test case.
The question requires to compute a large Fibonacci number in a given period of time.
I have passed 8 cases out of 10 and stuck on 9.
Here is my Code:
import java.util.*;
import java.math.BigInteger;
public class LastNumberofFibo {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
BigInteger bi = sc.nextBigInteger();
System.out.println(fib(bi));
}
public static BigInteger fib(BigInteger n) {
BigInteger val=new BigInteger("10");
int k = n.intValue();
BigInteger ans = null;
if(k == 0) {
ans = new BigInteger("0");
} else if(Math.abs(k) <= 2) {
ans = new BigInteger("1");
} else {
BigInteger km1 = new BigInteger("1");
BigInteger km2 = new BigInteger("1");
for(int i = 3; i <= Math.abs(k); ++i) {
ans = km1.add(km2);
km2 = km1;
km1 = ans;
}
}
if(k<0 && k%2==0) { ans = ans.negate(); }
return ans.mod(val);
}
}
After Submitting I get the following Time-out result.
I need help in making my code more efficient.
Feedback :
Failed case #9/10: time limit exceeded
Input:
613455
Your output:
stderr:
(Time used: 3.26/1.50, memory used: 379953152/536870912.)
Please guide me.
Yours Sincerely,
Vidit Shah
I have taken the most easy to implemement suggestions from comments and put it in code.
import java.util.*;
import java.math.BigInteger;
public class LastNumberofFibo {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
BigInteger bi = sc.nextBigInteger();
System.out.println(fib(bi));
}
public static BigInteger fib(BigInteger n) {
int m = 10;
BigInteger sixty = new BigInteger("60");
int k = (n.mod(sixty)).intValue();
int ans = 0;
if(k == 0) {
ans = 0;
} else if(Math.abs(k) <= 2) {
ans = 1;
} else {
int km1 = 1;
int km2 = 1;
for(int i = 3; i <= Math.abs(k); ++i) {
ans = (km1 + km2)%m;
km2 = km1;
km1 = ans;
}
}
if(k<0 && k%2==0) { ans = -ans; }
return new BigInteger("" + ans);
}
}
Try that:
public static int fibonacci(int n) {
return (int)((Math.pow((1 + Math.sqrt(5)) / 2, n) - Math.pow((1 - Math.sqrt(5)) / 2, n)) / Math.sqrt(5));
}
I have applied the KNN algorithm for classifying handwritten digits. the digits are in vector format initially 8*8, and stretched to form a vector 1*64..
As it stands my code applies the kNN algorithm but only using k = 1. I'm not entirely sure how to alter the value k after attempting a couple of things I kept getting thrown errors. If anyone could help push me in the right direction it would be really appreciated. The training dataset can be found here and the validation set here.
ImageMatrix.java
import java.util.*;
public class ImageMatrix {
private int[] data;
private int classCode;
private int curData;
public ImageMatrix(int[] data, int classCode) {
assert data.length == 64; //maximum array length of 64
this.data = data;
this.classCode = classCode;
}
public String toString() {
return "Class Code: " + classCode + " Data :" + Arrays.toString(data) + "\n"; //outputs readable
}
public int[] getData() {
return data;
}
public int getClassCode() {
return classCode;
}
public int getCurData() {
return curData;
}
}
ImageMatrixDB.java
import java.util.*;
import java.io.*;
import java.util.ArrayList;
public class ImageMatrixDB implements Iterable<ImageMatrix> {
private List<ImageMatrix> list = new ArrayList<ImageMatrix>();
public ImageMatrixDB load(String f) throws IOException {
try (
FileReader fr = new FileReader(f);
BufferedReader br = new BufferedReader(fr)) {
String line = null;
while((line = br.readLine()) != null) {
int lastComma = line.lastIndexOf(',');
int classCode = Integer.parseInt(line.substring(1 + lastComma));
int[] data = Arrays.stream(line.substring(0, lastComma).split(","))
.mapToInt(Integer::parseInt)
.toArray();
ImageMatrix matrix = new ImageMatrix(data, classCode); // Classcode->100% when 0 -> 0% when 1 - 9..
list.add(matrix);
}
}
return this;
}
public void printResults(){ //output results
for(ImageMatrix matrix: list){
System.out.println(matrix);
}
}
public Iterator<ImageMatrix> iterator() {
return this.list.iterator();
}
/// kNN implementation ///
public static int distance(int[] a, int[] b) {
int sum = 0;
for(int i = 0; i < a.length; i++) {
sum += (a[i] - b[i]) * (a[i] - b[i]);
}
return (int)Math.sqrt(sum);
}
public static int classify(ImageMatrixDB trainingSet, int[] curData) {
int label = 0, bestDistance = Integer.MAX_VALUE;
for(ImageMatrix matrix: trainingSet) {
int dist = distance(matrix.getData(), curData);
if(dist < bestDistance) {
bestDistance = dist;
label = matrix.getClassCode();
}
}
return label;
}
public int size() {
return list.size(); //returns size of the list
}
public static void main(String[] argv) throws IOException {
ImageMatrixDB trainingSet = new ImageMatrixDB();
ImageMatrixDB validationSet = new ImageMatrixDB();
trainingSet.load("cw2DataSet1.csv");
validationSet.load("cw2DataSet2.csv");
int numCorrect = 0;
for(ImageMatrix matrix:validationSet) {
if(classify(trainingSet, matrix.getData()) == matrix.getClassCode()) numCorrect++;
} //285 correct
System.out.println("Accuracy: " + (double)numCorrect / validationSet.size() * 100 + "%");
System.out.println();
}
In the for loop of classify you are trying to find the training example that is closest to a test point. You need to switch that with a code that finds K of the training points that is the closest to the test data. Then you should call getClassCode for each of those K points and find the majority(i.e. the most frequent) of the class codes among them. classify will then return the major class code you found.
You may break the ties (i.e. having 2+ most frequent class codes assigned to equal number of training data) in any way that suits your need.
I am really inexperienced in Java, but just by looking around the language reference, I came up with the implementation below.
public static int classify(ImageMatrixDB trainingSet, int[] curData, int k) {
int label = 0, bestDistance = Integer.MAX_VALUE;
int[][] distances = new int[trainingSet.size()][2];
int i=0;
// Place distances in an array to be sorted
for(ImageMatrix matrix: trainingSet) {
distances[i][0] = distance(matrix.getData(), curData);
distances[i][1] = matrix.getClassCode();
i++;
}
Arrays.sort(distances, (int[] lhs, int[] rhs) -> lhs[0]-rhs[0]);
// Find frequencies of each class code
i = 0;
Map<Integer,Integer> majorityMap;
majorityMap = new HashMap<Integer,Integer>();
while(i < k) {
if( majorityMap.containsKey( distances[i][1] ) ) {
int currentValue = majorityMap.get(distances[i][1]);
majorityMap.put(distances[i][1], currentValue + 1);
}
else {
majorityMap.put(distances[i][1], 1);
}
++i;
}
// Find the class code with the highest frequency
int maxVal = -1;
for (Entry<Integer, Integer> entry: majorityMap.entrySet()) {
int entryVal = entry.getValue();
if(entryVal > maxVal) {
maxVal = entryVal;
label = entry.getKey();
}
}
return label;
}
All you need to do is adding K as a parameter. Keep in mind, however, that the code above does not handle ties in a particular way.
I want to convert String input into int using recursion. This is the code I came up with but if my input is 123456 it only returns 124. If I enter 1234567, it gives an error.
import java.util.*;
public class Problem1 {
static int x =0;
static int counter = 0;
//input
public static void main(String[] args) {
Scanner scan = new Scanner (System.in);
String s= scan.nextLine();
System.out.println(recursive(s));
}
//recursive method
public static int recursive(String s){
if(s.length()==1){
x=(x*10)+ Integer.parseInt(s.substring(0,1));
return x;
}
else{
x = (x*10)+Integer.parseInt(s.substring(0,1));
counter++;
return recursive(s.substring(counter,s.length()-1));
}
}
}
import java.util.Scanner;
public class Problem1 {
static int x = 0;
static int counter = 0;
// input
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
String s = scan.nextLine();
System.out.println(recursive(s));
}
// recursive method
public static int recursive(String s) {
if (s.length() == 1) {
x = (x * 10) + Integer.parseInt(s.substring(0, 1));
return x;
} else {
x = (x * 10) + Integer.parseInt(s.substring(0, 1));
counter++;
return recursive(s.substring(1, s.length()));
}
}
}
Look at your static counter variable. You are incrementing it every time. But you only want to have the substring starting at 1 (so cut off the first "letter").
So instead of using:
counter++;
return recursive(s.substring(counter,s.length()-1));
consider using:
return recursive(s.substring(1)); // you even don't really need the length
Because the String s parameter is as follows:
1st call: 1234567
2nd call: 234567
3rd call: 34567
4th call: 4567
...
So, you only have to cut off the first letter.
Btw: your sample "project" is a really funny one ;)
A few notes to start:
If you're doing recursion, you probably don't want to use a member variable. It's not wrong to do so, but not really typical of the pattern (your x variable).
It's often handy to pass in state through the recursion, although you wouldn't have to (that is, current value of x).
Your case is a little odd because you have to change your current parse value for every sub-parse (shifting by 10 each time); makes it a little more complicated.
If you are going to keep x as a member variable (which does seem to make sense in this case), you don't need to return anything from recursive.
Can you really not just use Integer.parseInt()?
Code could be much more simple, something like:
void recursive (String s)
{
if (s.length() == 0) return 0;
x = x * 10 + Integer.parseInt(s.substring(0, 1));
recursive(s.substring(1));
}
recursion("1234567", 0, 1)
The above code will turn the string "1234567" into an int using recursion. You must pass the string you want to convert, and then 0 and 1.
public static int recursion(String s, int result, int place) {
result += place * Integer.parseInt(s.charAt(s.length() - 1) + "");
if(s.length() == 1) {
return result;
}
else {
return recursion(s.substring(0, s.length() - 1), result, place * 10);
}
}
public static int computeStr(String str) {
if (str.equals("")) {
return 0;
}
int x = 1;
for (int i = 0; i < str.length() - 1; i++) {
x = x * 10;
}
x = x * Integer.parseInt(str.substring(0, 1));
return x + computeStr(str.substring(1));
}
For example: "2432" is (2 * 1000) + (4 * 100) + (3*10) + (2*1) = 2432
this algorithm begins at first position (2) from 2432
I know its kind of a late response but you could try something like this :-
private static int stringToInt(String string) {
if (string.length() == 0) {
return 0;
}
int rv;
int num = string.charAt(string.length() - 1) - '0';
String restOfTheString = string.substring(0, string.length() - 1);
rv = stringToInt(restOfTheString) * 10 + num;
return rv;
}
Try something like this:
Subtracting the ASCII code of the '0' character from your character returns an integer:
public class StringRecursion {
static int counter = 0;
public static void main(String[] args) {
System.out.println(convertStringToInt("123456"));
}
public static int convertStringToInt(String input) {
if (input.length() == 1)
return input.charAt(0) - '0';
int value = convertStringToInt(input.substring(0, input.length() - 1));
counter++;
return value * 10 + input.charAt(counter) - '0';
}
}
Try it like this :
public static int conStrToInt(String str) {
if(str.length()==0)
{
return 0;
}
char cc = str.charAt(0);
String ros = str.substring(1);
int factor=1;
for(int i=0;i<str.length()-1;i++)
factor*=10;
factor=factor*(cc-'0');
return factor+conStrToInt(ros);
}