Binary divison java implementation - java

It might be a weird question, but I havent found any binary division java implementation browsing the internet. I will use it for CRC16 coding, so converting to decimal is not a solution. I understand the method on paper, but I am a beginner and since it's very important I wouldn't want to make it wrong. The only thing I found is a CRC.java on the code.google.com which uses binary division, but even if I only use the division part of that (removing the other parts) I dont get the desirable value.
Anybody can show me a java implementation of it? I'd appreciate it very much! Thanks in advance
The code what I found:
public class CRC {
private String data, divisor;
public CRC(String d, String di) {
this.data = d;
this.divisor = di;
}
public String getRemainder(String data, String divisor) {
int x = 1, z = divisor.length(), j = 0, i;
String data2 = "", strOfZeros = "";
int y = divisor.length() - 1;
/* This is to get correct amount of zero's onto the end of the data */
while (y > 0) {
data += "0";
y--;
}
// Main part of method, this is the long division of Binary numbers.
needToExit: for (i = x, j = 1; i < z && z <= data.length(); i++, j++) {
if (z == data.length() && data2.charAt(0) == '1') {
strOfZeros = "";
for (i = 1; i < divisor.length(); i++) {
if (data2.charAt(i) == divisor.charAt(i))
strOfZeros += '0';
else
strOfZeros += '1';
}
data2 = strOfZeros;
break needToExit;
}
if (data.charAt(i) == divisor.charAt(j))
data2 += "0";
else
data2 += "1";
if (i == divisor.length() - 1) {
data2 += data.charAt(z);
x++;
z++;
// i = x;
j = 0;
// when first bit is a 0
while (data2.charAt(0) != '1' && i == divisor.length() - 1) {
for (i = 1; i < divisor.length(); i++) {
if (data2.charAt(i) == '0')
strOfZeros += "0";
else
strOfZeros += "1";
}
strOfZeros += data.charAt(z);
data2 = strOfZeros;
strOfZeros = "";
x++;
z++;
i = x;
}
}
}
return data2;
}
public String getDataPlusCRC(String data){
String str = data.concat(getRemainder(this.data, this.divisor));
return str;
}
}
The getRemainder() method gives me a bad result when I try to divide to numbers. And this part is not necessary, because it needs for the CRC.
while (y > 0) {
data += "0";
y--;
}

BigInteger can do base 2 division;
BigInteger divisor = new BigInteger("10", 2);
BigInteger dividend = new BigInteger("100", 2);
BigInteger result = dividend.divide(divisor);
System.out.println(result.toString(2));

Related

add/subtract/or multiply as per the given string

I was given this problem in an interview, return the output of this String s = "4+8×2" , output = 20, Ex2: String s = "3×7-4", output = 17.
This is my approach, but I am not able to get the expected result, please point out the correct way here.
public static int findResult (String s) {
int i = 0;
Stack<String> stack = new Stack<>();
while (i < s.length()) {
if (s.charAt(i) == '+') {
stack.push(String.valueOf(s.charAt(i)));
i++;
} else if (s.charAt(i) == '*') {
stack.push(String.valueOf(s.charAt(i)));
i++;
} else if (s.charAt(i) == '-') {
stack.push(String.valueOf(s.charAt(i)));
i++;
} else if (Character.isDigit(s.charAt(i))) {
int num = s.charAt(i) - '0';
while (i+1 < s.length() && Character.isDigit(s.charAt(i + 1))) {
num = num * 10 + s.charAt(++i) - '0';
}
stack.push(String.valueOf(num));
i++;
}
}
int current = 0;
//second while loop
while (!stack.isEmpty()) {
int firstNumber = Integer.parseInt(stack.pop());
if (stack.isEmpty()) return current;
String sign = stack.pop(""
//int firstNum = Integer.parseInt(stack.pop());
if (sign.equals("*")) {
current = firstNumber * Integer.parseInt(stack.pop());
stack.push(String.valueOf(current));
}
else if (sign.equals("-")) {
current = firstNumber;
stack.push(String.valueOf(current));
} else {
current = firstNumber + Integer.parseInt(stack.pop());
stack.push(String.valueOf(current));
}
}
return Integer.parseInt(stack.pop());
}
This is how I approached this problem. (It is somewhat similar to yours). I'll post the code first, then explain the process below:
import java.util.*;
class Main {
public static void main(String[] args) {
System.out.println(findResult("2*57-38*3/5-5-2+3*4/2-2-2"));
}
public static double findResult (String s){
String sub = s;
ArrayList<Double> nums = new ArrayList<Double>();
ArrayList<Character> operations = new ArrayList<Character>();
for(int x = 0; x < s.length(); x++){
if(s.charAt(x) == '+' || s.charAt(x) == '-' || s.charAt(x) == '*' || s.charAt(x) == '/' ){
operations.add(s.charAt(x));
int subInd = sub.indexOf(s.charAt(x));
nums.add(Double.valueOf(sub.substring(0,subInd)));
sub = sub.substring(subInd + 1);
}
}
nums.add(Double.valueOf(sub));
String[] operationTypes = {"*/","+-"};
for(int i = 0; i < 2; i++){
for(int j = 0; j < operations.size(); j++){
if(operationTypes[i].indexOf(operations.get(j)) != -1){
double val;
if(operations.get(j) == '*'){
val = nums.get(j) * nums.get(j+1);
}
else if(operations.get(j) == '/'){
val = nums.get(j) / nums.get(j+1);
}
else if(operations.get(j) == '+'){
val = nums.get(j) + nums.get(j+1);
}
else{
val = nums.get(j) - nums.get(j+1);
}
nums.set(j,val);
nums.remove(j+1);
operations.remove(j);
j--;
}
}
}
return nums.get(0);
}
}
Yeah...it's a lot:
The first step in this process was to divide the String into two ArrayLists: nums and operations. nums stores the terms and operations stores the..operations (*, /, +, -).
Now, we iterate through each "group" of operations, that being multiplication and division, and addition and subtraction.
Starting with mult/div, if we see either a '*' or '/' in our operations, then we compute the product or quotient of the corresponding elements in our nums and edit nums accordingly by modifying the element that matches indexes with the operation and deleting the term following it. Make sure you also remove the operation from nums and decrement the counter variable so the loop does not skip any values.
Finally, we will return the only value left in our nums which will be our answer.
I hope this helped you! Please let me know if you need any further details or clarification :)

Big theta run time of string concatenation?

I have an assignment to create my own implementation of a class to handle integers of unlimited size, and then to compare my implementation's runtime to that of Java's BigInteger. When I measured and graphed the runtime of my add function it was a parabola, implying a big theta running time of Ө(n^2). I have no nested loops so I expected it to be Ө(n) and cannot figure out why it isn't. I suspect it might be that I use
string += integer
in my add method inside a loop. I am not quite sure how that operation is implemented, is it a runtime of Ө(n)? If not, can anyone spot why my code isn't Ө(n)?
Here is my add method and the constructor it calls.
public HugeInteger(String val) throws IllegalArgumentException{
String temp = "";
boolean leading = true;
//check valid input
for(int i=0; i<val.length(); i++){
if(val.charAt(i) < '0' || val.charAt(i) > '9') //checks if each digit is a number from 0 to 9
if(i!=0 || val.charAt(i) != '-') //doesn't throw if the digit is a '-' at the first character of string
throw new IllegalArgumentException("Input string must be a number");
}
//remove leading zeros
for(int i=0; i<val.length(); i++){
if(!leading || val.charAt(i) != '0')
temp += val.charAt(i);
if(val.charAt(i) > '0' && val.charAt(i) <= '9') //reached first non-zero digit
leading = false;
}
if(temp == "") //this happens when the input was just a string of zeros
temp = "0";
val = temp;
if(val.charAt(0) != '-'){ //no negative sign
digits = new int[val.length()];
for(int i=0; i<val.length(); i++){
digits[i] = (int)(val.charAt(val.length()-1-i) - 48); //in ASCII the char '0' == 48
}
negative = false;
}
else{
digits = new int[val.length() - 1];
for(int i=1; i<val.length(); i++){ //for loop starts after the '-' sign
digits[i-1] = (int)(val.charAt(val.length()-i) - 48); //in ASCII the char '0' == 48
}
negative = true;
}
}
public HugeInteger add(HugeInteger h){
int carry = 0;
int size = digits.length>h.digits.length?digits.length:h.digits.length; //choose larger # of digits
String sum = "";
String sumFlipped = "";
int bigger = 0;
boolean swapped = false;
int temp;
int sign = 1;
int hsign = 1;
//assign sign based on negative or not
if(negative && !h.negative)
sign = -1;
if(!negative && h.negative)
hsign = -1;
//compare magnitudes. 1 means this is biger and -1 means h is bigger
if(digits.length>h.digits.length)
bigger = 1;
else if(digits.length<h.digits.length)
bigger = -1;
else{ //same length
for(int i=0; i<digits.length; i++){ //both digits arrays are same length
if(digits[digits.length-1-i] > h.digits[h.digits.length-1-i]){
bigger = 1;
break;
}
if(digits[digits.length-1-i] < h.digits[h.digits.length-1-i]){
bigger = -1;
break;
}
}
}
//positive number must be bigger than negative number for long subtraction
//if not, swap signs
if(bigger == 1 && negative && !h.negative){ //this is bigger and negative
swapped = true;
sign *= -1;
hsign *= -1;
}
if(bigger == -1 && !negative && h.negative){ //h is bigger and negative
swapped = true;
sign *= -1;
hsign *= -1;
}
for(int i=0; i<size; i++){
if(i>=digits.length)
temp = h.digits[i]*hsign + carry;
else if(i>=h.digits.length)
temp = digits[i]*sign + carry;
else
temp = digits[i]*sign + h.digits[i]*hsign + carry;
if(temp>9){ //adds the digit to the string, then increments carry which is used in next iteration
temp -= 10;
sum += temp;
carry = 1;
}
else if(temp<0){
temp += 10;
carry = -1;
sum += temp;
}
else{
sum += temp;
carry = 0;
}
}
if(carry == 1)
sum += 1;
if(negative && h.negative || swapped)
sum += '-';
//flip string around
for(int i=0; i < sum.length(); i++){
sumFlipped += sum.charAt(sum.length() - 1 - i);
}
HugeInteger sumHugeInteger = new HugeInteger(sumFlipped);
return sumHugeInteger;
}

Adding two big numbers pt.2

So in my last question's code was an error. I tried to modify the code which should add two big numbers made as two arrays (I can't use BigIntiger for this, I have to made the method by myself). But it still gives me wrong results of addition.
For example (I already have the constructors for this):
BigNumber dl1 = new BigNumber(1500);
BigNumber dl2 = new BigNumber("987349837937497938943242");
dl3 = dl1.add(dl2);
System.out.println("Result: " + dl3);
It gives me 6575 which is wrong result.
public BigNumber add(BigNumber num2){
char[] m = null;
long y = 0;
long x = 0;
boolean tmpBool = false;
boolean leftIsBigger = false;
String tmpString = "";
int ending = 0;
if (this.n.length >= num2.n.length){
m = new char[this.n.length + 1];
y = num2.n.length;
x = this.n.length;
leftIsBigger = true;
}
else{
m = new char[this.n.length + 1];
y = this.n.length;
x = num2.n.length;
}
for(int i = 0; i < y; i++){
int left = 0;
if(leftIsBigger) left = Character.getNumericValue(this.n[i]);
else left = Character.getNumericValue(num2.n[i]);
for(int j = 0; j < y; j++){
int right = 0;
if(!leftIsBigger) right = Character.getNumericValue(num2.n[j]);
else righta = Character.getNumericValue(this.n[j]);
int z = left + right;
if(tmpBool){
z++;
tmpBool = false;
}
if(z > 9){
tmpBool = true;
z = z%10;
}
m[i] = Character.forDigit(z, 10);
}
ending++;
}
for(int k = ending; k < m.length - 1; k++){
if (leftIsBigger){
if (tmpBool){
int c = Character.getNumericValue(this.n[k]);
if (c > 9){
tmpBool = true;
c = c%10;
m[k] = Character.forDigit(c, 10);
}
else{
tmpBool = false;
m[k] = Character.forDigit((c+1), 10);
}
}
else
m[k] = this.n[k];
}else{
if (tmpBool){
int c = Character.getNumericValue(liczba2.n[k]);
if (c > 9){
tmpBool = true;
c = c%10;
m[k] = Character.forDigit(c, 10);
}
else{
tmpBool = false;
m[k] = Character.forDigit((c+1), 10);
}
}
else
m[k] = this.n[k];
}
}
for (int it = m.length - 1; it >= 0; it--){
tmpString += m[it];
}
BigNumber dl = new BigNumber(tmpString);
return dl;
}
Isn't the problem that in your initial if statement (The one that checks the lengths of the inner arrays) in the else you initialize your m char array to the length of this.n instead of num2.n?
EDIT: Also, the way you've setup your iterations, I assume your inner arrays go from left to right? as in Index 0 is 10^0, index 1 is 10^1, index 2 is 10^2 etc? Otherwise that would be a problem as well. Be mindful that this means you have to revert the inner String char array in the String type constructor.
Your code is too complicated for me to search for the error. The whole "left is longer" logic is flawed, IMHO.
I'd do it thus, assuming we are working on char-Arrays with decimal digits in them:
char [] x, y; // the operands we want to add
char [] result = new char[max (x.length, y.length) + 1];
int xi = x.length-1; // index in 1st operand
int yi = y.length-1; // index in 2nd operand
int ri = result.length-1; // index in result
boolean carry = false;
while (xi >= 0 || yi >= 0) {
char xc = xi >= 0 ? x[xi--] : '0';
char yc = yi >= 0 ? y[yi--] : '0';
char res = xc + yc - '0';
if (carry) res++;
carry = res > '9';
if (carry) res -= 10;
result[ri--] = res;
}
assert (ri == 0);
result[0] = carry ? '1' : '0';
Note that the result array is always 1 char longer than the longest argument. This is not good, as repeated additions will result in longer and longer arrays that carry a lot of 0 in front.
Hence, either copy the result to another array if the last addition did not have a carry bit, or - even better - change the algorithm so that it ignores leading zeroes.
This is left as an exercise.

Java - for loops being skipped

import java.lang.Integer;
import java.util.Arrays;
public class Decimal {
//initialize intance variables
private int decimal;
private String hex;
public static void toHex(String s) {
int decimal = Integer.parseInt(s); //converts the s string into an int for binary conversion.
String hex = null;
int[] binNum = new int[16];
int[] binNumNibble = new int[4]; //A nibble is four bits.
int nibbleTot = 0;
char hexDig = '\0';
char[] cvtdHex = new char[4];
StringBuffer result = new StringBuffer();
for(int a = 32768; a == 1; a /= 2) { //32768 is the value of the largest bit.
int b = 0;//Will top at 15 at the end of the for loop. 15 references the last spot in the binNum array.
if(decimal > a) {
decimal -= a;
binNum[b++] = 1;//Arrays have a default value of zero to all elements. This provides a parsed binary number.
}
}
for(int a = 0; a == 15; a += 3) {
//Copies pieces of the binary number to the binNumNibble array. .arraycopy is used in java 1.5 and lower.
//Arrays.copyOfRange is used in java 1.5 and higher.
System.arraycopy(binNum, a, binNumNibble, 0, 4);
for(int b = 8; b == 1; a += 3) {
int c = 0;
nibbleTot += binNumNibble[c++];
//Converts the single hex value into a hex digit.
if(nibbleTot >= 1 && nibbleTot <= 9) {
hexDig += nibbleTot;
} else if(nibbleTot == 10) {
hexDig = 'A';
} else if(nibbleTot == 11) {
hexDig = 'B';
} else if(nibbleTot == 12) {
hexDig = 'C';
} else if(nibbleTot == 13) {
hexDig = 'D';
} else if(nibbleTot == 14) {
hexDig = 'E';
} else if(nibbleTot == 15) {
hexDig = 'F';
}
cvtdHex[c++] = hexDig;
}
}
//return hex = new String(cvtdHex);
hex = new String(cvtdHex);
System.out.print("Hex: " + hex);
}
}
I can't seem to figure out why variable hex is returned as a blank variable. I've been using System.out.print(); in each for loop and none of them are used, giving me the impression that the for loops are being skipped entirely, but I don't understand why and I'm on a time limit.
Any help is much appreciated, but please don't just paste code. I need to understand this for my computer science class!
yes, your for loops ARE being skipped, since the second part of the for statement is not the break condition but the condition that has to be fullfilled for the loop to run.
So it is NOT
for(a = 0; a == 15; a += 3)
but
for(a = 0; a <= 15; a += 3)
and so on...
The for loops wont execute because of the double ==
How about
String.format("%h", 256)

Evaluate a Math Expression given in string form without using API

I want to evaluate an expression like -4-12-2*12-3-4*5 given in a String form without using API as I am a beginner and want to grasp the logic.
Given below is my unsuccessful attempt to this problem which, if you may like, ignore and suggest appropriate logic.And of course your codes are also welcome :-)
public class SolveExpression3 {
static String testcase1 = "-4-12-2*12-3-4*5";
public static void main(String args[]){
SolveExpression3 testInstance= new SolveExpression3();
int result = testInstance.solve(testcase1);
System.out.println("Result is : "+result);
}
public int solve(String str){
int sum = 1;
int num1 = 0;
int num2 = 0;
String num = "";
int len = str.length();
System.out.println(str);
for (int i = len-1 ; i >= 0; i--)
{
char ch = str.charAt(i);
if(ch == '*')
{
String s = "";
num1 = num2 = 0;
//to get the number on left of *
for (int j = i; j >= 0; j--)
{
char c = str.charAt(j);
if(c == '+' || c == '-' || j == 1)
{
num1 = stringToInt(s);
s = "";
break;
}
else
{
s = c + s;
}
}
//to get the number on right of *
for (int j = i; j <= len; j++)
{
char c = str.charAt(j);
if(c == '+' || c == '-' || j == len-1)
{
num2 = stringToInt(s);
s = "";
break;
}
else
{
s = c + s;
}
}
sum = sum + num1*num2;
}
else
{
num = ch + num;
}
}
len = str.length();
for (int i = len-1; i >= 0; i--)
{
char ch = str.charAt(i);
if(ch==' ')
{}
else if(ch=='+')
{
sum = sum + stringToInt(num);
num = "";
}
else if(ch=='-')
{
sum = sum - stringToInt(num);
num = "";
}
else
{
num = ch + num;
}
}
return sum;
}
public int stringToInt(String str)
{
int number=0;
for(int i = 0; i < str.length(); i++)
{
int num = str.charAt(i) - 48;
number = number*10+num;
}
return number;
}
}
found=true;
static String testcase1 = "-4-12-2*12-3-4*5";
Pattern SEGMENT_PATTERN = Pattern.compile("(\\d+(\\.\\d+)?|\\D+)");
/*\\d-means digit,
\\.-point,
+-one or more times,
?-optional and
\\D-non digit ch*/
Matcher matcher = SEGMENT_PATTERN.matcher(testcase1);
while (found) {
boolean Found = matcher.find();
String segment = matcher.group();//representing a number or an operator
if (Character.isDigit(segment.toCharArray()[0])) {
//is digit
}
else {
//is operator
}
}
This a a solution using a patter to determine if you have a number or and operator,u just have to adapt it a little to your case to computing the result.
You can add all the matches found to an array list than traverse it and test the operators and computer the result.
It works for floating numbers too,ex:"it matches 5.10".
I would suggest a different logic for your purpose.
Usually the logic behind programs algorithms is not different from the logic that you will apply if you have to do the task by hand.
For an expression like your example you would usually do:
Find all the *
For each * compute the result of the operation
Repeat steps 1 and 2 for + and -
Try to implement a recursive descent parser, a tutorial depicting how a calculator can be implemented (in Python but the same concepts apply to java) can be found here http://blog.erezsh.com/how-to-write-a-calculator-in-70-python-lines-by-writing-a-recursive-descent-parser/

Categories

Resources