Multiply large string numbers without using Big-Integer library - java

I coded a simple solution which multiplied 2 integers given as strings and returned the product as a string. But it doesn't work for big values and I'm not allowed to use the Big-Integer library.
This is my current solution.
class Solution {
public String multiply(String num1, String num2) {
int numOne = 0;
int numTwo = 0;
for(char c : num1.toCharArray()){
if((int)(c-'0') >= 0 && (int)(c-'0') <= 9){
numOne = numOne*10 + (int)(c-'0');
}
}
for(char c : num2.toCharArray()){
if((int)(c-'0') >= 0 && (int)(c-'0') <= 9){
numTwo = numTwo*10 + (int)(c-'0');
}
}
return numOne*numTwo + "";
}
}
I got an error in the following test case:
Input:
"123456789"
"987654321"
Output:
"-67153019"
Expected:
"121932631112635269"
What changes should I make so as to be able to multiply large numbers also?

For this, you can refer to the Karatsuba Multiplication algorithm.
You can do this too.
If any of the numbers is negative pick up from substring 1 to n.
Start from the last digit of second number.
Multiply it with the first number. store the result.
Do it with all the numbers of the second numbers and keep adding the result of the previous step to current step with ith shift in the position.
There are samples of this solution too on the internet. You will find it.

Related

How would I add two int that are in the same array to each other and convert them into an int. In the Luhn Algorithm

I am trying to add two parts of an array together to go into an int value. I am using Luhn algorithm to figure out of a credit card is a valid credit card. We are only using 6 digit credit card's just to make sure no one enter's a real credit card number. The part I am confused on is when I go to split a number that is above 10 and add it together. Example if the algorithm was to give me 12 I would need to separate it into 1 and 2 and then add them together to equal 3. I believe I am splitting it currently in the code but when I go to add them together I get some number that makes no since. here is a section of the code with some notes about it.
I have printed out numbers in certain places to show myself what is going on in certain places. I have also added in some comments that say that either the number that is printed out is what is expected, and some comments for when there isn't something I expected
int[] cardNumber = new int[]{ 1,2,3,4,5,5};
int doubleVariablesum = 0;
int singleVariablesum = 0;
int totalSum = 0;
int cutOffVar = 0;
String temp2;
for (int i = cardNumber.length - 1; i >= 0;) {
int tempSum = 0;
int temp = cardNumber[i];
temp = temp * 2;
System.out.println("This is the temp at temp * 2: " + temp);
temp2 = Integer.toString(temp);
if (temp2.length() == 1) {
System.out.println("Temp2 char 0: "+ temp2.charAt(0));
// this prints out the correct number
// Example: if there number should be 4 it will print 4
tempSum = temp2.charAt(0);
System.out.println("This is tempSum == 1: " + tempSum);
// when this goes to add temp2.charAt(0) which should be 4 it prints out //something like 56
} else {
System.out.println("TEMP2 char 0 and char 1: " + temp2.charAt(0) + " " + temp2.charAt(1));
// this prints out the correct number successfully spited
tempSum = temp2.charAt(0) + temp2.charAt(1);
System.out.println("This is tempSum != 1: " + tempSum);
// but here it when I try to add them together it is giving me something
// like 97 which doesn't make since for the numbers I am giving it
}
doubleVariablesum = tempSum + doubleVariablesum;
System.out.println("This is the Double variable: " + doubleVariablesum);
System.out.println();
i = i - 2;
}
Since you are converting the number to a string to split the integer, and then trying to add them back together. You're essentially adding the two characters numerical values together which is giving you that odd number. You would need to convert it back to an integer, which you can do by using
Integer.parseInt(String.valueOf(temp2.charAt(0)))
When adding char symbols '0' and '1' their ASCII values are added - not numbers 0 and 1.
It is possible to use method Character::getNumericValue or just subtract '0' when converting digit symbol to int.
However, it is also possible to calculate sum of digits in a 2-digit number without any conversion to String and char manipulation like this:
int sum2digits = sum / 10 + sum % 10; // sum / 10 always returns 1 if sum is a total of 2 digits
Seems like charAt() type casts into integer value, but the ascii one. Hence for the characters '0' and '1', the numbers 48 and 49 are returned resulting in a sum of 97. To fix this, you could just assign temp2 to (temp / 10) + (temp % 10). Which actually splits a two digit integer and adds their sum.
You need to be aware of the following when dealing with char and String
Assigning the result of charAt(index) to an int will assign the ASCII value and not the actual integer value. To get the actual value you need to String.valueOf(temp2.charAt(0)).
The result of concatenating chars is the sum of the ASCII values.
eg if char c = '1'; System.out.println(c + c); will print "98" not "11".
However System.out.println("" + c + c); will print "11". Note the "" will force String concatenation.

calculate Check Number in Java

Not sure if anyone can explain this to me or help me.
I have a 15 Digit Number of which I want to multiply each even number by 2 unless the even number is greater than 9. If it is this needs to be subtracted by 9 to give me an integer that again I can multiply by 2. Once I have all the even numbers multiplied by 2 i need to add them all together with the odd numbers.
Does that make sense.
UPDATE ***
so i have a number say 49209999856459. for that number I am looking to get the even integer so for example the first even one would be 4 then the second would be 2 and so on.
If one of those even numbers are multiplied by 2 then it might be above 9 so I want to subtract 9 to then use the remainder as the even number in its place.
SO !!!
Multiply by 2 the value of each even digit starting from index 0 and then each even index. In each case, if the resulting value is greater than 9, subtract 9 from it (which reduces larger values to a single digit). Leave the values of the digits at the odd indexes unchanged.
public String calculateCheckNumber()
String firstFifteen = longNumber.substring(0,15) ;
int i, checkSum = 0, totalSum = 0;
for (i = 0; i<firstFifteen.length(); i += 2) {
while (i < 9)
i *= 2;
if (i > 9)
i -= 9 ;
}
Was one option I was trying but it honestly I cant seem to get my head around it.
Any Help would be greatly appreciated.
Well, here is one approach. This uses the ternary (?:) operator to condense the operations. Edited base on clarification from the OP. The example you gave is actually a 14 digit string. But the following will work with any number of digits if they start out in a string. If you have a long value, then you can create the character array using:
long v = 49209999856459L;
char[] d = Long.toString(v).toCharArray();
Here is the main algorithm.
String s = "49209999856459";
int sum = 0;
char[] d = s.toCharArray();
for (int i = 0; i < d.length; i++) {
int v = d[i] - '0';
// The even digit will only be greater than 9 after
// doubling if it is >= 5 before.
sum += ((i % 2) == 1) ? v : (v >= 5) ? v+v-9 : v+v;
}
System.out.println(sum);
Prints
86

How many bases b are there such that the base b representation of number starts with a 1?

The problem statement is :
Problem Statement-: Altaf has recently learned about number bases and is becoming fascinated.
Altaf learned that for bases greater than ten, new digit symbols need to be introduced, and that the convention is to use the first few letters of the English alphabet. For example, in base 16, the digits are 0123456789ABCDEF. Altaf thought that this is unsustainable; the English alphabet only has 26 letters, so this scheme can only work up to base 36. But this is no problem for Altaf, because Altaf is very creative and can just invent new digit symbols when she needs them. (Altaf is very creative.)
Altaf also noticed that in base two, all positive integers start with the digit 1! However, this is the only base where this is true. So naturally, Altaf wonders: Given some integer N, how many bases b are there such that the base-b representation of N starts with a 1?
Input Format :
The first line of the input contains an integer T denoting the number of test cases. The description of T test cases follows.
Each test case consists of one line containing a single integer N (in base ten).
Output Format :
For each test case, output a single line containing the number of bases b, or INFINITY if there are an infinite number of them.
Constraints:
1 <= T <= 10^5
0 <= N < 10^12
Sample Input
4
6
9
11
24
Sample Output:
4
7
8
14
Explanation:
In the first test case, 6 has a leading digit 1 in bases 2, 4, 5 and 6: 610 = 1102 = 124 = 115 = 106.
I trying this in java , But at some point my loop is not working it only takes the first value and after that it will come out of the loop!! Thank you
My code :
import java.util.*;
public class MyClass {
public static void main(String args[]) {
Scanner sc = new Scanner(System.in);
long n,i,j,k,m;
long count=0,rem1,index;
long rem[];
rem = new long[(int)100];
int t = sc.nextInt();
for(i=1;i<=t;i++)
{
n = sc.nextInt();
j=2;
while(j<=n)
{
// for(j=2;j<=n;j++)
// {
index=0;
m = j;
while(n>0)
{
rem1 = n%m;
rem[(int)index++] = rem1;
n = (long) (n / m);
}
// for(k=index-1;k>=0;k--)
// {
if(rem[1]==1)
{
count++;
}
// }
j++;
}
System.out.println(count);
// }
}
}
}
I'm not sure I follow the logic in the loop (and, by your own admission, there's a problem there).
The logic of the loop (i.e., "how many bases represent the number N with a representation starting by 1"), can be greatly simplified.
The first step is finding the highest power of the base B required to represent the number N. This is given by logb(n), truncated to the nearest integer. Java doesn't have a built-in log function with a variable base, but you can get this result by calculating log(n)/log(b).
Then, you need to find the digit in this position. This can be calculated by dividing N by Bpower using integer division.
From there on, you just need to check if the result is 1, and if so, record it.
Put it all together and you'll end up with something like this:
private static int howManyBasesStartWithOne(int num) {
int count = 0;
for (int i = 2; i <= num; ++i) {
int highestBase = (int) (Math.log(num) / Math.log(i));
int leadingDigit = num / (int) Math.pow(i, highestBase);
if (leadingDigit == 1) {
++count;
}
}
return count;
}

sum of first and last digit in the integer

The method written in the below code needs to take integer and result sum of 1st digit and last digit in the integer.
NOTE: The reason i am asking this question though i got to know the correct solution is i need to understand why my code is not working also as that makes me a better programmer please help.
public class FirstLastDigitSum {
public static int sumFirstAndLastDigit(int number)//to add first and last
//digits of a given interger
{
int firstdigit=0;
int lastdigit=0;
if(number>=0 && number<=9)
{
return number+number;
}
else if(number>9)
{
lastdigit=number%10;
while(number>0)
{
number/=10;
if(number<=9 & number>=0){
firstdigit=number;
}
}
return firstdigit+lastdigit;
}
else
return -1;
}
public static void main(String[] args)
{
System.out.println(sumFirstAndLastDigit(121));
}
}
In the above code if i keep number/=10 after if block like below
if(number<=9 & number>=0){
firstdigit=number;
}
number/=10;
then my code is giving proper results. like if i input 121 to the method as first digit is 1 and second digit is 1 it is summing both and giving me result 2. which is absolutely correct
But if keep number/=10 above the if block like below
number/=10;
if(number<=9 & number>=0){
firstdigit=number;
}
Then my code is not giving proper result it is giving only last number which is 1.
I am not at all understanding why this is happening can any one explain please.
Lets break this up into two parts. Get the last digit of the number, and getting the first digit of the number.
The first part of the problem is easy. Its exactly what you already have; just take modulo 10 of the number.
int lastdigit = number % 10;
The second part is a little trickier, but not too much. While the number is greater than 10 divide it by 10 (using integers you will have truncation for the remainder). One problem I see in your solution is that you keep checking the value even after a digit is discovered. That means if the value was 1234, you correctly find 1, but then overwrite it to 0 with an extra loop iteration
int firstdigit = number;
while (firstdigit >= 10) {
firstdigit /= 10;
}
And that's it, you are done. Just return the value.
return firstdigit + lastdigit;
If the number is less than 0 then return -1. Otherwise the last number can be found by modulus 10, and the first number found by dividing by 10 until that number is less than 10.
public static int sumFirstAndLastDigit(int number) {
if (number < 0) {
return -1;
}
int last = number % 10;
int first = number;
while (first >= 10) {
first = first / 10;
}
return first + last;
}
In this case:
while(number>0)
{
number/=10;
if(number<=9 & number>=0){
firstdigit=number;
}
}
Note that you change number after you check number > 0. That means that number can be 0 when reaches the if statement and if it is 0 it will be accepted as first digit because it satisfies the condition number<=9 & number>=0. As an example, when you test it with 121 you have this values for number 121, 12, 1 and 0. The last one satisfies the if statement and set first digit to 0.
In this case:
while(number>0)
{
if(number<=9 & number>=0){
firstdigit=number;
}
number/=10;
}
You change number before you check number > 0. That means that the if statement will never have a number = 0 and firstdigit will never be 0. As an example, when you test it with 121 you have this values for number 121, 12, and 1. The last one satisfies the if statement and set first digit to 1. After that you divide number by zero and it becomes 0 and it stop the while loop.
This is not a direct solution to your problem, but we can fairly easily handle this using regex and the base methods:
int number = 12345678;
String val = String.valueOf(number);
val = val.replaceAll("(?<=\\d)\\d+(?=\\d)", "");
number = Integer.parseInt(val);
int sum = number % 10 + number / 10;
System.out.println(sum);

Find lowest odd number in a loop

I know this code is wrong. I'm a beginner so bear with me.
I need to find the lowest odd number but it keeps coming up as zero no matter what numbers are entered. I need to initialize 'lowest' but how/where do I initialize it?
lowest = 0 is causing a problem but I'm not sure where to initialize lowest
class Odd
{
public static void main(String[] args)
{
int number; //the number entered by the user
int input; //the amount of numbers to be entered by the user
int index;
int lowest = 0; //lowest odd number
System.out.println("How many numbers? ");
input = EasyIn.getInt();
for (index = 1; index <= input ; index ++)
{
System.out.println("Enter number " + index + ":" );
number = EasyIn.getInt();
if ((number % 2 == 1) && (number < lowest))
{
lowest = number;
}
}
System.out.println("The lowest odd number entered was " + lowest);
}
}
If you're sure your input isn't empty, a solution is to initialize lowest to a big enough value :
int lowest = Integer.MAX_VALUE;
This ways all values will be smaller, so lowest will be one of the values of your input.
You are starting at 0 so you will not get a value larger. If you start like this
int lowest = Integer.MAX_VALUE;
Also (n % 2) will only be 1 for positive numbers. If you want to test for odd negative numbers you want (n & 1) != 0
Note: Integer.MAX_VALUE is an odd number so even if this is the only value it will be the maximum. However, if you want to be able to tell the difference between some one entering this value and no odd values you can use this instead.
long lowest = Long.MAX_VALUE;
This will allow you to tell the difference between Integer.MAX_VALUE being entered and no value as Long.MAX_VALUE is much higher.
You initialise lowest as 0 and then look for numbers lower than it (and odd).
I'd initialise it as EasyIn.getInt() so it's the first number in your list to check through.

Categories

Resources