2011-11-07 29 views
11

Tôi có nhiệm vụ này mà tôi phải xóa một yếu tố được lựa chọn từ một mảng, vì vậy tôi đã đưa ra với mã này:Làm thế nào để xóa một phần tử đã chọn trong mảng?

strInput = Console.ReadLine(); 
for (int i = 0; i < intAmount; i++) 
{ 
    if (strItems[i] == strInput) 
    { 
     strItems[i] = null; 
     for (int x = 0; x < intAmount-i; x++) 
     { 
      i = i + 1; 
      strItems[i - 1] = strItems[i]; 
     } 
     intAmount = intAmount - 1; 
    } 
} 

Vấn đề là, giả sử tôi có một mảng [1,2,3,4,5,], và tôi muốn xóa 1 . Đầu ra sẽ là [2,3,4,5,5]. Điều này cũng xảy ra khi tôi chọn 2, nhưng điều đó không xảy ra khi tôi chọn bất kỳ số nào khác.

Tôi đang làm gì sai?

+2

gì là 'intAmount' và' strItems'? Bạn đang làm rất nhiều thao tác của các chỉ số vòng lặp của bạn trong vòng lặp của bạn, mà thường là một ý tưởng tồi. –

+0

Bạn có thể làm rõ câu hỏi của mình: bạn nói [1,2,3,4,5], với thao tác xóa 1, trở thành [2,3,4,5,5]. Làm thế nào để bạn chọn 5 là yếu tố để nhân đôi vào cuối? – ssamuel

+0

strItems là mảng chuỗi, intAmount là số phần tử và strInput là phần tử mà người dùng chọn để xóa. – user1033065

Trả lời

33

Tôi giả sử bạn đang làm việc với một mảng cơ bản của chuỗi:

var strItems = new string[] { "1", "2", "3", "4", "5" }; 

Trong .NET, mảng đó là luôn luôn sẽ dài 5 yếu tố. Để loại bỏ một phần tử, bạn sẽ phải sao chép các phần tử còn lại vào một mảng mới và trả về nó. Đặt giá trị tại vị trí thành null không xóa giá trị đó khỏi mảng.

Bây giờ, với những thứ như LINQ này là rất dễ dàng (không hiển thị ở đây), hoặc bạn có thể gian lận bằng cách sử dụng bộ sưu tập List<> và làm điều này:

var list = new List<string>(strItems); 
list.Remove("3"); 
strItems = list.ToArray(); 

Nhưng tôi không nghĩ rằng điều đó sẽ dạy cho bạn bất cứ điều gì.

Bước đầu tiên là tìm chỉ mục của phần tử bạn muốn xóa. Bạn có thể sử dụng Array.IndexOf để giúp bạn. Hãy tìm phần tử ở giữa, "3":

int removeIndex = Array.IndexOf(strItems, "3"); 

Nếu phần tử không được tìm thấy, nó sẽ trả về -1, vì vậy hãy kiểm tra điều đó trước khi làm bất cứ điều gì.

if (removeIndex >= 0) 
{ 
    // continue... 
} 

Cuối cùng, bạn phải sao chép các phần tử (ngoại trừ phần tử mà chúng tôi không muốn) vào mảng mới. Vì vậy, hoàn toàn, bạn kết thúc với một cái gì đó như thế này (bình luận cho lời giải thích):

string strInput = Console.ReadLine(); 
string[] strItems = new string[] { "1", "2", "3", "4", "5" }; 

int removeIndex = Array.IndexOf(strItems, strInput); 

if (removeIndex >= 0) 
{ 
    // declare and define a new array one element shorter than the old array 
    string[] newStrItems = new string[strItems.Length - 1]; 

    // loop from 0 to the length of the new array, with i being the position 
    // in the new array, and j being the position in the old array 
    for (int i = 0, j = 0; i < newStrItems.Length; i++, j++) 
    { 
     // if the index equals the one we want to remove, bump 
     // j up by one to "skip" the value in the original array 
     if (i == removeIndex) 
     { 
      j++; 
     } 

     // assign the good element from the original array to the 
     // new array at the appropriate position 
     newStrItems[i] = strItems[j]; 
    } 

    // overwrite the old array with the new one 
    strItems = newStrItems; 
} 

Và bây giờ strItems sẽ là mảng mới, trừ đi giá trị quy định để loại bỏ.

+0

Chà! Thật là một câu trả lời hoàn chỉnh và giải thích! – zazkapulsk

1
  • Mảng có kích thước cố định, bạn không thể rút ngắn độ dài của chúng mà không tạo mảng mới. Tất cả những gì bạn có thể làm là lưu trữ độ dài hợp lệ yếu tố trong mảng (ví dụ: sau khi bạn xóa 1 độ dài là 4). Ngoài ra, tôi không chắc liệu thứ tự của các phần tử trong mảng của bạn có quan trọng hay không, nhưng nếu không, bạn có thể hoán đổi phần tử đầu tiên và cuối cùng thay vì di chuyển mọi phần tử sau phần tử bị xóa về trước 1 vị trí.

  • Cách thay thế cho việc sử dụng mảng là sử dụng bộ sưu tập như ArrayList sẽ giúp bạn thay đổi kích thước, xóa và đếm số lượng vật phẩm trong đó, cộng thêm nhiều thứ khác.

  • Tuy nhiên, vì đây là bài tập về nhà, bạn có thể phải sử dụng mảng. Hãy theo dõi độ dài bằng một biến, thay vì sử dụng array.length hoặc tạo một mảng mới mỗi khi bạn muốn thay đổi kích thước.Nếu bạn không phải sử dụng mảng thì hãy xem các bộ sưu tập bạn có thể sử dụng trong C#.

3

Mảng trong C# có một kích thước cố định - một khi khởi tạo, bạn chỉ có thể sửa đổi các mặt hàng, nhưng bạn không thể thêm hoặc xoá các mục. Nếu bạn muốn xóa một mục khỏi bộ sưu tập, bạn có hai tùy chọn:

1.) Tạo một mảng mới có tất cả thành viên của mảng ban đầu trừ đi phần bạn muốn xóa.

2.) Sử dụng loại bộ sưu tập có thể thay đổi kích thước và cho phép thêm hoặc xóa các mục như List<T> (List<int> trong trường hợp của bạn). Đây là những gì bạn sẽ làm trong "thế giới thực" nếu bộ sưu tập của bạn không tĩnh.

3

Trong triển khai cụ thể của bạn, tôi nghĩ rằng u bỏ lỡ một tuyên bố break;, bạn nên đi ra ngoài từ vòng lặp bên ngoài khi bạn hoàn thành vòng lặp bên trong. Việc gán cho null không hữu ích chút nào.

Nếu danh sách chỉ là danh sách các số tại sao bạn sử dụng chuỗi? sử dụng số nguyên trực tiếp nếu đúng như vậy.

Bài tập của bạn dường như hỏi một cái gì đó như thế này, nếu bạn chỉ cần loại bỏ một phần tử.

public bool MyDelete(int[] array, int value) // Easy to do for strings too. 
{ 
    bool found = false; 
    for (int i = 0; i < array.Length; ++i) 
    { 
     if (found) 
     { 
      array[i - 1] = array[i]; 
     } 
     else if (array[i] == value) 
     { 
      found = true; 
     } 
    } 
    return found; 
} 

Chức năng này sẽ trả về true nếu tìm thấy khoảng trống được chỉ định, sai nếu không. Nó sẽ di chuyển tất cả các mục như bạn mô tả trong ví dụ của bạn, nhưng tất nhiên, nó sẽ không thay đổi kích thước của mảng.

Mảng có kích thước cố định. Bạn không thể thay đổi kích cỡ của một mảng, đơn giản là ngôn ngữ không cho phép điều đó. Mảng được, đã và sẽ luôn luôn kích thước cố định!

Để xóa một mục từ một mảng bạn nên làm điều gì đó này:

public static T[] RemoveAt<T>(T[] array, int index) // hope there are not bugs, wrote by scratch. 
{ 
    int count = array.Length - 1; 
    T[] result = new T[count]; 

    if (index > 0) 
     Array.Copy(array, 0, result, 0, index - 1); 
    if (index < size) 
     Array.Copy(array, index + 1, result, index, size - index); 

    return result; 
} 

... 
strItems = RemoveAt(strItems, index); 

Chức năng này sẽ tạo ra một mảng mới có chứa tất cả các yếu tố ngoại trừ một ít chỉ số bạn chỉ định.

Bây giờ, tại sao một người nào đó sẽ làm điều gì đó như thế này thay vì sử dụng Danh sách hoặc Từ điển hoặc bất kỳ điều gì? Sử dụng trực tiếp Danh sách mà không cần sử dụng mảng.

2

có thể sử dụng Trừ phương pháp để lọc dữ liệu

AllData = {10, 30, 20, 50} 

FilterData = {30, 20} 

Result = AllData.Except(​FilterData) 

Ta được kết quả {10, 50}

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