Adding two big numbers pt.2 - java

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.

Related

Count the minimum number of jumps required for a frog to get to the other side of a river

I work with a Codility problem provided below,
The Fibonacci sequence is defined using the following recursive formula:
F(0) = 0
F(1) = 1
F(M) = F(M - 1) + F(M - 2) if M >= 2
A small frog wants to get to the other side of a river. The frog is initially located at one bank of the river (position −1) and wants to get to the other bank (position N). The frog can jump over any distance F(K), where F(K) is the K-th Fibonacci number. Luckily, there are many leaves on the river, and the frog can jump between the leaves, but only in the direction of the bank at position N.
The leaves on the river are represented in an array A consisting of N integers. Consecutive elements of array A represent consecutive positions from 0 to N − 1 on the river. Array A contains only 0s and/or 1s:
0 represents a position without a leaf;
1 represents a position containing a leaf.
The goal is to count the minimum number of jumps in which the frog can get to the other side of the river (from position −1 to position N). The frog can jump between positions −1 and N (the banks of the river) and every position containing a leaf.
For example, consider array A such that:
A[0] = 0
A[1] = 0
A[2] = 0
A[3] = 1
A[4] = 1
A[5] = 0
A[6] = 1
A[7] = 0
A[8] = 0
A[9] = 0
A[10] = 0
The frog can make three jumps of length F(5) = 5, F(3) = 2 and F(5) = 5.
Write a function:
class Solution { public int solution(int[] A); }
that, given an array A consisting of N integers, returns the minimum number of jumps by which the frog can get to the other side of the river. If the frog cannot reach the other side of the river, the function should return −1.
For example, given:
A[0] = 0
A[1] = 0
A[2] = 0
A[3] = 1
A[4] = 1
A[5] = 0
A[6] = 1
A[7] = 0
A[8] = 0
A[9] = 0
A[10] = 0
the function should return 3, as explained above.
Assume that:
N is an integer within the range [0..100,000];
each element of array A is an integer that can have one of the following values: 0, 1.
Complexity:
expected worst-case time complexity is O(N*log(N));
expected worst-case space complexity is O(N) (not counting the storage required for input arguments).
I wrote the following solution,
class Solution {
private class Jump {
int position;
int number;
public int getPosition() {
return position;
}
public int getNumber() {
return number;
}
public Jump(int pos, int number) {
this.position = pos;
this.number = number;
}
}
public int solution(int[] A) {
int N = A.length;
List<Integer> fibs = getFibonacciNumbers(N + 1);
Stack<Jump> jumps = new Stack<>();
jumps.push(new Jump(-1, 0));
boolean[] visited = new boolean[N];
while (!jumps.isEmpty()) {
Jump jump = jumps.pop();
int position = jump.getPosition();
int number = jump.getNumber();
for (int fib : fibs) {
if (position + fib > N) {
break;
} else if (position + fib == N) {
return number + 1;
} else if (!visited[position + fib] && A[position + fib] == 1) {
visited[position + fib] = true;
jumps.add(new Jump(position + fib, number + 1));
}
}
}
return -1;
}
private List<Integer> getFibonacciNumbers(int N) {
List<Integer> list = new ArrayList<>();
for (int i = 0; i < 2; i++) {
list.add(i);
}
int i = 2;
while (list.get(list.size() - 1) <= N) {
list.add(i, (list.get(i - 1) + list.get(i - 2)));
i++;
}
for (i = 0; i < 2; i++) {
list.remove(i);
}
return list;
}
public static void main(String[] args) {
int[] A = new int[11];
A[0] = 0;
A[1] = 0;
A[2] = 0;
A[3] = 1;
A[4] = 1;
A[5] = 0;
A[6] = 1;
A[7] = 0;
A[8] = 0;
A[9] = 0;
A[10] = 0;
System.out.println(solution(A));
}
}
However, while the correctness seems good, the performance is not high enough. Is there a bug in the code and how do I improve the performance?
Got 100% with simple BFS:
public class Jump {
int pos;
int move;
public Jump(int pos, int move) {
this.pos = pos;
this.move = move;
}
}
public int solution(int[] A) {
int n = A.length;
List < Integer > fibs = fibArray(n + 1);
Queue < Jump > positions = new LinkedList < Jump > ();
boolean[] visited = new boolean[n + 1];
if (A.length <= 2)
return 1;
for (int i = 0; i < fibs.size(); i++) {
int initPos = fibs.get(i) - 1;
if (A[initPos] == 0)
continue;
positions.add(new Jump(initPos, 1));
visited[initPos] = true;
}
while (!positions.isEmpty()) {
Jump jump = positions.remove();
for (int j = fibs.size() - 1; j >= 0; j--) {
int nextPos = jump.pos + fibs.get(j);
if (nextPos == n)
return jump.move + 1;
else if (nextPos < n && A[nextPos] == 1 && !visited[nextPos]) {
positions.add(new Jump(nextPos, jump.move + 1));
visited[nextPos] = true;
}
}
}
return -1;
}
private List < Integer > fibArray(int n) {
List < Integer > fibs = new ArrayList < > ();
fibs.add(1);
fibs.add(2);
while (fibs.get(fibs.size() - 1) + fibs.get(fibs.size() - 2) <= n) {
fibs.add(fibs.get(fibs.size() - 1) + fibs.get(fibs.size() - 2));
}
return fibs;
}
You can apply knapsack algorithms to solve this problem.
In my solution I precomputed fibonacci numbers. And applied knapsack algorithm to solve it. It contains duplicate code, did not have much time to refactor it. Online ide with the same code is in repl
import java.util.*;
class Main {
public static int solution(int[] A) {
int N = A.length;
int inf=1000000;
int[] fibs={1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765, 10946, 17711, 28657, 46368, 75025};
int[] moves = new int[N+1];
for(int i=0; i<=N; i++){
moves[i]=inf;
}
for(int i=0; i<fibs.length; i++){
if(fibs[i]-1<N && A[fibs[i]-1]==1){
moves[ fibs[i]-1 ] = 1;
}
if(fibs[i]-1==N){
moves[N] = 1;
}
}
for(int i=0; i<N; i++){
if(A[i]==1)
for(int j=0; j<fibs.length; j++){
if(i-fibs[j]>=0 && moves[i-fibs[j]]!=inf && moves[i]>moves[i-fibs[j]]+1){
moves[i]=moves[i-fibs[j]]+1;
}
}
System.out.println(i + " => " + moves[i]);
}
for(int i=N; i<=N; i++){
for(int j=0; j<fibs.length; j++){
if(i-fibs[j]>=0 && moves[i-fibs[j]]!=inf && moves[i]>moves[i-fibs[j]]+1){
moves[i]=moves[i-fibs[j]]+1;
}
}
System.out.println(i + " => " + moves[i]);
}
if(moves[N]==inf) return -1;
return moves[N];
}
public static void main(String[] args) {
int[] A = new int[4];
A[0] = 0;
A[1] = 0;
A[2] = 0;
A[3] = 0;
System.out.println(solution(A));
}
}
Javascript 100%
function solution(A) {
function fibonacciUntilNumber(n) {
const fib = [0,1];
while (true) {
let newFib = fib[fib.length - 1] + fib[fib.length - 2];
if (newFib > n) {
break;
}
fib.push(newFib);
}
return fib.slice(2);
}
A.push(1);
const fibSet = fibonacciUntilNumber(A.length);
if (fibSet.includes(A.length)) return 1;
const reachable = Array.from({length: A.length}, () => -1);
fibSet.forEach(jump => {
if (A[jump - 1] === 1) {
reachable[jump - 1] = 1;
}
})
for (let index = 0; index < A.length; index++) {
if (A[index] === 0 || reachable[index] > 0) {
continue;
}
let minValue = 100005;
for (let jump of fibSet) {
let previousIndex = index - jump;
if (previousIndex < 0) {
break;
}
if (reachable[previousIndex] > 0 && minValue > reachable[previousIndex]) {
minValue = reachable[previousIndex];
}
}
if (minValue !== 100005) {
reachable[index] = minValue + 1;
}
}
return reachable[A.length - 1];
}
Python 100% answer.
For me the easiest solution was to locate all leaves within one fib jump of -1. Then consider each of these leaves to be index[0] and find all jumps from there.
Each generation or jump is recorded in a set until a generation contains len(A) or no more jumps can be found.
def gen_fib(n):
fn = [0,1]
i = 2
s = 2
while s < n:
s = fn[i-2] + fn[i-1]
fn.append(s)
i+=1
return fn
def new_paths(A, n, last_pos, fn):
"""
Given an array A of len n.
From index last_pos which numbers in fn jump to a leaf?
returns list: set of indexes with leaves.
"""
paths = []
for f in fn:
new_pos = last_pos + f
if new_pos == n or (new_pos < n and A[new_pos]):
paths.append(new_pos)
return path
def solution(A):
n = len(A)
if n < 3:
return 1
# A.append(1) # mark final jump
fn = sorted(gen_fib(100000)[2:]) # Fib numbers with 0, 1, 1, 2.. clipped to just 1, 2..
# print(fn)
paths = set([-1]) # locate all the leaves that are one fib jump from the start position.
jump = 1
while True:
# Considering each of the previous jump positions - How many leaves from there are one fib jump away
paths = set([idx for pos in paths for idx in new_paths(A, n, pos, fn)])
# no new jumps means game over!
if not paths:
break
# If there was a result in the new jumps record that
if n in paths:
return jump
jump += 1
return -1
https://app.codility.com/demo/results/training4GQV8Y-9ES/
https://github.com/niall-oc/things/blob/master/codility/fib_frog.py
Got 100%- solution in C.
typedef struct state {
int pos;
int step;
}state;
int solution(int A[], int N) {
int f1 = 0;
int f2 = 1;
int count = 2;
// precalculating count of maximum possible fibonacci numbers to allocate array in next loop. since this is C language we do not have flexible dynamic structure as in C++
while(1)
{
int f3 = f2 + f1;
if(f3 > N)
break;
f1 = f2;
f2 = f3;
++count;
}
int fib[count+1];
fib[0] = 0;
fib[1] = 1;
int i = 2;
// calculating fibonacci numbers in array
while(1)
{
fib[i] = fib[i-1] + fib[i-2];
if(fib[i] > N)
break;
++i;
}
// reversing the fibonacci numbers because we need to create minumum jump counts with bigger jumps
for(int j = 0, k = count; j < count/2; j++,k--)
{
int t = fib[j];
fib[j] = fib[k];
fib[k] = t;
}
state q[N];
int front = 0 ;
int rear = 0;
q[0].pos = -1;
q[0].step = 0;
int que_s = 1;
while(que_s > 0)
{
state s = q[front];
front++;
que_s--;
for(int i = 0; i <= count; i++)
{
int nextpo = s.pos + fib[i];
if(nextpo == N)
{
return s.step+1;
}
else if(nextpo > N || nextpo < 0 || A[nextpo] == 0){
continue;
}
else
{
q[++rear].pos = nextpo;
q[rear].step = s.step + 1;
que_s++;
A[nextpo] = 0;
}
}
}
return -1;
}
//100% on codility Dynamic Programming Solution. https://app.codility.com/demo/results/training7WSQJW-WTX/
class Solution {
public int solution(int[] A) {
int n = A.length + 1;
int dp[] = new int[n];
for(int i=0;i<n;i++) {
dp[i] = -1;
}
int f[] = new int[100005];
f[0] = 1;
f[1] = 1;
for(int i=2;i<100005;i++) {
f[i] = f[i - 1] + f[i - 2];
}
for(int i=-1;i<n;i++) {
if(i == -1 || dp[i] > 0) {
for(int j=0;i+f[j] <n;j++) {
if(i + f[j] == n -1 || A[i+f[j]] == 1) {
if(i == -1) {
dp[i + f[j]] = 1;
} else if(dp[i + f[j]] == -1) {
dp[i + f[j]] = dp[i] + 1;
} else {
dp[i + f[j]] = Math.min(dp[i + f[j]], dp[i] + 1);
}
}
}
}
}
return dp[n - 1];
}
}
Ruby 100% solution
def solution(a)
f = 2.step.inject([1,2]) {|acc,e| acc[e] = acc[e-1] + acc[e-2]; break(acc) if acc[e] > a.size + 1;acc }.reverse
mins = []
(a.size + 1).times do |i|
next mins[i] = -1 if i < a.size && a[i] == 0
mins[i] = f.inject(nil) do |min, j|
k = i - j
next min if k < -1
break 1 if k == -1
next min if mins[k] < 0
[mins[k] + 1, min || Float::INFINITY].min
end || -1
end
mins[a.size]
end
I have translated the previous C solution to Java and find the performance is improved.
import java.util.*;
class Solution {
private static class State {
int pos;
int step;
public State(int pos, int step) {
this.pos = pos;
this.step = step;
}
}
public static int solution(int A[]) {
int N = A.length;
int f1 = 0;
int f2 = 1;
int count = 2;
while (true) {
int f3 = f2 + f1;
if (f3 > N) {
break;
}
f1 = f2;
f2 = f3;
++count;
}
int[] fib = new int[count + 1];
fib[0] = 0;
fib[1] = 1;
int i = 2;
while (true) {
fib[i] = fib[i - 1] + fib[i - 2];
if (fib[i] > N) {
break;
}
++i;
}
for (int j = 0, k = count; j < count / 2; j++, k--) {
int t = fib[j];
fib[j] = fib[k];
fib[k] = t;
}
State[] q = new State[N];
for (int j = 0; j < N; j++) {
q[j] = new State(-1,0);
}
int front = 0;
int rear = 0;
// q[0].pos = -1;
// q[0].step = 0;
int que_s = 1;
while (que_s > 0) {
State s = q[front];
front++;
que_s--;
for (i = 0; i <= count; i++) {
int nextpo = s.pos + fib[i];
if (nextpo == N) {
return s.step + 1;
}
//
else if (nextpo > N || nextpo < 0 || A[nextpo] == 0) {
continue;
}
//
else {
q[++rear].pos = nextpo;
q[rear].step = s.step + 1;
que_s++;
A[nextpo] = 0;
}
}
}
return -1;
}
}
JavaScript with 100%.
Inspired from here.
function solution(A) {
const createFibs = n => {
const fibs = Array(n + 2).fill(null)
fibs[1] = 1
for (let i = 2; i < n + 1; i++) {
fibs[i] = fibs[i - 1] + fibs[i - 2]
}
return fibs
}
const createJumps = (A, fibs) => {
const jumps = Array(A.length + 1).fill(null)
let prev = null
for (i = 2; i < fibs.length; i++) {
const j = -1 + fibs[i]
if (j > A.length) break
if (j === A.length || A[j] === 1) {
jumps[j] = 1
if (prev === null) prev = j
}
}
if (prev === null) {
jumps[A.length] = -1
return jumps
}
while (prev < A.length) {
for (let i = 2; i < fibs.length; i++) {
const j = prev + fibs[i]
if (j > A.length) break
if (j === A.length || A[j] === 1) {
const x = jumps[prev] + 1
const y = jumps[j]
jumps[j] = y === null ? x : Math.min(y, x)
}
}
prev++
while (prev < A.length) {
if (jumps[prev] !== null) break
prev++
}
}
if (jumps[A.length] === null) jumps[A.length] = -1
return jumps
}
const fibs = createFibs(26)
const jumps = createJumps(A, fibs)
return jumps[A.length]
}
const A = [0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0]
console.log(A)
const s = solution(A)
console.log(s)
You should use a QUEUE AND NOT A STACK. This is a form of breadth-first search and your code needs to visit nodes that were added first to the queue to get the minimum distance.
A stack uses the last-in, first-out mechanism to remove items while a queue uses the first-in, first-out mechanism.
I copied and pasted your exact code but used a queue instead of a stack and I got 100% on codility.
100% C++ solution
More answers in my github
Inspired from here
Solution1 : Bottom-Top, using Dynamic programming algorithm (storing calculated values in an array)
vector<int> getFibonacciArrayMax(int MaxNum) {
if (MaxNum == 0)
return vector<int>(1, 0);
vector<int> fib(2, 0);
fib[1] = 1;
for (int i = 2; fib[fib.size()-1] + fib[fib.size() - 2] <= MaxNum; i++)
fib.push_back(fib[i - 1] + fib[i - 2]);
return fib;
}
int solution(vector<int>& A) {
int N = A.size();
A.push_back(1);
N++;
vector<int> f = getFibonacciArrayMax(N);
const int oo = 1'000'000;
vector<int> moves(N, oo);
for (auto i : f)
if (i - 1 >= 0 && A[i-1])
moves[i-1] = 1;
for (int pos = 0; pos < N; pos++) {
if (A[pos] == 0)
continue;
for (int i = f.size()-1; i >= 0; i--) {
if (pos + f[i] < N && A[pos + f[i]]) {
moves[pos + f[i]] = min(moves[pos]+1, moves[pos + f[i]]);
}
}
}
if (moves[N - 1] != oo) {
return moves[N - 1];
}
return -1;
}
Solution2: Top-Bottom using set container:
#include <set>
int solution2(vector<int>& A) {
int N = A.size();
vector<int> fib = getFibonacciArrayMax(N);
set<int> positions;
positions.insert(N);
for (int jumps = 1; ; jumps++)
{
set<int> new_positions;
for (int pos : positions)
{
for (int f : fib)
{
// return jumps if we reach to the start point
if (pos - (f - 1) == 0)
return jumps;
int prev_pos = pos - f;
// we do not need to calculate bigger jumps.
if (prev_pos < 0)
break;
if (prev_pos < A.size() && A[prev_pos])
new_positions.insert(prev_pos);
}
}
if (new_positions.size() == 0)
return -1;
positions = new_positions;
}
return -1;
}

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;
}

If on a certain element of the array in a loop, do X action

Is there a way to see that, if a loop is on a certain element of an array, to do a specific action?
Say that if I'm on the first element of an array in a loop, set a flag to false?
ex)
int carry = 1;
int arraySum[] = new int[NUM_DIGITS];
boolean carryFlag = false;
for(int i = NUM_DIGITS - 1; i >= 0; i--){
arraySum[i] = array1[i] + array2[i];
if(carryFlag){
arraySum[i] += carry;
carryFlag = false;
}
//if on the last iteration/element of the array,
//arraySum[0], carryFlag = false; and continue;
if(arraySum[i] > 9){
arraySum[i] = arraySum[i] - 10;
carryFlag = true;
}
}
Sorry if my question sounds rather vague.. But if there's a way around to making it act like a boolean: if(arraySum[0]) carryFlag = false
I would suggest eliminating the flag and setting different values for carry:
int carry = 0;
int arraySum[] = new int[NUM_DIGITS];
for(int i = NUM_DIGITS - 1; i >= 0; i--){
arraySum[i] = array1[i] + array2[i] + carry;
// check for carry
if(arraySum[i] > 9){
arraySum[i] -= 10;
carry = 1;
} else {
carry = 0;
}
}
After the loop exits, if carry is not 0, then the summation overflowed.
It seems like in this implementation, you can test the value of i?
Something like if (i==NUM_DIGITS) carryFlag = false; ?

Searching a word in a given string array

You are given a 2D array as a string and a word via keyboard. The word
can be in any way (all 8 neighbors to be considered) but you can’t use
same character twice while matching. Return word's first and last
character's index as (x,y). If match is not found return -1.
That's the question. I'm having trouble with searching. I tried that:
int x=0,y=0;
for(int f=0; f<WordinArray.length; f++){
for(int i=0; i<matrix.length; i++){
for(int j=0; j<matrix[0].length; j++){
if(matrix[i][j].equals(WordinArray[f])){
x=i; y=j;
System.out.print("("+x+","+y+")");
}
}
}
}
But, That code is not working as it is supposed to. How else I can write this searching code?
Referring to Sixie's code
Assuming this is a valid input/output to your program?
Size:
4x4
Matrix:
a b c d
e f g h
i j k l
m n o p
Word: afkp
(0,0)(3,3)
I edited your code, so that it should work for input on this form (it is case sensitive at the moment, but can easily be changed by setting .toLowerCase()
Scanner k = new Scanner(System.in);
System.out.println("Size: ");
String s = k.nextLine();
s.toUpperCase();
int Xindex = s.indexOf('x');
int x = Integer.parseInt(s.substring(0, Xindex));
int y = Integer.parseInt(s.substring(Xindex + 1));
System.out.println("Matrix:");
char[][] matrix = new char[x][y];
for (int i = 0; i < x; i++) {
for (int p = 0; p < y; p++) {
matrix[i][p] = k.next().charAt(0);
}
}
System.out.print("Word: ");
String word = k.next();
int xStart = -1, yStart = -1;
int xEnd = -1, yEnd = -1;
// looping through the matrix
for (int i = 0; i < x; i++) {
for (int j = 0; j < y; j++) {
// when a match is found at the first character of the word
if (matrix[i][j] == word.charAt(0)) {
int tempxStart = i;
int tempyStart = j;
// calculating all the 8 normals in the x and y direction
// (the 8 different directions from each cell)
for (int normalX = -1; normalX <= 1; normalX++) {
for (int normalY = -1; normalY <= 1; normalY++) {
// go in the given direction for the whole length of
// the word
for (int wordPosition = 0; wordPosition < word
.length(); wordPosition++) {
// calculate the new (x,y)-position in the
// matrix
int xPosition = i + normalX * wordPosition;
int yPosition = j + normalY * wordPosition;
// if the (x,y)-pos is inside the matrix and the
// (x,y)-vector normal is not (0,0) since we
// dont want to check the same cell over again
if (xPosition >= 0 && xPosition < x
&& yPosition >= 0 && yPosition < y
&& (normalX != 0 || normalY != 0)) {
// if the character in the word is not equal
// to the (x,y)-cell break out of the loop
if (matrix[xPosition][yPosition] != word
.charAt(wordPosition))
break;
// if the last character in the word is
// equivalent to the (x,y)-cell we have
// found a full word-match.
else if (matrix[xPosition][yPosition] == word
.charAt(wordPosition)
&& wordPosition == word.length() - 1) {
xStart = tempxStart;
yStart = tempyStart;
xEnd = xPosition;
yEnd = yPosition;
}
} else
break;
}
}
}
}
}
}
System.out.println("(" + xStart + "," + yStart + ")(" + xEnd + ","
+ yEnd + ")");
k.close();
I think you need to plan your algorithm a bit more carefully before you start writing code. If I were doing it, my algorithm might look something like this.
(1) Iterate through the array, looking for the first character of the word.
(2) Each time I find the first character, check out all 8 neighbours, to see if any is the second character.
(3) Each time I find the second character as a neighbour of the first, iterate along the characters in the array, moving in the correct direction, and checking each character against the word.
(4) If I have matched the entire word, then print out the place where I found the match and stop.
(5) If I have reached the edge of the grid, or found a character that doesn't match, then continue with the next iteration of loop (2).
Once you have your algorithm nailed down, think about how to convert each step to code.
If I understood your question right. This is a quick answer I made now.
int H = matrix.length;
int W = matrix[0].length;
int xStart = -1, yStart = -1;
int xEnd = -1, yEnd = -1;
String word = "WordLookingFor".toLowerCase();
for (int i = 0; i < H; i++) {
for (int j = 0; j < W; j++) {
if (matrix[i][j] == word.charAt(0)) {
int tempxStart = i;
int tempyStart = j;
for (int x = -1; x <= 1; x++) {
for (int y = -1; y <= 1; y++) {
for (int k = 0; k < word.length(); k++) {
int xx = i+x*k;
int yy = j+y*k;
if(xx >= 0 && xx < H && yy >= 0 && yy < W && (x != 0 || y != 0)) {
if(matrix[xx][yy] != word.charAt(k))
break;
else if (matrix[xx][yy] == word.charAt(k) && k == word.length()-1) {
xStart = tempxStart;
yStart = tempyStart;
xEnd = xx;
yEnd = yy;
}
} else
break;
}
}
}
}
}
}
A little trick I used for checking all the 8 neighbors is to use two for-loops to create all the directions to go in:
for (int x = -1; x <= 1; x++) {
for (int y = -1; y <= 1; y++) {
if(x !=0 || y != 0)
System.out.println(x + ", " + y);
}
}
This creates
-1, -1
-1, 0
-1, 1
0, -1
0, 1
1, -1
1, 0
1, 1
Notice: All but 0,0 (you don't want to revisit the same cell).
The rest of the code is simply traversing though the matrix of characters, and though the whole length of the word you are looking for until you find (or maybe you don't find) a full match.
This time the problem is that how could I print word's first and last
letter's indexes. I tried various ways like printing after each word
was searched. But, all of them didn't work. I am about to blow up.
int[] values = new int[2];
for(int i=0; i<matrix.length; i++){
for(int j=0; j<matrix[0].length; j++){
if(Character.toString(word.charAt(0)).equals(matrix[i][j]) == true || Character.toString(ReversedWord.charAt(0)).equals(matrix[i][j]) == true ){
System.out.print("("+ i + "," +j+")");
//First letter is found.Continue.
for(int p=1; p<word.length(); p++){
try{
for (int S = -1; S <= 1; S++) {
for (int SS = -1; SS <= 1; SS++) {
if(S !=0 || SS != 0)
if(matrix[i+S][j+SS].equals(Character.toString(word.charAt(p))) && blocksAvailable[i+S][j+SS] == true ||
matrix[i+S][j+SS].equals(Character.toString(ReversedWord.charAt(p))) && blocksAvailable[i+S][j+SS] == true) {
values[0] = i+S;
values[1] = j+SS;
blocksAvailable[i+S][j+SS] = false;
}
}
}
}catch (ArrayIndexOutOfBoundsException e) {}

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