2010-03-08 36 views
7

Tôi luôn phải vật lộn với một cái gì đó giống như ví dụ Java sau:Khi tôi đang lặp qua hai mảng cùng một lúc, tôi sẽ sử dụng giới hạn nào làm giới hạn?

String breads[] = {"Brown", "White", "Sandwich"}; 
int count[] = new int[breads.length]; 
for (int i = 0; i < ****; i++) 
{ 
    // Prompt the number of breads 
} 

****: đó array.length tôi nên chọn cái nào?
Tôi có thể chọn giữa breads.lengthcount.length
Tôi biết nó sẽ là kết quả tương tự, nhưng tôi không biết tôi nên chọn người nào.

Có nhiều ví dụ khác mà tôi gặp vấn đề tương tự.
Tôi chắc chắn rằng bạn đã gặp sự cố này cũng như trong quá khứ.

Bạn nên chọn gì? Có thỏa thuận chung nào không?

Cảm ơn

+1

tất nhiên! cảm ơn! –

+0

Tôi không chắc chắn những gì bạn đang yêu cầu. Nếu không biết mục đích của mỗi mục đích thì khó có thể nói (ngoài ra, bạn có ý nghĩa gì để nạp số lượng chuỗi String của bạn với các giá trị int không?). –

+0

Cách bạn thực hiện việc này được gọi là sử dụng "mảng song song". Như nhiều người đã nói, nó có thể có ý nghĩa hơn để sử dụng một bản đồ hoặc một cái gì đó như thế. Nhưng hãy xem http://en.wikipedia.org/wiki/Parallel_array để thảo luận về những lợi thế và bất lợi của con đường bạn. – MatrixFrog

Trả lời

6

Tôi nghĩ rằng tôi hiểu câu hỏi của bạn.

Câu trả lời không sử dụng mảng.

Trong trường hợp này sử dụng bản đồ về:

Map<String, Integer> breadCount = new TreeMap<String, Integer>(); 

breadCount.put("Brown", 0); 
breadCount.put("White", 0); 
breadCount.put("Sandwich", 0); 

Sau đó, chỉ có một "chiều dài", mà là breadCount.size()

Ví dụ là trong Java

+0

Trong tinh thần tương tự, bạn có thể tạo một lớp để nắm bắt cả chuỗi và giá trị Integer, do đó, một lần nữa, có chỉ là một bộ sưu tập (tôi biết Bản đồ lớp không phải là một Bộ sưu tập) – daveb

+0

Bản đồ không phải là một Bộ sưu tập, nhưng bạn có thể thực hiện vòng lặp "cho mỗi" trên đó. Nó kết thúc một chút, nhưng không sao cả. 'for (Entry mục nhập: breadMap.entrySet()) {' ... và sau đó tên bánh là 'entry.getKey()' và số đếm là 'entry.getValue()'. – MatrixFrog

+0

Không đồng ý. Một bản đồ chỉ có ý nghĩa khi bạn cần để có thể tìm kiếm mọi thứ thay vì lặp lại theo thứ tự. Nếu không, một mảng có nhiều không gian hiệu quả hơn và là cấu trúc dữ liệu mẫu số chung thấp nhất tốt đẹp có nhiều khả năng là bản đồ được chấp nhận bởi các hàm thư viện chung. – dsimcha

0

Sử dụng Danh sách, Bộ và Bản đồ và vòng lặp foreach.

Nếu bạn thực sự phải sử dụng mảng và không thể sử dụng vòng lặp foreach, điều đó không quan trọng.

+1

Vòng lặp foreach không thể lặp qua hai bộ sưu tập cùng một lúc. –

+0

Đúng, nhưng trong nhiều trường hợp chỉ cần thêm các phần tử vào cuối danh sách là đủ. Trong các trường hợp khác, sử dụng Phần tử của Bộ sưu tập đầu tiên làm khóa và giá trị của giây làm giá trị trong Bản đồ hoạt động tốt. –

5

Sử dụng breads.length nhiều chính xác từ count kích thước phụ thuộc vào breads chiều dài, nhưng ngoài việc đó các kết quả khác nhau sẽ giống nhau .. và điều này phải được sự thật bất cứ khi nào bạn hoạt động theo một cách tương tự như bạn đã viết.

Nếu bạn thực sự không muốn được annoyied bởi những câu hỏi siêu hình này bạn có thể sử dụng một lớp đơn giản:

class Bread 
{ 
    String name; 
    int count 
} 

hoặc bạn có thể sử dụng một mảng đa chiều, hay cũng là một hashmap:

HashMap<String, Integer> counts 

để bạn có thể lặp lại trên bộ sưu tập thực trong khi thu thập các giá trị từ các bản đồ:

for (String b : breads) 
    System.out.println(b + " count: "+counts.get(b)); 
+0

Tôi không nghĩ "chính xác" thực sự là từ đúng. Có thể "trực tiếp". Dù sao, +1 cho lớp Bread. Các mảng song song là một dấu hiệu cho thấy bạn thực sự muốn một mảng các bản ghi, và các đối tượng là cách để làm các bản ghi trong một ngôn ngữ OOP. –

+0

Vâng, chính xác không phải là từ thích hợp nhưng tiếng Anh không phải là ngôn ngữ mẹ đẻ của tôi nên nó không xảy ra * chính xác * như tôi muốn :) – Jack

+0

Vấn đề với việc tạo một lớp như thế này là điều xảy ra khi bạn muốn vượt qua chỉ là mảng bánh mì hoặc chỉ là mảng đếm đến một hàm thư viện chung? Để giao tiếp với mã chung, một mảng nguyên thủy hầu như luôn dễ dàng hơn để làm việc với hầu hết các ngôn ngữ. – dsimcha

0

Nó phụ thuộc những gì bạn đang làm, nhưng cuối cùng điều này hiếm khi là một quyết định quan trọng (vì giá trị giống nhau). Có lẽ lo lắng về vấn đề "lớn hơn". Đối với lãi suất, trong NET JIT (không trình biên dịch) có thể nhận ra mô hình này và loại bỏ các out-of-bounds séc, nhưng chỉ khi nó là một cái gì đó hiển nhiên như:

for(int i = 0 ; i < arr.Length ; i++) { 
    Console.WriteLine(arr[i]); // no bounds check if the JIT can prove it will 
           // never fail 
} 
1

Trong kịch bản này, tôi sẽ đi với breads vì đó là cách bạn sẽ giải thích mã.

Về mặt logic, bạn đang lặp qua từng loại bánh, chứ không phải số lượng bánh mì (mặc dù nó giống nhau).

Hãy tưởng tượng bạn đang giải thích mã của mình cho người khác và sử dụng bất kỳ điều gì có ý nghĩa từ quan điểm đó. Đôi khi cả hai đều có ý nghĩa, trong trường hợp đó bạn chỉ cần chọn tùy ý.

0

Tôi muốn nói chọn "chính "mảng và sử dụng chiều dài của nó ở khắp mọi nơi. Bằng cách này, mã của bạn rõ ràng và dễ đọc hơn. Ngoài ra, tôi nghĩ nó không thực sự quan trọng, bởi vì count.length sẽ giống nhau và bạn có thể trộn hai thứ này theo ý muốn.

0

Đường may vấn đề này khá dễ mắc - nhưng trong trường hợp của bạn, tôi thích mảng mà bạn dự định thay đổi (đếm), vì trong một số trường hợp (số ca), chiều dài của bánh mì và số lượng sẽ khác nhau , nó luôn luôn là tốt nhất để không chạy vào mảng bounds rắc rối ...

Vẫn có thể có một giải pháp khác nhau: Chỉ có một mảng - có chứa cấu trúc với tên ("bánh mì" có thể cũng được gọi là "breadNames") và đếm ...

+0

Tại sao cách tiếp cận của bạn ngăn chặn sự cố về mảng bị ràng buộc? Để đạt được điều đó bạn sẽ phải sử dụng một cái gì đó như tối thiểu của hai chiều dài. Mà tôi sẽ xem xét mã obfuscation. –

+0

Bởi vì nó nhìn tôi như là chỉ có mảng đếm sẽ được sử dụng trong vòng lặp. "nhắc nhở số lượng bánh mì" - và (như tôi hiểu vấn đề) sẽ là một vòng lặp mà đầu vào đếm ... vì vậy chỉ có mảng đếm sẽ được xúc động. – Juergen

1

Trong tình huống như vậy, tôi khai báo biến cục bộ. Như thế này:

int n = breads.length; 
int[] count = new int[n]; 
for (int i = 0; i < n; i ++) { 
    // ... 
} 

Về mặt khái niệm, điều này có nghĩa là tôi tự đặt "giá trị vòng" một giá trị. Một tác dụng phụ là vấn đề của bạn được giải quyết.

0

Tôi sẽ cố tránh các mảng khác nhau hoàn toàn. Thường xuyên hơn không, nếu bạn có hai mảng có cùng kích thước tại mọi thời điểm bạn thực sự giả mạo một loại hợp chất hoặc một mối quan hệ.

// C++: inventory map: 
std::map< std::string, int > bread_inventory; 
bread_inventory["White"] = 0; 
bread_inventory["Brown"] = 0; 
bread_inventory["Sandwich"] = 0; 

// C++: complex type: 
struct bread_type 
{ 
    bread_type(std::string const & name, int calories) 
     : name(name), calories(calories) {} 
    std::string name; 
    int calories; 
}; 
std::vector<bread_type> v; 
v.push_back(bread_type("White", 100)); 
v.push_back(bread_type("Brown", 90)); 

Bằng cách sử dụng các loại bê tông hoặc container (so với các yếu tố không liên quan trong các thùng chứa khác nhau) bạn sẽ có được sự gắn kết miễn phí (chăm sóc ít phải được thực hiện để xác minh rằng cả hai container được cập nhật trong cùng một cách) và một số hoạt động trở đơn giản hơn nhiều (sắp xếp véc tơ bằng calo có thể được thực hiện một cách trivially với một hàm thứ tự, trong khi nếu bạn giữ hai vector riêng biệt cho các tên và các giá trị liên quan, bạn sẽ phải chiến đấu theo cách của bạn để đảm bảo rằng các hoạt động tương tự được thực hiện trên cả hai thùng chứa.

Mã cũng dễ dàng hơn để theo dõi và duy trì khi các loại đang nói cho người lập trình biết người viết muốn gì. n mà bạn có khi viết lớp bị mất trong quá trình thực hiện của bạn. Việc triển khai của bạn là đối phó với một loạt các loại bánh mì và một mảng đếm, nhưng mã không cho bạn biết rằng thực tế chúng là một thực thể duy nhất.

0

Bạn đang sử dụng for(int i=0; i<array.length; i++) để lặp qua các giá trị của mảng. Vì vậy, bạn thực sự muốn sử dụng array[i] và không phải cái gì khác. Trong trường hợp của bạn, bạn muốn lặp qua các tên mà bạn đã xác định. Tuy nhiên, mảng đếm được điền với số không và câu hỏi là lý do tại sao bạn muốn lặp lại chúng. Vì vậy, nếu bạn viết

String breads[] = {"Brown", "White", "Sandwich"}; 
int count[] = new int[breads.length]; 
for (int i = 0; i < breads.length; i++) { 
} 

bạn thấy rõ rằng vòng lặp dành cho việc lặp qua tên. Và bạn đối phó với những cái tên này (như hiển thị chúng). Nhưng nếu bạn viết

String breads[] = {"Brown", "White", "Sandwich"}; 
int count[] = new int[breads.length]; 
for (int i = 0; i < count.length; i++) { 
} 

Câu hỏi tăng tại sao bạn muốn lặp qua các giá trị đếm? tất cả đều là 0. Luồng dữ liệu thực sự giống như count_value = f(bread_value), tên bánh là independent variable. Bạn có thể viết (bằng Java)

String breads[] = {"Brown", "White", "Sandwich"}; 
int count[] = new int[breads.length]; 
for (String bread: breads) { 
} 

và thấy rõ rằng bạn quan tâm đến tên bánh mì và muốn làm điều gì đó với chúng. Bạn muốn đặt số số chỉ là một tác động phụ của vòng lặp, nhưng nó không kiểm soát thời gian lặp lại.

Các vấn đề liên quan