我遇到的问题一直困扰着我几天。我正在做大学校园,我必须乘以2个大数字(每个数字最多可达10000位),因此我必须使用数组。 我必须使用一个特殊的公式使用天真的分治法,它正在工作,我得到正确的输出。 问题虽然该程序的ram使用率达到715MB,而测试我的输出的大学服务器只允许小于10MB的峰值! 我使用visualVM来获取一些统计信息,它表明在main方法结束时我打开了超过25.000个int数组,这显然意味着垃圾收集器不会清理它们。我尝试通过array = null手动删除数组,但它没有任何效果。更重要的是,程序中的数组大小对ram的使用没有影响,如果我使所有数组大小为10000或者如果我使它们变小,那么ram的使用率仍然是715MB。我没有尝试过甚至使用RAM的1Kb差异。我做错了什么?
import java.util。*;
公共课Naloga2 {
static int firstNumberLength;
static int secondNumberLength;
static int count;
public static void main(String[] args) {
firstNumberLength = 0;
secondNumberLength = 0;
start(args);
System.out.println("Check memory usage and press any key");
Scanner scan = new Scanner(System.in);
scan.nextLine();
}
static void printArray(int[] a, int length) {
for(int i=0;i<length;i++) System.out.print(a[i]);
System.out.println();
}
static void printArrayNoNewLine(int[] a, int length) {
for(int i=0;i<length;i++) System.out.print(a[i]);
}
static int[] obrniTabelo(int[] tabela, int dolzinaTabele) {
int[] novaTabela = new int[firstNumberLength + secondNumberLength];
for(int i=0;i<dolzinaTabele;i++) {
novaTabela[i] = tabela[dolzinaTabele - i - 1];
}
return novaTabela;
}
static void readNumbers(int[] a, int[] b) {
Scanner sc = new Scanner(System.in);
String temp1 = "1814760427359093701773634896055154238604621068079345503988844965147764988324706056377247443923778795928948605699104801900306908537904148935233121873094936503998915865745862371767010306054062906768898568957847355344002122176514654744790212626620584107994283130875249861052935175219132106429755509971192581933953801388381188460986660581979158129483917001271702223407654800335931472019985629221607213865018069283189966200621625300134";
String temp2 = "97512060979417027247066473890437645860252983792423404628415959133594150264916901106891610016700858329869623573382829998749019896997745761637960733420798357562414782788848733769941600640359229331196534760613331886605807310229536529299047661042932723686940506490467693828359124032044766542882911974806517818312853119004786073768385133003204124346870416398337405003873260912959735781385513491033737150032844086069531948792576932151901897811096445945530418292434773408981209319417729967465446257427784080363848953538788259430643983374127862528899812266699138053211381274176090725067261872355977420957399650610409274997690573284775365452519492094199150332836530293736450846555043855394905294740708235099468050036111579819724363868989787277506605869758256547608040247461962450653542826639244219294087064008107664753142535552152880164752050308970662812876788273331513642358933315796998961151437131149920030780118660547331872894504653590764949555989125948482198399816531852334011945495558518939896596518131272300822293060394523495515862731265541258202053045616084735425799134171661329905235453695720851880506732702524221829703587444566936446048580047972702945614278702240636251666791566010549308512827456794434888225729025123511920552233844557238739513734443927750297099927757353661453279831551902974620243283691649185034824294607701567938075725970651517685420371143465190361476038554928265834067374093805712372282561321345651430079136538347289657425955000036298701183558407903511884604388721633166414508318158";
firstNumberLength = temp1.length();
secondNumberLength = temp2.length();
for(int i=0;i<firstNumberLength;i++) a[i] = temp1.charAt(i) - 48;
for(int i=0;i<secondNumberLength;i++) b[i] = temp2.charAt(i) - 48;
}
static void start(String[] args) {
int a[] = new int[10000];
int b[] = new int[10000];
readNumbers(a, b);
int aa[] = new int[firstNumberLength];
int bb[] = new int[secondNumberLength];
for(int i=0;i<firstNumberLength;i++) aa[i] = a[i];
for(int i=0;i<secondNumberLength;i++) bb[i] = b[i];
dv(aa, bb, "count");
}
static int[] steviloPlusSteviloRu (int[] a, int[] b, int[] tempDolzina) {
a = obrniTabelo(a, tempDolzina[0]);
b = obrniTabelo(b, tempDolzina[1]);
int prenos = 0;
if(tempDolzina[0] < tempDolzina[1]) {
tempDolzina[0] = tempDolzina[1];
}
int limit = tempDolzina[1];
for(int i=0;i<tempDolzina[1];i++) {
a[i] = a[i] + b[i] + prenos;
prenos = 0;
if(a[i] > 9) {
prenos = a[i] / 10;
a[i] = a[i] % 10;
}
}
while(prenos > 0) {
if(prenos > 9) System.out.println("prenos nad 9, error !");
a[limit] = a[limit] + prenos;
prenos = 0;
if(a[limit] > 9) {
prenos = a[limit] / 10;
a[limit] = a[limit] % 10;
}
if(limit == tempDolzina[0]) tempDolzina[0]++;
limit++;
}
a = obrniTabelo(a, tempDolzina[0]);
return a;
}
static int[] stevkaKratSteviloDv(int[] a, int b, int[] length) { // dv - mnozenje z stevko
int prenos = 0;
a = obrniTabelo(a, length[0]);
for(int i=0;i<length[0];i++) {
a[i] = a[i] * b + prenos;
prenos = 0;
if(a[i] > 9) {
prenos = a[i] / 10;
a[i] = a[i] % 10;
}
}
if(prenos > 0 ) {
if(prenos > 9) System.out.println("prenos vecji od 9 !!");
a[length[0]] = prenos;
length[0]++;
}
a = obrniTabelo(a, length[0]);
return a;
}
static void dv(int[] a, int[] b, String m) { // dk
int mode = 0;
if(m.equals("count")) mode = 1;
if(mode == 1) {
printArray(a, firstNumberLength);
printArray(b, secondNumberLength);
}
int[] dolzine = {firstNumberLength, secondNumberLength};
int[] dolzina = {firstNumberLength, secondNumberLength};
int[] len1 = {firstNumberLength};
int[] len2 = {secondNumberLength};
int[] len3 = new int[1];
int[] rezultat = dvRek(a, b, len1, len2, len3, mode);
rezultat = odstrani(rezultat, len3);
if(mode == 0) {
printArray(rezultat, len3[0]);
} else System.out.println(count);
}
static int[] subSet(int[] aa, int[] length, int mode) { // returns subset, depends on mode
int dolzina = length[0];
if(dolzina < 2) {
System.out.println("error, dolzina je " + dolzina);
return aa;
}
int start = 0;
int stop = dolzina / 2;
if(mode == 1) {
start = dolzina / 2;
stop = dolzina;
}
int[] temp = new int[length[0]];
int index = 0;
for(int i=start;i<stop;i++) {
temp[index] = aa[i];
index++;
}
length[0] = (stop - start);
aa = null;
return temp;
}
static int[] dodajNicle(int[] aa, int[] length, int num) { // adds zeroes, basicly multiplying with 10^num
int[] temp = new int[length[0] + num];
for(int i=0;i<length[0];i++) temp[i] = aa[i];
for(int i=0;i<num;i++) {
temp[length[0]] = 0;
length[0]++;
}
aa = null;
return temp;
}
static int[] dopolni(int[] aa, int[] length, int num) { // adds num zeros at start and returns
aa = obrniTabelo(aa, length[0]);
int start = length[0];
int end = start + num;
for(int i=start;i<end;i++) aa[i] = 0;
length[0] = length[0] + num;
aa = obrniTabelo(aa, length[0]);
return aa;
}
static int[] odstrani(int[] aa, int[] length) { // removes zeros from beginning
aa = obrniTabelo(aa, length[0]);
for(int i=(length[0]-1);i>0;i--)
if(aa[i] == 0) length[0]--;
else break;
aa = obrniTabelo(aa, length[0]);
return aa;
}
static int[] dvRek (int[] a, int[] b, int[] lengthA, int[] lengthB, int[] lengthC, int mode) {
a = odstrani(a, lengthA);
b = odstrani(b, lengthB);
if(mode == 0) {
printArrayNoNewLine(a, lengthA[0]);
System.out.print(" ");
printArray(b, lengthB[0]);
}
if(lengthA[0] == 1) {
if(a[0] == 0) {
lengthC[0] = 1;
return new int[1];
}
int temp = lengthB[0];
int minus = 0;
for(int i=0;i<temp;i++) {
if(b[i] == 0) minus++;
if(b[i] > 0) break;
}
count = count + temp - minus;
b = stevkaKratSteviloDv(b, a[0], lengthB);
lengthC[0] = lengthB[0];
lengthB[0] = temp;
return b;
} else if (lengthB[0] == 1) {
if(b[0] == 0) {
lengthC[0] = 1;
return new int[1];
}
int temp = lengthA[0];
int minus = 0;
for(int i=0;i<temp;i++) {
if(a[i] == 0) minus++;
if(a[i] > 0) break;
}
count = count + temp - minus;
a = stevkaKratSteviloDv(a, b[0], lengthA);
lengthC[0] = lengthA[0];
return a;
} else {
if(lengthA[0] > lengthB[0]) {
b = dopolni(b, lengthB, (lengthA[0] - lengthB[0]));
}
else if (lengthA[0] < lengthB[0]) {
a = dopolni(a, lengthA, (lengthB[0] - lengthA[0]));
}
int[] a1Len = { lengthA[0] };
int[] a0Len = { lengthA[0] };
int[] b1Len = { lengthB[0] };
int[] b0Len = { lengthB[0] };
int[] a1 = subSet(a, a1Len, 0);
int[] a0 = subSet(a, a0Len, 1);
int[] b1 = subSet(b, b1Len, 0);
int[] b0 = subSet(b, b0Len, 1);
a = null;
b = null;
int[] temp = new int[1];
int[] tempp = new int[1];
temp[0] = b0Len[0];
tempp[0] = a0Len[0];
int[] a0b0 = dvRek(a0, b0, tempp, temp, lengthC, mode);
int[] a0b0Len = { lengthC[0] };
temp[0] = b1Len[0];
tempp[0] = a0Len[0];
int[] a0b1 = dvRek(a0, b1, tempp, temp, lengthC, mode);
int[] a0b1Len = { lengthC[0] };
//a1b0
temp[0] = b0Len[0];
tempp[0] = a1Len[0];
int[] a1b0 = dvRek(a1, b0, tempp, temp, lengthC, mode);
int[] a1b0Len = { lengthC[0] };
//a1b1
temp[0] = b1Len[0];
tempp[0] = a1Len[0];
int[] a1b1 = dvRek(a1, b1, tempp, temp, lengthC, mode);
int[] a1b1Len = { lengthC[0] };
int n = lengthA[0];
if(lengthB[0] > n) n = lengthB[0];
if(n % 2 != 0) n++;
int[] temp1 = dodajNicle(a1b1, a1b1Len, n );
int[] dolzine = {a0b1Len[0], a1b0Len[0]};
int[] temp2 = steviloPlusSteviloRu(a0b1, a1b0, dolzine);
temp2 = dodajNicle(temp2, dolzine, (n/2) );
int[] dolzine1 = {a1b1Len[0], dolzine[0]};
int[] temp3 = steviloPlusSteviloRu(temp1, temp2, dolzine1);
int[] dolzine2 = {dolzine1[0], a0b0Len[0] };
int[] temp4 = steviloPlusSteviloRu(temp3, a0b0, dolzine2);
lengthC[0] = dolzine2[0];
a = null;
b = null;
a0b0 = null;
a1b0 = null;
a0b1 = null;
a1b1 = null;
a0 = null;
a1 = null;
b0 = null;
b1 = null;
lengthA = null;
lengthB = null;
lengthC = null;
temp = null;
tempp = null;
dolzine = null;
dolzine1 = null;
dolzine2 = null;
temp1 = null;
temp2 = null;
temp3 = null;
return temp4;
}
}
}