Java get each digit from 2 strings and calculate it - java

The task is asking me to insert 2 strings of a very huge number and sum them from right to left like the way we studied in primary school like:
23 + 28 =
(2 + 2 + <1> (this is the left 1 >>> keep reading ))(3 + 8 (give the left <1> from 11 sum with the two front numbers)) =
51.
The algorithm is ok but when I try to do like (just default that the 2 number has the same length so I get lenA and not greater than 10 to make easier):
int len = a.length();
String result="";
for(int i = len; i>0 ; i--) { //<- We only need it to loop how many times
result = Integer.valueOf( a.charAt(len-1) ) + Integer.valueOf( b.charAt(len-1) ) + "" + result;//<<<because we sum them from right to left
lenA--; lenB--;
}
and that (<<<) line always give me the error.
This is just one of a many ways I tried if it's wrong and you have a solution, please just guide me, sometimes i think too much and forgot a lot of small details :))
So the question here is how can i change it from a digit of String to Integer, calculate it and print out String again. But after I read the .charAt() info it said: "Returns the char value at the specified index." so the question maybe confuse between the first question and Convert from a digit from String use charAt -> become Char then convert Char to Integer to calculate and finally convert back to String so that I can + with String result.
I tried a lot of way but still can't solve it.

int lena = a.length();
int lenb = b.length();
int inta[] = new int[lena];
int intb[] = new int[lenb];
int result[];
int carry = 0, maxLen = 0, tempResult;
if(lena >lenb)
maxLen = lena + 1;
else
maxLen = lenb + 1;
result = new int[maxLen];
for(int i = lena - 1; i>=0 ; i--) {
inta[i] = Integer.valueOf( a.charAt(i) );
}
for(int i = lenb - 1; i>0 ; i--) {
intb[i] = Integer.valueOf( b.charAt(i) );
}
for(int i = maxLen - 1; i >= 0; i--) {
result[i] = 0;
}
for(int i = 1; i < maxLen - 1; i++) {
tempResult = 0;
if(lena > i)
tempResult += inta[lena - i];
if(lenb > i)
tempResult += intb[lenb - i];
result[maxSize - i] += tempResult % 10;
result[maxSize - i - 1] = tempResult / 10;
}
String res = "";
for(int i = 0; i < maxLen; i++) {
res += result[i];
}
System.out.println(res);
I think that would do what you want and will avoid most simple mistakes (couldn't try it, no acces to an IDE).
I actually separate the two string into their inside number and then add them into the result tab.
Then I put the result tab into a string that I print.

Related

A question about for-loop condition in java

I am working on the problem below:
Given a non-empty array of digits representing a non-negative integer, plus one to the integer.
Eg:[1,2,3] Output:[1,2,4]
My approach is usring carry to calculate the singular digit from end to start.
I got 2 version of this problem. First one does not work when the input is [1,4,4,9].However, the second one is wokring. In the second version, I change the for-loop condition. I wonder why this happened? Could anyone help me with this? Any help would be appreciated! Thanks!
Version 1:
public static int[] plusOne(int[] digits) {
int sum = 0;
int len = digits.length;
int carry = (digits[digits.length -1]+1)/10;
digits[digits.length -1] = (digits[digits.length -1]+1)%10;
for (int j = len-2;j >= 0;j--){
carry = (digits[j]+carry)/10 ;
digits[j] =(digits[j]+carry)%10 ;
}
if (carry==0) return digits;
else{
int[] res = new int[len+1];
res[0] = 1;
int i = 0;
for (int j=1;j<res.length;j++){
res[j] = digits [i++];
}
return res;
}
}
Version 2:
public static int[] plusOne(int[] digits) {
int sum = 0;
int len = digits.length;
int carry = (digits[digits.length -1]+1)/10;
digits[digits.length -1] = (digits[digits.length -1]+1)%10;
for (int j = len-2;j >= 0;j--){
int temp = digits[j]+carry;
carry = (temp)/10 ;
digits[j] =(temp)%10 ;
}
if (carry==0) return digits;
else{
int[] res = new int[len+1];
res[0] = 1;
int i = 0;
for (int j=1;j<res.length;j++){
res[j] = digits [i++];
}
return res;
}
Posting a longer answer after all...
The only difference in those two code snippets are the first for loops. Your first example doesn't work as you expected.
for (int j = len-2;j >= 0;j--){
carry = (digits[j]+carry)/10 ;
digits[j] =(digits[j]+carry)%10 ;
}
Here the problem lies in the line carry = (digits[j]+carry)/10 ;
You're changing the variable carry, but this value is being used in the next line.
Let's say, carry was 1 and digits[j] is 5. After carry = (digits[j]+carry)/10; the variable carry changed to 0 and the subsequent calculation of digits[j] results in 5 instead of 6.
The second example works, because you're introducing an intermediate variable temp:
for (int j = len-2;j >= 0;j--){
int temp = digits[j]+carry;
carry = (temp)/10 ;
digits[j] =(temp)%10 ;
}
temp is calculated once and then only read from, so carry and digits are not dependant on each other any more. In turn, you will get the result you expect.

How to print a array with different conditions

I'm trying to print values by mapping one to another array. Below is my sample code.
int k;
int m=0;
int NUMBER_OF_TIME = 2; // this value will be constant won't change
int[] timeReadings = {1,2,3,4,5,6,7,8,9,10,11,12};
String array1[] = {"A, B"};
System.out.println("-----------------"+"\n");
for (k=0; k < array1.length; k++) {
inner: for (; m < timeReadings.length; m++) {
if(m==NUMBER_OF_TIME && k!=0) {
System.out.println(array1[k]+"\n");
System.out.println(timeReadings[m]+"\n");
break inner;
}else
System.out.println(array1[k]+"\n");
System.out.println(timeReadings[m]+"\n");
}System.out.println("-----------------"+"\n");
}
Expected output is:
When user NUMBER_OF_TIME =2, the output should be like this.
--------------------
A
1 2 3 4 5 6
--------------------
B
7 8 9 10 11 12
--------------------
If i correctly understood what you want, this should work :
int NUMBER_OF_TIME = 2;
int n = 1;
boolean bool = true;
int[] timeReadings = {1,2,3,4,5,6,7,8,9,10,11,12};
String array1[] = {"A", "B"};
System.out.print("-----------------"+ System.lineSeparator());
System.out.print(array1[0] + System.lineSeparator());
for(int i : timeReadings) {
System.out.print(i + " ");
if(n > (timeReadings.length / NUMBER_OF_TIME) - 1 && bool) {
System.out.println(System.lineSeparator()+"-----------------");
System.out.print(array1[1] + System.lineSeparator());
bool = false;
}
n++;
}
System.out.println(System.lineSeparator()+"-----------------");
If this doesn't work for you, please provide more output examples, as others already asked.
Edit : Modified the code to output what you expect.

Multiply the number based on its length

I wanted to multiply the number based on its String length.
For example
String s = "153";
So, here the length of the above string is 3. So i wanted to multiply each number in the string 3 times (which is the actual length of the string)
Something like below
Here the length is 3
Something like this 1*1*1+5*5*5+3*3*3
Can anyone please help me in that?
This is what I have tried:
int number = 153;
String originalNumber = number+"";
char[] ch = originalNumber.toCharArray();
int length = originalNumber.length();
for (int i = 0; i < ch.length; i++) {
char c = ch[i];
for (int j = 0; j < ch.length; j++) {
// I'm stuck here
}
}
So you have to take each digit and take it to the power of the length of your string, then add all those results up.
You could do the following:
String s = "153";
int result = 0;
for (char n : s.toCharArray())
if (Character.isDigit(n))
result += Math.pow(Character.getNumericValue(n), s.length());
System.out.println(result);
It prints:
153
I added a safety check to see if the char is actually a digit (if (Character.isDigit(n))).
Classic solution : You need to turn each char, in an int then use use power to the length and sum all :
int res = 0;
for (int i = 0; i < ch.length; i++) {
int newNb = (int) Math.pow(Character.digit(ch[i], 10), ch.length);
res += newNb;
}
for-each loop solution
for (char c : ch) {
int newNb = (int) Math.pow(c - '0', ch.length);
res += newNb;
}
To turn a char c to its corresponding int value you can do :
int a = Character.getNumericValue(c);
int a = Character.digit(c, 10);
int a = c - '0';
You could simply iterate over each digit of the given string and calculate it's power. It is better to use str.charAt(i) instead of str.toCharArray() to not create additional char[].
public static int multiplyNumberLength(String str) {
int res = 0;
for (int i = 0; i < str.length(); i++)
if (Character.isDigit(str.charAt(i)))
res += Math.pow(str.charAt(i) - '0', str.length());
return res;
}
To turn a character back into a digit:
char c = ch[i];
int digit = c - '0';
int product = 1;
then for your inner loop multiply the digit into the product.

Trie Data Structure in Finding an Optimal Solution

This Question is part of ongoing Competition , I have solved the 75% of this Question Data Set but the 25% is giving me TLE. I am asking why it's is giving TLE an i am sure my complexity is O(n*n)Question:
String S consisting of N lowercase English alphabets. We has prepared a list L consisting of all non empty substrings of the string S.
Now he asks you Q questions. To ith question, you need to count the number of ways to choose exactly Ki equal strings from the list L
For Example:
String = ababa
L = {"a", "b", "a", "b", "a", "ab", "ba", "ab", "ba", "aba", "bab", "aba", "abab", "baba", "ababa"}.
k1 = 2: There are seven ways to choose two equal strings ("a", "a"), ("a", "a"), ("a", "a"), ("b", "b"), ("ab", "ab"), ("ba", "ba"), ("aba", "aba").
k2 = 1: We can choose any string from L (15 ways).
k3 = 3: There is one way to choose three equal strings - ("a", "a", "a").
k4 = 4: There are no four equal strings in L .
Question LINK
My approach
I am making a TRIE of IT and Calculating The and Array F[i] where F[i] represent the number of times i equal String Occur.
My TRIE:
static class Batman{
int value;
Batman[] next = new Batman[26];
public Batman(int value){
this.value = value;
}
}
MY Insert Function
public static void Insert(String S,int[] F , int start){
Batman temp = Root;
for(int i=start;i<S.length();i++){
int index = S.charAt(i)-'a';
if(temp.next[index]==null){
temp.next[index] = new Batman(1);
F[1]+=1;
}else{
temp.next[index].value+=1;
int xx = temp.next[index].value;
F[xx-1]-=1;
F[xx]+=1;
// Calculating The Frequency of I equal Strings
}
temp = temp.next[index];
}
}
MY MAIN FUNCTION
public static void main(String args[] ) throws java.lang.Exception {
Root = new Batman(0);
int n = in.nextInt();
int Q = in.nextInt();
String S = in.next();
int[] F = new int[n+1];
for(int i=0;i<n;i++)
Insert(S,F,i);
long[] ans = new long[n+1];
for(int i=1;i<=n;i++){
for(int j=i;j<=n;j++){
ans[i]+= F[j]*C[j][i]; // C[n][k] is the Binomial Coffecient
ans[i]%=mod;
}
}
while(Q>0){
Q--;
int cc = in.nextInt();
long o =0;
if(cc<=n) o=ans[cc];
System.out.println(o+" "+S.length());
}
}
Why My appraoch is giving TLE as time Complexity is O(N*N) ans the length of String is N<=5000. Please Help me Working CODE
One reason this program get TLE (keep in mind that time constraint is 1 sec):
Each time you create a Batman object, it will create an array with length [26], and it is equivalence to adding a loop with n = 26.
So, you time complexity is 26*5000*5000 = 650000000 = 6.5*10^8 operations, theoretically, it can still fit into time limit if CPU speed is 10^9 operations per sec, but also keep in mind that there are some heavy calculation stuffs after this, so, this should be the reason.
To solve this problem, I used Z-algorithm and get accepted: Link
The actual code is quite complex, so the idea is, you have a table count[i][j], which is the number of substring that matched substring (i, j). Using Z-algorithm, you can have a time complexity of O(n^2).
For each string s:
int n = in.nextInt();
int q = in.nextInt();
String s = in.next();
int[][] cur = new int[n][];
int[][] count = new int[n][n];
int[] length = new int[n];
for (int i = 0; i < n; i++) {
cur[i] = Z(s.substring(i).toCharArray());//Applying Z algorithm
for (int j = 1; j < cur[i].length; j++) {
if (cur[i][j] > length[j + i]) {
for (int k = i + length[j + i]; k < i + cur[i][j]; k++) {
count[i][k]++;
}
length[j + i] = cur[i][j];
}
}
}
int[] F = new int[n + 1];
for(int i = 0; i < n; i++){
for(int j = i; j < n; j++){
int v = count[i][j] + (length[i] < (j - i + 1) ? 1 : 0);
F[v]++;
}
}
Z-algorithm method:
public static int[] Z(char[] s) {
int[] z = new int[s.length];
int n = s.length;
int L = 0, R = 0;
for (int i = 1; i < n; i++) {
if (i > R) {
L = R = i;
while (R < n && s[R - L] == s[R])
R++;
z[i] = R - L;
R--;
} else {
int k = i - L;
if (z[k] < R - i + 1) {
z[i] = z[k];
} else {
L = i;
while (R < n && s[R - L] == s[R])
R++;
z[i] = R - L;
R--;
}
}
}
return z;
}
Actual code: http://ideone.com/5GYWeS
Explanation:
First, we have an array length, with length[i] is the longest substring that matched with the string start from index i
For each index i, after calculate the Z function, we see that, if cur[i][j] > length[j + i], which means, there exists one substring longer than previous substring matched at index j + i, and we havent counted them in our result, so we need to count them.
So, even there are 3 nested for loop, but each substring is only counted once, which make this whole time complexity is O(n ^2)
for (int j = 1; j < cur[i].length; j++) {
if (cur[i][j] > length[j + i]) {
for (int k = i + length[j + i]; k < i + cur[i][j]; k++) {
count[i][k]++;
}
length[j + i] = cur[i][j];
}
}
For below loop, we notice that, if there is a matched for substring (i,j), length[i] >= length of substring (i,j), but if there is no matched, we need to add 1 to count substring (i,j), as this substring is unique.
for(int j = i; j < n; j++){
int v = count[i][j] + (length[i] < (j - i + 1) ? 1 : 0);
F[v]++;
}

I'm trying to reverse an array line by line

To clarify, this IS a homework assignment. I'm merely looking for advice, I'm not looking for someone to do my homework for me.
I've already done the first half. It uses two arrays to print an Asterisk design (in this case, the letter 'S'. That works fine. Then, I skip two lines and print the design but flipped (so each line is reversed). It seems to be working fine, but when I run the program, it prints two S's and the second one isn't reversed. Any ideas of what I'm doing wrong?
public class Design {
public static void main (String [] args) {
char [] array = new char [150];
for (int index = 0; index < array.length; index ++)
{
array [index] = '#';
}
int [] indexNumbers = {
0,1,2,3,4,5,6,7,8,9,10,20,30,40,50,
60,70,71,72,73,74,75,76,77,78,79,89,99,109,119,129,139,140,
141,142,143,144,145,146,147,148,149
};
for (int i = 0; i < indexNumbers.length; i++)
{
array [indexNumbers[i]] = ' ';
}
for (int index = 0; index < array.length; index ++)
{
if (index % 10 == 0 && index > 0)
System.out.println();
System.out.print (array[index]);
}
//Now, to reverse the letter
System.out.println();
System.out.println();
int lines = 5;
for (int i = 0; i< array.length; i++){
if (i >= lines)
lines += 10;
char temp = array [i];
array [i] = array [lines - i - 1];
array [lines - i - 1] = temp;
}
for (int index = 0; index < array.length; index ++)
{
if (index % 10 == 0 && index > 0)
System.out.println();
System.out.print (array[index]);
}
}
}
EDIT: Yeah... the design is in spaces, everything else is asterisks.
your reversing is a bit confused.... makes it easier if you do it in two loops.
for (int row = 0; row < (array.Length / 10); row++)
{
for (int col = 0; col < 5; col++)
{
int rowStart = row * 10;
int rowEnd = rowStart + 9;
char temp = array[rowStart + col];
array[rowStart + col] = array[rowEnd - col];
array[rowEnd - col] = temp;
}
}
First, why don't you use String[] or char[][]? Instead you are using a simple array to put multiple lines within. This makes your code confuse and brittle.
To swap an array, the rule is generally simple: Get the first and the last line and swap them. Get the second and the second last, and swap them, get the third and the third last and swap them... Until you get to the middle. This will be much easier if you have an array where each element is a line (like in an String[] or in an char[][]).
If you need to keep the idea of a simple char[] where each 10-char block is a line, simply swap each 10-char block like I stated above.
If you don't want to change the general behaviour of your program, this is the problematic block:
int lines = 5;
for (int i = 0; i< array.length; i++){
if (i >= lines)
lines += 10;
char temp = array [i];
array [i] = array [lines - i - 1];
array [lines - i - 1] = temp;
}
You are not swapping lines here, instead you are swapping chars. This way, your if is not checking and skipping lines, but is instead checking and skipping chars.
This is better:
int lines = array.length / 10;
for (int i = 0; i<= lines / 2; i++){
for (int j = 0; j < 10; j++) {
char t = array[i * 10 + j];
array[i * 10 + j] = array[(lines - i - 1) * 10 + j];
array[(lines - i - 1) * 10 + j] = t;
}
}
So..
First of all, start by printing '#' instead of ' ', and '.' instead of '#'. You will see more clearly what's going on.
Second, you have a problem in the reverse, you are actually not reversing anything, the way you calculate the index lines - i - 1 is wrong. The good way is (i / 10) * 10 + (10 - (i % 10)) -1. Yep, is kinda horrible, but if you want that in one line, using a one-dimension array, there it is. Now it's up to you to understand it, and integrate it in your code ;)

Categories

Resources