Java - Summing big Integer with a traditional way - java

I have nested for loop :
String s1 = "4412";
String s2 = "0123";
int k = 0, l = 0, i3 = 0;
for (int i = s1.length() - 1; i < s1.length(); i--) {
for (int j = s2.length() - 1; j <= i; j--) {
k = Integer.parseInt(Character.toString(s1.charAt(i)));
l = Integer.parseInt(Character.toString(s2.charAt(j)));
i3 = k + l;
System.out.println(i3);
}
}
when I am executing this program I am getting 234 as output. because its taking last element value in the s1 and s2 . S2 keep on repeating loop like this:
1
321
2
321
.
.
so 2+3 ,2+2,2+1 like this its working . But what I am expecting is
4412+123 = 4535
can anyone help me out. Thanks in advance

You coud use split with reverse String and loop throw your arrays like this :
String s1 = "4421";
String s2 = "321";
//reverse and split your string
String[] spl1 = new StringBuilder(s1).reverse().toString().split("");//[1,2,4,4]
String[] spl2 = new StringBuilder(s2).reverse().toString().split("");//[1,2,4,4]
String result = "";
int max = spl1.length > spl2.length ? spl1.length : spl2.length;
for (int i = 0; i < max; i++) {
int k = spl1.length <= i ? 0 : Integer.parseInt(spl1[i]);
int l = spl2.length <= i ? 0 : Integer.parseInt(spl2[i]);
result += (k + l) + "";
}
System.out.println(result);//result 2474
The Idea is :
reverser your Strings 12345 -> 54321
split your Strings [5,4,3,2,1]
find the max between your arrays
loop throw your array and make the addition, if the input not exist use 0, spl1.length <= i ? 0 : Integer.parseInt(spl1[i]);
add the addition to your result.
Edit
Lets back to school :
you can use this instead, the idea is simple :
String s1 = "5768956788678907689076890076544765433564376543564";
String s2 = "657687986578905438732902587349320254893";
String[] spl1 = new StringBuilder(s1).reverse().toString().split("");
String[] spl2 = new StringBuilder(s2).reverse().toString().split("");
String result = "";
int max = spl1.length > spl2.length ? spl1.length : spl2.length;
int rest = 0;
int sum;
for (int i = 0; i < max; i++) {
int k = spl1.length <= i ? 0 : Integer.parseInt(spl1[i]);
int l = spl2.length <= i ? 0 : Integer.parseInt(spl2[i]);
sum = k + l + rest;
if (sum > 9) {
rest = 1;
sum = sum - 10;
} else {
rest = 0;
}
result = (i + 1 == max ? sum + rest * 10 : sum) + result;
}
System.out.println(result);

try these code
String s1 = "4412";
String s2 = "0123";
int k = 0, l = 0;
int num1 = 0, num2 = 0, length = 0;
length = s1.length() > s2.length() ? s1.length() : s2.length();
for (int i = 0; i < length; i++) {
if (i < s1.length()) {
k = Integer.parseInt(Character.toString(s1.charAt(i)));
num1 = num1 * 10 + k;
}
if (i < s2.length()) {
l = Integer.parseInt(Character.toString(s2.charAt(i)));
num2 = num2 * 10 + l;
}
}
int result = num1 + num2;
System.out.println(num1 + "+" + num2 + "=" + result);

Related

How to overwrite String in loop

public static String decrypt(final String encryptedText, final int n) {
char [] chars;
String s = encryptedText;
String s1 = "";
int buffer = 0;
int buffer2 = 1;
for (int j = 0; j < n; j++) {
if (j < 1){
chars = s.toCharArray();
}else{
chars = s1.toCharArray();
}
char [] charsUpdate = new char[chars.length];
for (int i = chars.length / 2; i < chars.length; i++) {
if (buffer % 2 == 0 && buffer <= charsUpdate.length){
charsUpdate[buffer] = chars[i];
}
buffer += 2;
}
for (int i = 0; i < chars.length / 2 ; i++) {
if (buffer2 % 2 != 0 && buffer2 < charsUpdate.length){
charsUpdate[buffer2] = chars[i];
}
buffer2 += 2;
}
s = "";
s1 = "";
for (int i = 0; i < charsUpdate.length; i++) {
s = s + charsUpdate[i];
}
s1 = s;
}
return s;
Hi, community. I have some problem here. I try to resolve some task and have stuck in moment when I need to overwrite my String in loop. I need give my old String in start of loop and overwrite this String in end of loop and give new String to start of loop, something like that, but I can't do this, because after first iteration in the start of loop I can see my empty String. Sorry for my shit-code and bad english :)
There are some other issues:
ArrayIndexOutOfBoundsException because the condition buffer <= charsUpdate.length is incorrect
Variables buffer and buffer2 are not reset at the end of the loop, so after recreation of charUpdate array during the 2nd and the following iteration the symbols are not copied from chars to charUpdate
Updated and refactored code may look as follows:
public static String decrypt(final String encryptedText, final int n) {
int len = encryptedText.length();
int half = len / 2;
String s = encryptedText;
for (int j = 0; j < n; j++) {
char[] chars = s.toCharArray();
char[] charsUpdate = new char[len];
for (int i = half, even = 0; i < len && even < len; i++, even += 2) {
charsUpdate[even] = chars[i];
}
for (int i = 0, odd = 1; i < half && odd < len; i++, odd += 2) {
charsUpdate[odd] = chars[i];
}
s = new String(charsUpdate);
}
return s;
}
But I am not sure that it produces valid results.
A simple test shows the following output:
for (int i = 1; i < 5; i++) {
System.out.println("abcdefgh (" + i + ") -> " + decrypt("abcdefgh", i));
}
output:
abcdefgh (1) -> eafbgchd
abcdefgh (2) -> gecahfdb
abcdefgh (3) -> hgfedcba
abcdefgh (4) -> dhcgbfae
----
// for odd length of the input string
abcdefg (1) -> daebfcg
abcdefg (2) -> bdfaceg
abcdefg (3) -> abcdefg
abcdefg (4) -> daebfcg

string multiplication using a big integer class

I'm trying to write a code that multiplies two strings of integers. I'm not too sure where it's going wrong... It works for some numbers, but is horribly wrong for others. I'm not asking for a full solution, but just a hint (I seriously appreciate any help possible) as to where I'm making the obviously silly mistake. Thanks in advance.
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
System.out.print("Please enter a big integer. ");
String t = scan.nextLine();
System.out.print("And another. ");
String s = scan.nextLine();
BigInt a = new BigInt(t);
BigInt b = new BigInt(s);
System.out.println(a + " + " + b + " = " + a.add(b));
System.out.println(a + " - " + b + " = " + a.sub(b));
System.out.println(a + " * " + b + " = " + a.mul(b));
System.out.println(a + " / " + b + " = " + a.div(b));
}
}
class BigInt {
public BigInt() {
n = new int[1];
}
public BigInt(String s) {
n = new int[s.length()];
for (int i = 0; i < n.length; ++i) {
n[n.length - i - 1] = s.charAt(i) - '0' ;
}
}
private BigInt(int[] n) {
this.n = new int[n.length];
for (int i = 0; i < n.length; ++i) {
this.n[i] = n[i];
}
}
public String toString() {
String s = "";
for (int i : n) {
s = i + s;
}
return s;
}
public BigInt mul(BigInt o) {
int carry = 0;
int s = 0;
int digit;
int subtotal = 0;
int total = 0;
int max = n.length > o.n.length ? n.length : o.n.length;
int[] result = new int[n.length + o.n.length];
for (int i = 0; i < o.n.length; ++i) {
int bottom = i <= o.n.length ? o.n[i] : 0;
for (s = 0; s <= n.length; ++s){
int top = s < n.length ? n[s] : 0;
int prod = (top * bottom + carry);
if (s == (max-1)) {
total = Integer.valueOf((String.valueOf(prod) + String.valueOf(subtotal)));
carry = 0;
digit = 0;
subtotal = 0;
break;
}
if (prod < 10) {
digit = prod;
subtotal += digit;
carry = 0;
}
if (prod >= 10); {
digit = prod % 10;
carry = prod / 10;
subtotal += digit;
}
}
result[i] = total;
}
return new BigInt(trim(result));
}
private int[] trim(int[] nums) {
int size = nums.length;
for (int i = nums.length - 1; i > 0; --i) {
if (nums[i] != 0) {
break;
}
--size;
}
int[] res = new int[size];
for (int i = 0; i < size; ++i) {
res[i] = nums[i];
}
return res;
}
private int[] n;
}
A quick test using:
for (int x = 0; x < 10; x++) {
for (int y = 0; y < 10; y++) {
System.out.println(x + " * " + y + " = " + new BigInt(Integer.toString(x)).mul(new BigInt(Integer.toString(y))));
}
}
demonstrates that somehow your multiply of x * y is actually multiplying by 10x * y. That should give you a clear hint to the problem.

Large addition using String

Given two numbers as input, return the sum of the numbers. Note that the numbers can be very large and hence are provided as Strings
Sample Input #1:
add("2354725234782357","9999999999999999999999999988888888888")
Sample Output #1:
10000000000000000000002354714123671245
Implementation:
public String add(String str1, String str2) {
int max = str1.length() > str2.length() ? str1.length() : str2.length();
int n1[] = new int[max];
int n2[] = new int[max];
for (int i = 0; i < str1.length(); i++) {
n1[i] = str1.charAt(str1.length() - 1 - i);
}
for (int i = 0; i < str2.length(); i++) {
n2[i] = str2.charAt(str2.length() - 1 - i);
}
int carry = 0;
int sum[] = new int[max + 1];
int k = 0;
for (k = 0; k < max; k++) {
sum[k] = (n1[k] + n2[k] + carry) % 10;
if ((n1[k] + n2[k] + carry) >= 10) {
carry = 1;
} else {
carry = 0;
}
}
sum[max] = carry;
String result = "";
return result;
}
I have implemented my logic but I don't know how to get the output as a string.
Why don't use BigInteger this is much easier and still native java.
private static String add(String s1, String s2)
{
BigInteger n1 = new BigInteger(s1);
BigInteger n2 = new BigInteger(s2);
return n1.add(n2).toString();
}
Anyway, there is one bug in your Code. Dont cast char to int the ascii value is used, which is wrong. Parse it with Character.getNumericValue();
If you have done this, you can concat sum array to a string in reversed order.
Solution:
public static String add(String str1, String str2) {
int max = str1.length() > str2.length() ? str1.length() : str2.length();
int n1[] = new int[max];
int n2[] = new int[max];
for (int i = 0; i < str1.length(); i++)
{
// conver char to int
n1[i] = Character.getNumericValue(str1.charAt(str1.length() - 1 - i));
}
for (int i = 0; i < str2.length(); i++) {
// conver char to int
n2[i] = Character.getNumericValue(str2.charAt(str2.length() - 1 - i));
}
int carry = 0;
int sum[] = new int[max + 1];
int k = 0;
for (k = 0; k < max; k++) {
sum[k] = (n1[k] + n2[k] + carry) % 10;
if ((n1[k] + n2[k] + carry) >= 10) {
carry = 1;
} else {
carry = 0;
}
}
sum[max] = carry;
// concat array in reverse order
StringBuilder sb = new StringBuilder();
for(int i = sum.length - 1; i >= 0; i--)
sb.append(sum[i]);
return sb.toString();
}
Input
add("2354725234782357","9999999999999999999999999988888888888")
Output
10000000000000000000002354714123671245
There is a logic error in your code: you are adding the char value of each integer instead of the integer themselves. You can get the numeric value of a char using Character.getNumericValue(char ch).
Then, you can construct the resulting String by looping over the sum array. The loop must be done in reverse order (to get the correct order). Beware of the first value sum[max], if it is 0, we must not add it to the String (otherwise, we will get a value padded with a 0):
public static String add(String str1, String str2) {
int max = Math.max(str1.length(), str2.length());
int n1[] = new int[max];
int n2[] = new int[max];
for (int i = 0; i < str1.length(); i++) {
//n1[i] = str1.charAt(str1.length() - 1 - i);
n1[i] = Character.getNumericValue(str1.charAt(str1.length() - 1 - i));
}
for (int i = 0; i < str2.length(); i++) {
//n2[i] = str2.charAt(str2.length() - 1 - i);
n2[i] = Character.getNumericValue(str2.charAt(str2.length() - 1 - i));
}
int carry = 0;
int sum[] = new int[max + 1];
int k = 0;
for (k = 0; k < max; k++) {
sum[k] = (n1[k] + n2[k] + carry) % 10;
if ((n1[k] + n2[k] + carry) >= 10) {
carry = 1;
} else {
carry = 0;
}
}
sum[max] = carry;
StringBuilder sb = new StringBuilder();
if (sum[max] > 0) {
sb.append(String.valueOf(sum[max]));
}
for (int i = max - 1; i >= 0; i--) {
sb.append(String.valueOf(sum[i]));
}
return sb.toString();
}
Note that you can also replace
int max = str1.length() > str2.length() ? str1.length() : str2.length();
with
int max = Math.max(str1.length(), str2.length());
I have modified some code:(you can avoid array creation)
public static String add(String str1, String str2) {
int carry=0;
StringBuilder sum=new StringBuilder();
int l1=str1.length();
int l2=str2.length();
while(l1>0 && l2>0){
int s=Character.getNumericValue(str1.charAt(--l1))+Character.getNumericValue(str2.charAt(--l2))+carry;
if(s<10){
sum.append(s);
}else{
sum.append(s%10);
carry=s/10;
}
}
if(l2>0){
while(l2>0){
int s=Character.getNumericValue(str2.charAt(--l2))+carry;
if(s<10){
sum.append(s);
}else{
sum.append(s%10);
carry=s/10;
}
}
}
if(l1>0){
while(l2>0){
int s=Character.getNumericValue(str1.charAt(--l1))+carry;
if(s<10){
sum.append(s);
}else{
sum.append(s%10);
carry=s/10;
}
}
}
if(carry>0){
sum.append(carry);
}
return sum.reverse().toString();
}
You can use a StringBuilder to append all the digits from your int[] from max to 0.
StringBuilder sb = new StringBuilder();
for (int i=max; i>=0; i--)
{
sb.append(String.valueOf(sum[i]));
}
String result = sb.toString();
You can also improve this to skip leading zeroes if you want:
boolean leadingZero = true;
StringBuilder sb = new StringBuilder();
for (int i=max; i>=0; i--)
{
if (sum[i] != 0)
{
leadingZero=false;
}
if (!leadingZero)
{
sb.append(String.valueOf(sum[i]));
}
}
String result = sb.toString();

Suffix Array Implementation Error

I keep getting compiler errors with an implementation of a suffix array by Arrays.sort.
I get the following errors:
a cannot be resolved to a variable
Syntax error on token ",", . expected
Syntax error on token "-", -- expected
a cannot be resolved to a variable
b cannot be resolved to a variable
In the following code:
import java.util.*;
public class SuffixArray {
// sort suffixes of S in O(n*log(n))
public static int[] suffixArray(CharSequence S) {
int n = S.length();
Integer[] order = new Integer[n];
for (int i = 0; i < n; i++)
order[i] = n - 1 - i;
// stable sort of characters
Arrays.sort(order, (a, b) -> Character.compare(S.charAt(a), S.charAt(b)));
int[] sa = new int[n];
int[] classes = new int[n];
for (int i = 0; i < n; i++) {
sa[i] = order[i];
classes[i] = S.charAt(i);
}
// sa[i] - suffix on i'th position after sorting by first len characters
// classes[i] - equivalence class of the i'th suffix after sorting by first len characters
for (int len = 1; len < n; len *= 2) {
int[] c = classes.clone();
for (int i = 0; i < n; i++) {
// condition sa[i - 1] + len < n simulates 0-symbol at the end of the string
// a separate class is created for each suffix followed by simulated 0-symbol
classes[sa[i]] = i > 0 && c[sa[i - 1]] == c[sa[i]] && sa[i - 1] + len < n && c[sa[i - 1] + len / 2] == c[sa[i] + len / 2] ? classes[sa[i - 1]] : i;
}
// Suffixes are already sorted by first len characters
// Now sort suffixes by first len * 2 characters
int[] cnt = new int[n];
for (int i = 0; i < n; i++)
cnt[i] = i;
int[] s = sa.clone();
for (int i = 0; i < n; i++) {
// s[i] - order of suffixes sorted by first len characters
// (s[i] - len) - order of suffixes sorted only by second len characters
int s1 = s[i] - len;
// sort only suffixes of length > len, others are already sorted
if (s1 >= 0)
sa[cnt[classes[s1]]++] = s1;
}
}
return sa;
}
// sort rotations of S in O(n*log(n))
public static int[] rotationArray(CharSequence S) {
int n = S.length();
Integer[] order = new Integer[n];
for (int i = 0; i < n; i++)
order[i] = i;
Arrays.sort(order, (a, b) -> Character.compare(S.charAt(a), S.charAt(b)));
int[] sa = new int[n];
int[] classes = new int[n];
for (int i = 0; i < n; i++) {
sa[i] = order[i];
classes[i] = S.charAt(i);
}
for (int len = 1; len < n; len *= 2) {
int[] c = classes.clone();
for (int i = 0; i < n; i++)
classes[sa[i]] = i > 0 && c[sa[i - 1]] == c[sa[i]] && c[(sa[i - 1] + len / 2) % n] == c[(sa[i] + len / 2) % n] ? classes[sa[i - 1]] : i;
int[] cnt = new int[n];
for (int i = 0; i < n; i++)
cnt[i] = i;
int[] s = sa.clone();
for (int i = 0; i < n; i++) {
int s1 = (s[i] - len + n) % n;
sa[cnt[classes[s1]]++] = s1;
}
}
return sa;
}
// longest common prefixes array in O(n)
public static int[] lcp(int[] sa, CharSequence s) {
int n = sa.length;
int[] rank = new int[n];
for (int i = 0; i < n; i++)
rank[sa[i]] = i;
int[] lcp = new int[n - 1];
for (int i = 0, h = 0; i < n; i++) {
if (rank[i] < n - 1) {
for (int j = sa[rank[i] + 1]; Math.max(i, j) + h < s.length() && s.charAt(i + h) == s.charAt(j + h); ++h)
;
lcp[rank[i]] = h;
if (h > 0)
--h;
}
}
return lcp;
}
// Usage example
public static void main(String[] args) {
String s1 = "abcab";
int[] sa1 = suffixArray(s1);
// print suffixes in lexicographic order
for (int p : sa1)
System.out.println(s1.substring(p));
System.out.println("lcp = " + Arrays.toString(lcp(sa1, s1)));
// random test
Random rnd = new Random(1);
for (int step = 0; step < 100000; step++) {
int n = rnd.nextInt(100) + 1;
StringBuilder s = new StringBuilder();
for (int i = 0; i < n; i++)
s.append((char) ('\1' + rnd.nextInt(10)));
int[] sa = suffixArray(s);
int[] ra = rotationArray(s.toString() + '\0');
int[] lcp = lcp(sa, s);
for (int i = 0; i + 1 < n; i++) {
String a = s.substring(sa[i]);
String b = s.substring(sa[i + 1]);
if (a.compareTo(b) >= 0
|| !a.substring(0, lcp[i]).equals(b.substring(0, lcp[i]))
|| (a + " ").charAt(lcp[i]) == (b + " ").charAt(lcp[i])
|| sa[i] != ra[i + 1])
throw new RuntimeException();
}
}
System.out.println("Test passed");
}
}
a cannot be resolved to a variable
Syntax error on token ",", . expected
Syntax error on token "-", -- expected
a cannot be resolved to a variable
b cannot be resolved to a variable
You are getting these errors on this line (which appears twice in the code) :
Arrays.sort(order, (a, b) -> Character.compare(S.charAt(a), S.charAt(b)));
^^ ^ ^ ^
The reason must be that you are not compiling the code in Java 8. Lambda expressions require Java 8.

Java, converting string to integers then add all the integers together

I need to add 8 numbers together from a string.E.g. If someone enters say 1234 it will add the numbers together 1 + 2 + 3 + 4 = 10 then 1 + 1 = 2. I have done this so far. I cannot figure out how to add these numbers up using a for loop.
String num2;
String num3;
num2 = (jTextField1.getText());
num3 = num2.replaceAll("[/:.,-0]", "");
String[] result = num3.split("");
int inte = Integer.parseInt(num3);
for (int i = 0; i < 8; i++){
// Stuck
}
How about that (I skipped exceptions...):
String[] sNums = jTextField1.getText().replaceAll("[^1-9]", "").split("(?<!^)");
int sum = 0;
for (String s : sNums) {
sum += Integer.parseInt(s); // add all digits
}
while (sum > 9) { // add all digits of the number, until left with one-digit number
int temp = 0;
while (sum > 0) {
temp += sum % 10;
sum = sum / 10;
}
sum = temp;
}
For every element in result, you need to convert it to an int, then add it to some variable, maybe called sum.
int sum = 0;
// for every String in the result array
for (int i = 0; i < BOUND; i++) {
// convert s[i] to int value
// add the int value to sum
}
This pseudo code should do it without splitting, arrays etc.
String s = "1234.56";
int sum = 0;
int i = 0;
while (i < s.length()) {
char c = s.charAt(i)
if (c >= '0' && c <= '9') sum += c - '0';
i++;
}
Should result in sum = 21
public static int addAll(String str) {
str = str.replaceAll("[^1-9]", "");
if (str.length() == 0)
return 0;
char[] c = str.toCharArray();
Integer result = c[0] - 48;
while (c.length > 1) {
result = 0;
for (int i = 0; i < c.length; i++) {
result += c[i] - 48;
}
c = result.toString().toCharArray();
}
return result;
}

Categories

Resources