Android Question Hot to Redim this array?

watesoft

Active Member
Licensed User
Longtime User
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

  • 1.zip
    8.7 KB · Views: 173
Upvote 0

LucaMs

Expert
Licensed User
Longtime User
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

  • Project.zip
    9.6 KB · Views: 193
Upvote 0

stevel05

Expert
Licensed User
Longtime User
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

stevel05

Expert
Licensed User
Longtime User
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

LucaMs

Expert
Licensed User
Longtime User
1604393611860.png

;)
 
Upvote 0

watesoft

Active Member
Licensed User
Longtime User
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
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

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


Another way: use inline Java

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

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