Android Question Hot to Redim this array?

Forget Arrays :), use Lists or Maps.

Using a Map you might have:
B4X:
Dim mapX As Map
mapX.Initialize
mapX.Put(2, 234)
mapX.Put(3, 3456789)

' and even:
mapX.Remove(2)

Hi LucaMs
This is a code used to calculate combinations of large Int numbers. It was originally written in VB6 and can run successfully. I rewrite it with B4A and replaced Array with MAP, but there are always NULL errors and run slowly. I hope to be able to run both in B4A and B4I, can you help me?
 

Attachments

Upvote 0
I found 2 problems:

1 - your change to "replace" the Mid$ function (I created a similar function and now this part does not crash);
2 - I have yet to find out why but there are problems using a Long as a Map key.
In this part of your source:
B4X:
XYS.Put(i + j - 1, XYS.Get(i + j - 1) + x.Get(i) * y.Get(i))
the Map x contains: 1 (key) 1 (value).
x.Get(i) results Null only because "i" is declared as Long; if you declare it as Int, 1 is returned as expected.

Still studying :)

In the meantime I am attaching the B4XPages version so you can use it with B4A, B4J and B4i.
I hope to be able to run both in B4A and B4I
I am doing tests with B4J (much more direct, more comfortable debugging).
 

Attachments

Upvote 0
Try explicit casting

B4X:
Dim Key As Long = i + j - 1
Dim Value As Long = XYS.Get(Key) + x.Get(i) * y.Get(i)
XYS.Put(Key, Value)
 
Upvote 0
And this line is incorrect:
B4X:
For i = 1 To x.Size + y.Size-1

Should be

B4X:
For i = 1 To x.Size -1 + y.Size-1

So that plus changing the previous to:

B4X:
Dim Key As Long = 1
    x.Put(Key,Key)      'VB6: x(1) = 1
    XYS.Put(Key,Key)    'VB6: XYS(1) = 1

And it completes
 
Upvote 0
1604393611860.png

;)
 
Upvote 0
As you can tell, I'm not used to B4xPages yet. :)
I found 2 problems:

1 - your change to "replace" the Mid$ function (I created a similar function and now this part does not crash);
2 - I have yet to find out why but there are problems using a Long as a Map key.
In this part of your source:
B4X:
XYS.Put(i + j - 1, XYS.Get(i + j - 1) + x.Get(i) * y.Get(i))
the Map x contains: 1 (key) 1 (value).
x.Get(i) results Null only because "i" is declared as Long; if you declare it as Int, 1 is returned as expected.

Still studying :)

In the meantime I am attaching the B4XPages version so you can use it with B4A, B4J and B4i.

I am doing tests with B4J (much more direct, more comfortable debugging).

Thanks
I found 2 problems:

1 - your change to "replace" the Mid$ function (I created a similar function and now this part does not crash);
2 - I have yet to find out why but there are problems using a Long as a Map key.
In this part of your source:
B4X:
XYS.Put(i + j - 1, XYS.Get(i + j - 1) + x.Get(i) * y.Get(i))
the Map x contains: 1 (key) 1 (value).
x.Get(i) results Null only because "i" is declared as Long; if you declare it as Int, 1 is returned as expected.

Still studying :)

In the meantime I am attaching the B4XPages version so you can use it with B4A, B4J and B4i.

I am doing tests with B4J (much more direct, more comfortable debugging).

Thanks LucaMs, Map may be a bit problem. I find two new methods that do not use collections. It is very fast. Although there are still limitations, it has been able to meet my needs.

One way: Formula transformation
[CODE lang="b4x" title="Combination"]Sub Class_Globals
Private Root As B4XView
Private xui As XUI
Dim const e As Double = 2.718281828459
End Sub

Public Sub lnchoose(n As Int,m As Int) As Double
If (m > n) Then Return 0
If (m < n/2.0) Then m=n-m
Dim s1 As Double
s1=0
Dim i As Int
For i=m+1 To n
Dim t1 As Double
t1=i
s1=s1+Logarithm(i,e)
Next
Dim s2 As Double
s2=0
Dim ub As Int
ub = n-m
For i=2 To ub
s2=s2+Logarithm(i,e)
Next
Return s1-s2
End Sub

Public Sub Combination(n As Int,m As Int) As Double
If (m > n) Then Return 0
Return Power(e,lnchoose(n,m))
End Sub

Sub Button1_Click
MsgboxAsync(Combination(1000,500),"fff") 'Result:2.702882409453408E299'
End Sub[/CODE]

Limitations: (1000,500) is the largest combination that can be calculated,but you can cal (2000,200); (5000,150) ......


Another way: use inline Java

[CODE lang="b4x" title="Combination2"]Sub Process_Globals
Private NativeMe As JavaObject
End Sub

#If JAVA
import java.math.BigDecimal;
import java.math.RoundingMode;

public static BigDecimal computePaiLie(int n, int m) {
if(m > n || n < 0 || m < 0) {
throw new IllegalArgumentException("n must >m!");
}
return computerJC(n).divide(computerJC(n - m), 1, RoundingMode.HALF_UP);
}

public static BigDecimal computeZuhe(int n, int m) {
if(m > n || n < 0 || m < 0) {
throw new IllegalArgumentException("n must >m!");
}
//=n!/m!(n-m)!

return computerJC(n).divide((computerJC(m).multiply(computerJC(n - m)).setScale(1, RoundingMode.HALF_UP)), 1, RoundingMode.HALF_UP);
}


public static BigDecimal computerJC(int n) {
if(n < 0) {
throw new IllegalArgumentException("n must >0!");
} else if(n == 0) {
return new BigDecimal(1);
}
BigDecimal bd = new BigDecimal(1.0);
for(int i=n; i>=1; i--) {
bd = bd.multiply(new BigDecimal(i)).setScale(1, RoundingMode.HALF_UP);
}
return bd;
}

#End If

Sub Button1_Click
Dim ZuHe As String = NativeMe.RunMethod("computeZuhe", Array(5000,2500)) 'You can cal very big num'
MsgboxAsync(ZuHe,"fff")
End Sub[/CODE]

Limitations: can't use in b4i,At least i don't know how to use in b4i.
 
Last edited:
Upvote 0
Back
Top