A question about for-loop condition in java - 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.

Related

Fill an array with powers of 3

public class Power {
public static void main(String[] args) {
int base = 3, exponent = 9;
int[] result = new int[10];
System.out.println(result);
while (exponent != 0)
{
result * base = result;
--exponent;
System.out.println(result);
}
}
}
What I would like this code to do is be able to Multiply 1*3 to make 3, put it inside of the array, and multiply it again, and so on and so forth. Basically, it needs to output, 1 3 9 27 81 243 729 2187 6561 19683. How can I store it inside of the array, and also multiply it again?
You could keep a result variable and continue saving it to an array:
int index = 0;
int[] result = new int[10];
int current = 1;
for (int i = 0; i < result.length; ++i) {
result[i] = current;
current *= 3;
}
System.out.println(Arrays.asString(result));
result[0] = 1;
System.out.print(result[0] + " ");
for (int i = 1; i < n; i++) {
result[i] = result[i-1]*3;
System.out.print(result[i] + " ");
}
Let n be one less than the number of entries you want to print.
Your first problem is that assignments need the name on the left side, and the expression on the right side; replace result * base = result; by result = result * base;.
Secondly, result is an array. You’re trying to treat it as a single number.
Thirdly, if you want to fill an array, use a for loop instead of what you currently have:
final int base = 3;
final int[] result = new int[10];
result[0] = 1;
for (int i = 1; i < result.length; i++) {
result[i] = result[i - 1] * base;
}

Java get each digit from 2 strings and calculate it

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.

fibonacci in Java

I am trying to create a program which finds the sum of even numbers below 4 million the Fibonacci sequence. I know there is a much simpler way of doing this, but I wanted to see if it would work with arrays. I have never really used arrays before as I am fairly new to Java, which is why I wanted to see if this worked with arrays. The main problem that I have is with the for statement. How would I see if the contents of fibarray[i] is less than 4000000?
Also, is it OK if I do the thing with the fibarray = new int[i]?
public static void main(String[] args) {
int[] fibarray;
int numcount = 0;
int i = 0;
long sum = 0;
fibarray = new int[i];
fibarray[0] = 0;
fibarray[1] = 1;
for(i = 0 , fibarray[i] < 4000000, i++;;){
fibarray[i] = fibarray[i - 1] + fibarray[i - 2];
}
}
I apologise if this sounds really stupid.
Any help would be much appreciated.
Thanks.
Well, you need to start your for loop with i = 2. And the for loop should be in this syntax
for(i = 2; fibarray[i] < 4000000; i++) {
fibarray[i] = fibarray[i - 1] + fibarray[i - 2];
}
See comments within the code:
public static void main(String[] args){
/*************************
* comments on your code
int[] fibarray; //use right java naming convention
int numCount = 0; //this variable is never used
int i = 0;
long sum = 0;
fibarray = new int[i];//you initialize an array of size 0.
fibarray[0] = 0; //you can't set value to array of size 0
fibarray[1] = 1; //you can't set value to array of size 0
//wrong syntax
for(i = 0 , fibarray[i] < 4000000, i++;;){
//use for(i = 0 ; fibarray[i] < 4000000; i++){
fibarray[i] = fibarray[i - 1] + fibarray[i - 2];
}
*******************************/
//Alternative code
//you don't need to keep all Fibonachi numbers found.
//you only use 3 numbers for every calculation
int size = 3;
int totalLimit = 4000000;
int[] fibArray = new int[size];
fibArray[0] = 0; fibArray[1] = 1;
int total = 0;
while( true ) {
fibArray[2] = fibArray[0] + fibArray[1] ;
if((fibArray[2]%2) ==0) { //even number
if((total + fibArray[2]) >= totalLimit) {
break;
}
total += fibArray[2];
}
fibArray[0] = fibArray[1] ;
fibArray[1] = fibArray[2] ;
}
System.out.println("Total "+ total );
}
Don't hesitate to ask for clarifications as needed.

Array in the reverse order [duplicate]

This question already has answers here:
How do I reverse an int array in Java?
(47 answers)
Closed 8 years ago.
I have an array of n elements and these methods:
last() return the last int of the array
first() return the first int of the array
size() return the length of the array
replaceFirst(num) that add the int at the beginning and returns its position
remove(pos) that delete the int at the pos
I have to create a new method that gives me the array at the reverse order.
I need to use those method. Now, I can't understand why my method doesn't work.
so
for (int i = 1; i
The remove will remove the element at the position i, and return the number that it is in that position, and then with replaceFirst will move the number (returned by remove) of the array.
I made a try with a simple array with {2,4,6,8,10,12}
My output is: 12 12 12 8 6 10
so if I have an array with 1,2,3,4,5
for i = 1; I'm gonna have : 2,1,3,4,5
for i=2 >3,2,1,4,5
etc
But it doesn't seem to work.
Well, I'll give you hints. There are multiple ways to reverse an array.
The simplest and the most obvious way would be to loop through the array in the reverse order and assign the values to another array in the right order.
The previous method would require you to use an extra array, and if you do not want to do that, you could have two indices in a for loop, one from the first and next from the last and start swapping the values at those indices.
Your method also works, but since you insert the values into the front of the array, its going to be a bit more complex.
There is also a Collections.reverse method in the Collections class to reverse arrays of objects. You can read about it in this post
Here is an code that was put up on Stackoverflow by #unholysampler. You might want to start there: Java array order reversing
public static void reverse(int[] a)
{
int l = a.length;
for (int j = 0; j < l / 2; j++)
{
int temp = a[j]
a[j] = a[l - j - 1];
a[l - j - 1] = temp;
}
}
int[] reverse(int[] a) {
int len = a.length;
int[] result = new int[len];
for (int i = len; i > 0 ; i--)
result[len-i] = a[i-1];
return result;
}
for(int i = array.length; i >= 0; i--){
System.out.printf("%d\n",array[i]);
}
Try this.
If it is a Java array and not a complex type, the easiest and safest way is to use a library, e.g. Apache commons: ArrayUtils.reverse(array);
In Java for a random Array:
public static void reverse(){
int[] a = new int[4];
a[0] = 3;
a[1] = 2;
a[2] = 5;
a[3] = 1;
LinkedList<Integer> b = new LinkedList<Integer>();
for(int i = a.length-1; i >= 0; i--){
b.add(a[i]);
}
for(int i=0; i<b.size(); i++){
a[i] = b.get(i);
System.out.print(a[i] + ",");
}
}
Hope this helps.
Reversing an array is a relatively simple process. Let's start with thinking how you print an array normally.
int[] numbers = {1,2,3,4,5,6};
for(int x = 0; x < numbers.length; x++)
{
System.out.println(numbers[x]);
}
What does this do? Well it increments x while it is less than numbers.length, so what is actually happening is..
First run : X = 0
System.out.println(numbers[x]);
// Which is equivalent to..
System.out.println(numbers[0]);
// Which resolves to..
System.out.println(1);
Second Run : X = 1
System.out.println(numbers[x]);
// Which is equivalent to..
System.out.println(numbers[1]);
// Which resolves to..
System.out.println(2);
What you need to do is start with numbers.length - 1, and go back down to 0. To do this, you need to restructure your for loop, to match the following pseudocode..
for(x := numbers.length to 0) {
print numbers[x]
}
Now you've worked out how to print, it's time to move onto reversing the array. Using your for loop, you can cycle through each value in the array from start to finish. You'll also be needing a new array.
int[] revNumbers = new int[numbers.length];
for(int x = numbers.length - 1 to 0) {
revNumbers[(numbers.length - 1) - x] = numbers[x];
}
int[] noArray = {1,2,3,4,5,6};
int lenght = noArray.length - 1;
for(int x = lenght ; x >= 0; x--)
{
System.out.println(noArray[x]);
}
}
int[] numbers = {1,2,3,4,5};
int[] ReverseNumbers = new int[numbers.Length];
for(int a=0; a<numbers.Length; a++)
{
ReverseNumbers[a] = numbers.Length - a;
}
for(int a=0; a<ReverseNumbers.Length; a++)
Console.Write(" " + ReverseNumbers[a]);
int[] numbers = { 1, 2, 3, 4, 5, 6 };
reverse(numbers, 1); >2,1,3,4,5
reverse(numbers, 2); >3,2,1,4,5
public int[] reverse(int[] numbers, int value) {
int index = 0;
for (int i = 0; i < numbers.length; i++) {
int j = numbers[i];
if (j == value) {
index = i;
break;
}
}
int i = 0;
int[] result = new int[numbers.length];
int forIndex = index + 1;
for (int x = index + 2; x > 0; x--) {
result[i] = numbers[forIndex--];
++i;
}
for (int x = index + 2; x < numbers.length; x++) {
result[i] = numbers[x];
++i;
}
return result;
}

Getting all combinations of values from many lists

I'm trying to resolve all the combinations of elements based on a given string.
The string is like this :
String result="1,2,3,###4,5,###6,###7,8,";
The number of element between ### (separated with ,) is not determined and the number of "list" (part separated with ###) is not determined either.
NB : I use number in this example but it can be String too.
And the expected result in this case is a string containing :
String result = "1467, 1468, 1567, 1568, 2467, 2468, 2567, 2568, 3467, 3468, 3567, 3568"
So as you can see the elements in result must start with an element of the first list then the second element must be an element of the second list etc...
From now I made this algorithm that works but it's slow :
String [] parts = result.split("###");
if(parts.length>1){
result="";
String stack="";
int i;
String [] elmts2=null;
String [] elmts = parts[0].split(",");
for(String elmt : elmts){ //Browse root elements
if(elmt.trim().isEmpty())continue;
/**
* This array is used to store the next index to use for each row.
*/
int [] elmtIdxInPart= new int[parts.length];
//Loop until the root element index change.
while(elmtIdxInPart[0]==0){
stack=elmt;
//Add to the stack an element of each row, chosen by index (elmtIdxInPart)
for(i=1 ; i<parts.length;i++){
if(parts[i].trim().isEmpty() || parts[i].trim().equals(","))continue;
String part = parts[i];
elmts2 = part.split(",");
stack+=elmts2[elmtIdxInPart[i]];
}
//rollback i to previous used index
i--;
if(elmts2 == null){
elmtIdxInPart[0]=elmtIdxInPart[0]+1;
}
//Check if all elements in the row have been used.
else if(elmtIdxInPart[i]+1 >=elmts2.length || elmts2[elmtIdxInPart[i]+1].isEmpty()){
//Make evolve previous row that still have unused index
int j=1;
while(elmtIdxInPart[i-j]+1 >=parts[i-j].split(",").length ||
parts[i-j].split(",")[elmtIdxInPart[i-j]+1].isEmpty()){
if(j+1>i)break;
j++;
}
int next = elmtIdxInPart[i-j]+1;
//Init the next row to 0.
for(int k = (i-j)+1 ; k <elmtIdxInPart.length ; k++){
elmtIdxInPart[k]=0;
}
elmtIdxInPart[i-j]=next;
}
else{
//Make evolve index in current row, init the next row to 0.
int next = elmtIdxInPart[i]+1;
for(int k = (i+1) ; k <elmtIdxInPart.length ; k++){
elmtIdxInPart[k]=0;
}
elmtIdxInPart[i]=next;
}
//Store full stack
result+=stack+",";
}
}
}
else{
result=parts[0];
}
I'm looking for a more performant algorithm if it's possible. I made it from scratch without thinking about any mathematical algorithm. So I think I made a tricky/slow algo and it can be improved.
Thanks for your suggestions and thanks for trying to understand what I've done :)
EDIT
Using Svinja proposition it divide execution time by 2:
StringBuilder res = new StringBuilder();
String input = "1,2,3,###4,5,###6,###7,8,";
String[] lists = input.split("###");
int N = lists.length;
int[] length = new int[N];
int[] indices = new int[N];
String[][] element = new String[N][];
for (int i = 0; i < N; i++){
element[i] = lists[i].split(",");
length[i] = element[i].length;
}
// solve
while (true)
{
// output current element
for (int i = 0; i < N; i++){
res.append(element[i][indices[i]]);
}
res.append(",");
// calculate next element
int ind = N - 1;
for (; ind >= 0; ind--)
if (indices[ind] < length[ind] - 1) break;
if (ind == -1) break;
indices[ind]++;
for (ind++; ind < N; ind++) indices[ind] = 0;
}
System.out.println(res);
This is my solution. It's in C# but you should be able to understand it (the important part is the "calculate next element" section):
static void Main(string[] args)
{
// parse the input, this can probably be done more efficiently
string input = "1,2,3,###4,5,###6,###7,8,";
string[] lists = input.Replace("###", "#").Split('#');
int N = lists.Length;
int[] length = new int[N];
int[] indices = new int[N];
for (int i = 0; i < N; i++)
length[i] = lists[i].Split(',').Length - 1;
string[][] element = new string[N][];
for (int i = 0; i < N; i++)
{
string[] list = lists[i].Split(',');
element[i] = new string[length[i]];
for (int j = 0; j < length[i]; j++)
element[i][j] = list[j];
}
// solve
while (true)
{
// output current element
for (int i = 0; i < N; i++) Console.Write(element[i][indices[i]]);
Console.WriteLine(" ");
// calculate next element
int ind = N - 1;
for (; ind >= 0; ind--)
if (indices[ind] < length[ind] - 1) break;
if (ind == -1) break;
indices[ind]++;
for (ind++; ind < N; ind++) indices[ind] = 0;
}
}
Seems kind of similar to your solution. Does this really have bad performance? Seems to me that this is clearly optimal, as the complexity is linear with the size of the output, which is always optimal.
edit: by "similar" I mean that you also seem to do the counting with indexes thing. Your code is too complicated for me to go into after work. :D
My index adjustment works very simply: starting from the right, find the first index we can increase without overflowing, increase it by one, and set all the indexes to its right (if any) to 0. It's basically counting in a number system where each digit is in a different base. Once we can't even increase the first index any more (which means we can't increase any, as we started checking from the right), we're done.
Here is a somewhat different approach:
static void Main(string[] args)
{
string input = "1,2,3,###4,5,###6,###7,8,";
string[] lists = input.Replace("###", "#").Split('#');
int N = lists.Length;
int[] length = new int[N];
string[][] element = new string[N][];
int outCount = 1;
// get each string for each position
for (int i = 0; i < N; i++)
{
string list = lists[i];
// fix the extra comma at the end
if (list.Substring(list.Length - 1, 1) == ",")
list = list.Substring(0, list.Length - 1);
string[] strings = list.Split(',');
element[i] = strings;
length[i] = strings.Length;
outCount *= length[i];
}
// prepare the output array
string[] outstr = new string[outCount];
// produce all of the individual output strings
string[] position = new string[N];
for (int j = 0; j < outCount; j++)
{
// working value of j:
int k = j;
for (int i = 0; i < N; i++)
{
int c = length[i];
int q = k / c;
int r = k - (q * c);
k = q;
position[i] = element[i][r];
}
// combine the chars
outstr[j] = string.Join("", position);
}
// join all of the strings together
//(note: joining them all at once is much faster than doing it
//incrementally, if a mass concatenate facility is available
string result = string.Join(", ", outstr);
Console.Write(result);
}
I am not a Java programmer either, so I adapted Svinja's c# answer to my algorithm, assuming that you can convert it to Java also. (thanks to Svinja..)

Categories

Resources