Saya sedang mengerjakan formulir windows untuk menghitung UPC untuk nomor item.
Saya berhasil membuat satu yang akan menangani satu nomor item / UPC pada suatu waktu, sekarang saya ingin memperluas dan melakukannya untuk beberapa nomor item / UPC.
Saya sudah mulai dan mencoba menggunakan daftar, tetapi saya terus macet. Saya membuat kelas pembantu:
public class Codes
{
private string incrementedNumber;
private string checkDigit;
private string wholeNumber;
private string wholeCodeNumber;
private string itemNumber;
public Codes(string itemNumber, string incrementedNumber, string checkDigit, string wholeNumber, string wholeCodeNumber)
{
this.incrementedNumber = incrementedNumber;
this.checkDigit = checkDigit;
this.wholeNumber = wholeNumber;
this.wholeCodeNumber = wholeCodeNumber;
this.itemNumber = itemNumber;
}
public string ItemNumber
{
get { return itemNumber; }
set { itemNumber = value; }
}
public string IncrementedNumber
{
get { return incrementedNumber; }
set { incrementedNumber = value; }
}
public string CheckDigit
{
get { return checkDigit; }
set { checkDigit = value; }
}
public string WholeNumber
{
get { return wholeNumber; }
set { wholeNumber = value; }
}
public string WholeCodeNumber
{
get { return wholeCodeNumber; }
set { wholeCodeNumber = value; }
}
}
Kemudian saya mulai dengan kode saya, tetapi masalahnya adalah prosesnya bertahap, artinya saya mendapatkan nomor item dari kotak-kotak melalui kotak centang dan memasukkannya ke dalam daftar. Kemudian saya mendapatkan UPC terakhir dari basis data, menghapus checkdigit, lalu menambah jumlahnya satu per satu dan memasukkannya ke dalam daftar. Lalu saya menghitung checkdigit untuk nomor baru dan memasukkannya ke dalam daftar. Dan di sini saya sudah mendapatkan Pengecualian Kehabisan Memori. Berikut adalah kode yang saya miliki sejauh ini:
List<Codes> ItemNumberList = new List<Codes>();
private void buttonSearch2_Click(object sender, EventArgs e)
{
//Fill the datasets
this.immasterTableAdapter.FillByWildcard(this.alereDataSet.immaster, (textBox5.Text));
this.upccodeTableAdapter.FillByWildcard(this.hangtagDataSet.upccode, (textBox5.Text));
this.uPCTableAdapter.Fill(this.uPCDataSet.UPC);
string searchFor = textBox5.Text;
int results = 0;
DataRow[] returnedRows;
returnedRows = uPCDataSet.Tables["UPC"].Select("ItemNumber = '" + searchFor + "2'");
results = returnedRows.Length;
if (results > 0)
{
MessageBox.Show("This item number already exists!");
textBox5.Clear();
//clearGrids();
}
else
{
//textBox4.Text = dataGridView1.Rows[0].Cells[1].Value.ToString();
MessageBox.Show("Item number is unique.");
}
}
public void checkMarks()
{
for (int i = 0; i < dataGridView7.Rows.Count; i++)
{
if ((bool)dataGridView7.Rows[i].Cells[3].FormattedValue)
{
{
ItemNumberList.Add(new Codes(dataGridView7.Rows[i].Cells[0].Value.ToString(), "", "", "", ""));
}
}
}
}
public void multiValue1()
{
_value = uPCDataSet.UPC.Rows[uPCDataSet.UPC.Rows.Count - 1]["UPCNumber"].ToString();//get last UPC from database
_UPCNumber = _value.Substring(0, 11);//strip out the check-digit
_UPCNumberInc = Convert.ToInt64(_UPCNumber);//convert the value to a number
for (int i = 0; i < ItemNumberList.Count; i++)
{
_UPCNumberInc = _UPCNumberInc + 1;
_UPCNumberIncrement = Convert.ToString(_UPCNumberInc);//assign the incremented value to a new variable
ItemNumberList.Add(new Codes("", _UPCNumberIncrement, "", "", ""));//**here I get the OutOfMemoreyException**
}
for (int i = 0; i < ItemNumberList.Count; i++)
{
long chkDigitOdd;
long chkDigitEven;
long chkDigitSubtotal;
chkDigitOdd = Convert.ToInt64(_UPCNumberIncrement.Substring(0, 1)) + Convert.ToInt64(_UPCNumberIncrement.Substring(2, 1)) + Convert.ToInt64(_UPCNumberIncrement.Substring(4, 1)) + Convert.ToInt64(_UPCNumberIncrement.Substring(6, 1)) + Convert.ToInt64(_UPCNumberIncrement.Substring(8, 1)) + Convert.ToInt64(_UPCNumberIncrement.Substring(10, 1));
chkDigitOdd = (3 * chkDigitOdd);
chkDigitEven = Convert.ToInt64(_UPCNumberIncrement.Substring(1, 1)) + Convert.ToInt64(_UPCNumberIncrement.Substring(3, 1)) + Convert.ToInt64(_UPCNumberIncrement.Substring(5, 1)) + Convert.ToInt64(_UPCNumberIncrement.Substring(7, 1)) + Convert.ToInt64(_UPCNumberIncrement.Substring(9, 1));
chkDigitSubtotal = (300 - (chkDigitEven + chkDigitOdd));
_chkDigit = chkDigitSubtotal.ToString();
_chkDigit = _chkDigit.Substring(_chkDigit.Length - 1, 1);
ItemNumberList.Add(new Codes("", "",_chkDigit, "", ""));
}
Apakah ini cara yang tepat untuk melakukannya, menggunakan daftar, atau haruskah saya melihat cara yang berbeda?
Code
kelas Anda ) berlebihan dan tidak ada apa-apa selain kebisingan,{ get; private set; }
sudah cukup.Jawaban:
Saya akan memperluas komentar saya:
Kerusakan Cepat
Array baik ketika Anda memiliki sejumlah elemen tetap yang tidak mungkin berubah, dan Anda ingin mengaksesnya dengan cara yang tidak berurutan.
Linked-Lists dioptimalkan untuk penambahan dan pemindahan cepat di kedua ujung, tetapi lambat diakses di tengah.
Daftar Array (seperti
List<T>
dalam C #!) Adalah campuran dari keduanya, dengan penambahan yang cukup cepat dan akses acak.List<T>
akan sering menjadi koleksi masuk Anda ketika Anda tidak yakin apa yang harus digunakan.Bagaimana Array Bekerja
Kebanyakan bahasa memodelkan array sebagai data yang berdampingan dalam memori, di mana setiap elemen memiliki ukuran yang sama. Katakanlah kita memiliki array
int
s (ditampilkan sebagai [alamat: nilai], menggunakan alamat desimal karena saya malas)Masing-masing elemen ini adalah integer 32-bit, jadi kita tahu berapa banyak ruang yang diperlukan dalam memori (32 bit!). Dan kita tahu alamat memori dari pointer ke elemen pertama.
Sangat mudah untuk mendapatkan nilai dari elemen lain dalam array itu:
Katakanlah elemen pertama kita di '0'. Kita tahu elemen kedua kita di '32' (0 + (32 * 1)), dan elemen ketiga kita di 64 (0 + (32 * 2)).
Fakta bahwa kita dapat menyimpan semua nilai-nilai ini di satu sama lain dalam memori berarti array kita sangat kompak. Ini juga berarti bahwa semua elemen kita perlu tetap bersama untuk hal-hal untuk terus bekerja!
Segera setelah kita menambah atau menghapus elemen, kita perlu mengambil yang lainnya, dan menyalinnya ke tempat baru di memori, untuk memastikan tidak ada celah di antara elemen, dan semuanya memiliki ruang yang cukup. Ini bisa sangat lambat , terutama jika Anda melakukannya setiap kali Anda ingin menambahkan satu elemen.
Daftar Tertaut
Tidak seperti array, Linked Linked tidak perlu semua elemen mereka bersebelahan dalam memori. Mereka terdiri dari node, yang menyimpan info berikut:
Daftar itu sendiri menyimpan referensi ke kepala dan ekor (node pertama dan terakhir) dalam banyak kasus, dan kadang-kadang melacak ukurannya.
Jika Anda ingin menambahkan elemen ke akhir daftar, yang perlu Anda lakukan adalah mendapatkan buntut , dan mengubahnya
Next
untuk referensi yang baru yangNode
mengandung nilai Anda. Menghapus dari ujung juga sama sederhana - cukup dereferensiNext
nilai dari node sebelumnya.Sayangnya, jika Anda memiliki
LinkedList<T>
elemen dengan 1000, dan Anda ingin elemen 500, tidak ada cara mudah untuk melompat langsung ke elemen ke-500 seperti ada dengan array. Anda harus mulai dari kepala , dan terus keNext
node, sampai Anda melakukannya 500 kali.Inilah sebabnya mengapa menambah dan menghapus dari a
LinkedList<T>
cepat (ketika bekerja di ujung), tetapi mengakses bagian tengah lambat.Sunting : Brian menunjukkan dalam komentar bahwa Linked Linked memiliki risiko menyebabkan kesalahan halaman, karena tidak disimpan dalam memori yang berdekatan. Ini bisa sulit untuk diperbandingkan, dan dapat membuat Linked Linked bahkan sedikit lebih lambat daripada yang Anda harapkan hanya dengan kompleksitas waktu mereka.
Terbaik dari Kedua Dunia
List<T>
kompromi untuk keduanyaT[]
danLinkedList<T>
dan muncul dengan solusi yang cukup cepat dan mudah digunakan dalam sebagian besar situasi.Secara internal,
List<T>
adalah array! Itu masih harus melompat melalui lingkaran menyalin elemen-elemennya ketika mengubah ukuran, tetapi itu menarik beberapa trik yang rapi.Sebagai permulaan, menambahkan elemen tunggal biasanya tidak menyebabkan array untuk menyalin.
List<T>
memastikan selalu ada cukup ruang untuk lebih banyak elemen. Ketika habis, alih-alih mengalokasikan array internal baru hanya dengan satu elemen baru, ia akan mengalokasikan array baru dengan beberapa elemen baru (seringkali dua kali lebih banyak dari yang saat ini dipegangnya!).Operasi penyalinan mahal, jadi
List<T>
kurangi sebanyak mungkin, sambil tetap memungkinkan akses acak cepat. Sebagai efek samping, ini mungkin akan menghabiskan sedikit lebih banyak ruang daripada array langsung atau daftar tertaut, tetapi biasanya bernilai tradeoff.TL; DR
Gunakan
List<T>
. Biasanya itu yang Anda inginkan, dan tampaknya benar untuk Anda dalam situasi ini (di mana Anda menelepon .Add ()). Jika Anda tidak yakin dengan apa yang Anda butuhkan,List<T>
adalah tempat yang baik untuk memulai.Array baik untuk kinerja tinggi, "Saya tahu saya perlu elemen X". Atau, mereka berguna untuk cepat, sekali-kali "Saya perlu mengelompokkan hal-hal X ini yang sudah saya definisikan bersama sehingga saya dapat mengulanginya" struktur.
Ada sejumlah kelas koleksi lainnya.
Stack<T>
seperti daftar tertaut yang hanya beroperasi dari atas.Queue<T>
berfungsi sebagai daftar masuk pertama keluar pertama.Dictionary<T, U>
adalah pemetaan asosiatif yang tidak tertata antara kunci dan nilai. Bermainlah dengan mereka dan kenali kekuatan dan kelemahan masing-masing. Mereka dapat membuat atau merusak algoritma Anda.sumber
int
menunjukkan jumlah elemen yang dapat digunakan. Di antara hal-hal lain, dimungkinkan untuk menyalin banyak elemen sekaligus dari satu array ke array lainnya, tetapi menyalin di antara daftar umumnya membutuhkan elemen pemrosesan secara individual. Selanjutnya, elemen array dapat diteruskanref
ke hal-hal sepertiInterlocked.CompareExchange
, sementara item daftar tidak bisa.List<>
kerja di bawah tenda.(index+first)%length
.Sementara jawaban KChaloux bagus, saya ingin menunjukkan pertimbangan lain:
List<T>
jauh lebih kuat daripada Array. MetodeList<T>
sangat berguna dalam banyak keadaan - sebuah Array tidak memiliki metode ini dan Anda mungkin menghabiskan banyak waktu untuk mengimplementasikan solusi.Jadi, dari perspektif pengembangan saya hampir selalu menggunakan
List<T>
karena ketika ada persyaratan tambahan, mereka sering jauh lebih mudah diimplementasikan ketika Anda menggunakan aList<T>
.Ini mengarah ke masalah terakhir: Kode saya (saya tidak tahu tentang Anda) mengandung 90%
List<T>
, jadi Array tidak benar-benar cocok. Ketika saya membagikannya, saya harus memanggil.toList()
metode mereka dan mengubahnya menjadi Daftar - ini menjengkelkan dan sangat lambat sehingga keuntungan kinerja dari menggunakan Array hilang.sumber
Tidak ada yang menyebutkan bagian ini: "Dan di sini saya sudah mendapatkan Pengecualian Kehabisan Memori." Yang sepenuhnya karena
Jelas untuk melihat alasannya. Saya tidak tahu apakah Anda bermaksud menambahkan ke daftar yang berbeda, atau hanya menyimpan
ItemNumberList.Count
sebagai variabel sebelum loop untuk mendapatkan hasil yang Anda inginkan, tetapi ini hanya rusak.Programmers.SE adalah untuk "... tertarik dengan pertanyaan konseptual tentang pengembangan perangkat lunak ...", dan jawaban lain memperlakukannya seperti itu. Coba http://codereview.stackexchange.com , di mana pertanyaan ini cocok. Tetapi meskipun ada yang mengerikan, karena kita hanya dapat mengasumsikan kode ini dimulai
_Click
, yang tidak memiliki panggilan kemultiValue1
tempat Anda mengatakan kesalahan terjadi.sumber