01/10/2018, 09:28

Push two dimention arrays to a stack in java

Mình muốn push array 2 chiều vào 1 stack trong java. Nhưng khi sử dụng pop để lấy giá trị ra thì tất cả các giá trị mà mình pop() nó là giá trị cuối cùng mà mình đã push . Mình thử nhiều cách , đã kiểm tra từng array mà mình push nhưng không hiểu tại sao khi lấy ra thì nó lại bị sai. Ai đó hay giúp mình. please. cảm ơn nhiều ạ.

Tynk Huynk viết 11:40 ngày 01/10/2018

Bạn có hiểu cơ chế làm việc của Stack không vậy ?

Nguyễn Vinh viết 11:39 ngày 01/10/2018

first in last out. bạn nghĩ mình không hiểu chỗ nào

viết 11:32 ngày 01/10/2018

stack là LIFO last in first out…

Tynk Huynk viết 11:43 ngày 01/10/2018

Theo như @tntxtnt hay ý của bạn đều đúng, cứ tưởng tượng Stack là chồng sách

https://img.clipartfest.com/ddaf3b52b9e49382a4dea9d4b051694b_book-stack-book-stack-images_872-1321.png

Lúc đầu bạn đặt cuốn sách đầu tiên lên bàn, tiếp theo đặt cuốn sách thứ 2 lên cuốn đầu tiên, cuốn thứ 3 lên cuốn thứ 2,…cho đến khi cuốn sách cuối cùng được đặt lên tạo thành 1 stack. Nếu bạn muốn lấy cuốn sách đầu tiên (cuốn dưới đáy) thì bắt buộc bạn phải lấy quyển cuối cùng (cuốn trên top) ra khỏi stack, rồi lần lượt lấy ra các quyển còn lại nằm trên cuốn đầu tiên cho đến khi chỉ còn cuốn đầu tiên trên bàn.

Hung viết 11:32 ngày 01/10/2018

Bạn xem stack của bạn có function hay class nào khác sử dụng không? Global variable hay gặp lỗi này.

Nguyễn Vinh viết 11:31 ngày 01/10/2018

mình là mới tạo account nên không đăng ảnh được. mình có up len gg drive phần code và out put . bạn xem giúp mình với
https://drive.google.com/open?id=0B2KHz6ZB5QmXTlhQemZ0MTBseHc

Nguyễn Vinh viết 11:40 ngày 01/10/2018

à cái array 2 chiều ( int[][] board) mình khai báo nó đúng là global variable chứ không phải là local .

Quân viết 11:42 ngày 01/10/2018

Push cùng 1 phần tử nhưng lại muốn Pop ra khác nhau, logic ở đâu vậy.
Bonus: diễn đàn có chức năng post code đó, nên lần sau bạn post code chứ không cần chụp màn hình đâu

Nguyễn Vinh viết 11:34 ngày 01/10/2018

Mình cũng có xem qua 1 câu hỏi tương tự lỗi của mình trên Stackoverflow. cũng nói đến vấn đề dùng cùng 1 object để gọi như vậy thì sẽ bị lỗi như thế này Nhưng mình vẫn không biết cách fix. mình có thử nhiều cách.

Quân viết 11:30 ngày 01/10/2018

Cách fix duy nhất là không push cùng 1 phần tử vào thôi, có thể deep copy nếu cần thiếtt

Nguyễn Vinh viết 11:33 ngày 01/10/2018

Mình có thử tạo clone cho array để push nhưng kết quả cũng tương tự -.- . bạn có thể làm gì đó giúp mình k

Quân viết 11:29 ngày 01/10/2018

Bạn clone ntn, ngoài ra bạn phải chắc chắn rằng dữ liệu của các phần tử push vào cũng có sự khác nhau, nếu không dù có copy thư khi pop vẫn thấy giống y nhau

Nguyễn Vinh viết 11:35 ngày 01/10/2018

Mình tạo 1 array clone cho mỗi lần làm thay đổi original array. sau đó mỗi lần sau khi push mình có dùng hàm peek() để show cái array mình vừa push vào . kết quả nó push đúng sau mỗi lần thay đổi giá trị của array. nhưng khi mình pop ra hết tất n phần tử có trong stack thì nó chỉ trả về n phần thử với giá trị cuối cùng. nghĩa là khi push 1 2 3 thì mình pop ra được 3 3 3

Quân viết 11:29 ngày 01/10/2018

Show me your code!

Nguyễn Vinh viết 11:32 ngày 01/10/2018

public class console {
public static void main(String[] agrs)
{

 demo2048 de = new demo2048(); // contructor này có tạo 1 array 2 chiều size 4*4 giá trị 0
 Stack st = new Stack(); // mình tạo thử 1 stack để test.
 de.addnewcell(); //  add randomly 1 giá trị trong array
 //de.showarr(de.board); // show cho các bạn xem. hàm này mình tạo để show array 
 int[][] a = de.board.clone();
 st.push(a); // push 
 de.showarr((int[][]) st.peek()); // show bằng stack 1 lần nữa để chắc chắn cái mình vừa push

 de.addnewcell(); //  add randomly 1 giá trị trong array
 //de.showarr(de.board); // show cho các bạn xem. hàm này mình tạo để show array 
 int[][] b =de.board.clone();
         
 st.push(b); // push 
 de.showarr((int[][]) st.peek()); // check lần nữa để chắc chắn cái mình vừa push
  
  de.addnewcell(); //  add randomly 1 giá trị trong array
 //de.showarr(de.board); // show cho các bạn xem. hàm này mình tạo để show array 
 int[][] c =de.board.clone();
         
 st.push(c); // push 
 de.showarr((int[][]) st.peek()); // check lần nữa để chắc chắn cái mình vừa push 
    System.out.println("pop");
 while(!st.empty())
 {
     de.showarr((int[][]) st.pop());
 }
Nguyễn Vinh viết 11:41 ngày 01/10/2018

run:
0 0 0 0
0 0 0 0
2 0 0 0
0 0 0 0

0 0 0 0
0 2 0 0
2 0 0 0
0 0 0 0

0 0 0 0
0 2 0 2
2 0 0 0
0 0 0 0

pop
0 0 0 0
0 2 0 2
2 0 0 0
0 0 0 0

0 0 0 0
0 2 0 2
2 0 0 0
0 0 0 0

0 0 0 0
0 2 0 2
2 0 0 0
0 0 0 0

Nguyễn Vinh viết 11:38 ngày 01/10/2018

mình viết thử vài dòng code như vậy :3 coi và sửa giúp mình nhé. cảm ơn :3

Quân viết 11:33 ngày 01/10/2018

Ok, vấn đề ở đây nằm ở chính cách bạn dùng method clone của array trong java, trong java phương thức clone của array chỉ là dạng shallow copy đối với kiểu đối tượng là object, và deepcopy đối với kiểu nguyên thuỷ, do đó khi clone 1 array kiểu object thì array được tạo mới nhưng object là item chúng của 2 array sẽ là 1.
Quay trở lại vấn đề của bạn thì có ý nghĩa gì. 1 array 2 chiều trong java chính là 1 array 1 chiều của các array 1 chiều, hay int[][] sẽ cho kết quả giống với int[int[]] , mà int[] cũng chỉ là object, do đó array của bạn là loại array chứa object, nên khi clone sẽ là shallow copy, nên khi bạn thay đổi nội dung sẽ thấy nó giống nhau là thế đó

Vinh Nguyễn viết 11:31 ngày 01/10/2018

vậy bạn ơi , làm sao để fix, làm sao để push đúng cách. ( do giới hạn về số lượng rep comment của new users nên mình phải log in 1 acc khác ) help me plz

Quân viết 11:40 ngày 01/10/2018

Bạn tự viết 1 hàm copy đi.

int[][] copy2DIntArray(int[][] source){
    final int n = source.length;
    final int[][] copy = new int[n][];
    for (int i = 0; i < n; i++) {
        copy[i] = source [i].clone();
    }
    return copy;
}

Java8

int[][] copy2DIntArray (int[][] source){
    return Arrays.stream(source).map(int[]::clone).toArray(int[][]::new);
}
Bài liên quan
0