如何清空含子数组的arrTransaksi?统计数据未更新求助
问题描述
我有一个名为arrTransaksi的数组,它包含子数组arrPembelian,我想清空这个子数组的所有数据用于统计分析。已经调用hapusTransaksi和hapusBarangTransaksi函数删除了数据,数据确实被移除了,但statistics统计函数里的数据没有同步更新。相关Go语言代码如下:
主代码
package main import "fmt" const NMAX = 1024 type barang struct { nama, kategori string hargaModal, hargaJual float64 stok, penjualan int } type transaksi struct { tanggal string idx int pembelian arrPembelian } type pembelian struct { barang string jumlah int } type arrBarang [NMAX]barang type arrTransaksi [NMAX]transaksi type arrPembelian [NMAX]pembelian func main() { var perintah_main, perintah_barang, perintah_transaksi, n, i, m, tgl, brg int var totalModal, totalPendapatan float64 var targetBarang, A, perintah_hapus_barang, targetTransaksi, targetTanggal string var b arrBarang var t arrTransaksi clearScreen() fmt.Print("PADA TANGGAL BERAPA YANG INGIN DI HAPUS: ") fmt.Scan(&targetTanggal) CTT := cekTransaksiTanggal(t, n, targetTanggal) if CTT >= 0 { clearScreen() for i := 0; i < t[CTT].idx; i++ { fmt.Println(t[CTT].pembelian[i]) } fmt.Scan(&perintah_hapus_barang) if perintah_hapus_barang == "Y" { hapusTransaksi(&t, &tgl, &m, CTT) hapusBarangTransaksi(&t, CTT, &m) } } } func cekTransaksiBarang(t arrTransaksi, CTT int, target string) int { for i := 0; i <= t[CTT].idx; i++ { if target == t[CTT].pembelian[i].barang { return i } } return -1 } func hapusTransaksi(t *arrTransaksi, tgl, m *int, target int) { for i := target; i < *tgl; i++ { t[i] = t[i+1] *tgl-- } } func hapusBarangTransaksi(t *arrTransaksi, CTT int, m *int) { for j := 0; j < *m; j++ { t[CTT].pembelian[j] = t[CTT].pembelian[j+1] *m-- } }
统计函数代码
func statistics(b *arrBarang, t *arrTransaksi, n, m int, totalModal float64, totalPendapatan float64) { fmt.Println("=======================| STATISTIK |========================") fmt.Println("| |") fmt.Println("| DATA MODAL DAN PENDAPATAN |") fmt.Println("| |") fmt.Println("============================================================") for i := 0; i < n; i++ { totalPendapatan += b[i].hargaJual * float64(b[i].penjualan) } fmt.Println("Total Modal: Rp.", totalModal) fmt.Println("Total Pendapatan: Rp.", totalPendapatan) fmt.Println("============================================================") fmt.Println("| |") fmt.Println("| [ 5 BARANG PALING BANYAK TERJUAL ] |") fmt.Println("| |") fmt.Println("============================================================") shortingBarang(b, n) // Display top 5 for i := 0; i < 5 && i < n; i++ { fmt.Println(b[i].nama, "-", b[i].penjualan, "unit") } fmt.Println("============================================================") fmt.Println("| TOKO KEREN |") fmt.Println("============================================================") fmt.Println(" TEKAN [X] UNTUK KEMBALI KE HALAMAN UTAMA ") var A string fmt.Scan(&A) }
问题原因与修复方案
核心问题
- 销量未同步回退:统计函数依赖
barang结构体的penjualan字段计算收入和销量排名,但删除交易时,没有把对应商品的销量减去,导致统计数据还是旧值。 - 删除函数逻辑错误:
hapusTransaksi循环中每次*tgl--会导致遍历提前终止,无法正确移除所有后续交易;hapusBarangTransaksi同样存在循环提前结束的问题,而且如果已经删除整个交易,再调用该函数完全多余。 - 统计函数参数传递错误:
totalModal和totalPendapatan是值传递,函数内的修改不会影响外部;且totalModal在函数内没有计算逻辑,直接输出传入的旧值。
修复步骤
1. 新增销量回退函数
删除交易/商品时,需要将对应商品的销量回退:
// 根据交易记录回退商品销量 func rollbackPenjualan(b *arrBarang, t transaksi, n int) { for i := 0; i < t.idx; i++ { for j := 0; j < n; j++ { if b[j].nama == t.pembelian[i].barang { b[j].penjualan -= t.pembelian[i].jumlah if b[j].penjualan < 0 { b[j].penjualan = 0 } break } } } }
2. 修正hapusTransaksi函数
先回退销量,再正确移除交易记录:
func hapusTransaksi(b *arrBarang, t *arrTransaksi, tgl *int, target int, n int) { // 回退该交易对应的商品销量 rollbackPenjualan(b, t[target], n) // 正确前移数组元素 for i := target; i < *tgl - 1; i++ { t[i] = t[i+1] } // 清空最后一个元素,避免残留数据 t[*tgl - 1] = transaksi{} *tgl-- }
3. 修正hapusBarangTransaksi函数(删除单条商品时用)
如果是删除交易内的单个商品,回退对应销量并修正循环:
func hapusBarangTransaksi(b *arrBarang, t *arrTransaksi, CTT int, idxPembelian int, n int) { // 回退该商品的销量 pembelian := t[CTT].pembelian[idxPembelian] for j := 0; j < n; j++ { if b[j].nama == pembelian.barang { b[j].penjualan -= pembelian.jumlah if b[j].penjualan < 0 { b[j].penjualan = 0 } break } } // 前移商品列表元素 for j := idxPembelian; j < t[CTT].idx - 1; j++ { t[CTT].pembelian[j] = t[CTT].pembelian[j+1] } t[CTT].idx-- }
4. 修正statistics函数
重新计算totalModal,并去掉无效参数:
func statistics(b *arrBarang, n int) { var totalModal, totalPendapatan float64 fmt.Println("=======================| STATISTIK |========================") fmt.Println("| |") fmt.Println("| DATA MODAL DAN PENDAPATAN |") fmt.Println("| |") fmt.Println("============================================================") // 计算总进货成本和总收入 for i := 0; i < n; i++ { totalModal += b[i].hargaModal * float64(b[i].stok) totalPendapatan += b[i].hargaJual * float64(b[i].penjualan) } fmt.Printf("Total Modal: Rp. %.2f\n", totalModal) fmt.Printf("Total Pendapatan: Rp. %.2f\n", totalPendapatan) fmt.Println("============================================================") fmt.Println("| |") fmt.Println("| [ 5 BARANG PALING BANYAK TERJUAL ] |") fmt.Println("| |") fmt.Println("============================================================") shortingBarang(b, n) // 展示销量Top5 for i := 0; i < 5 && i < n; i++ { fmt.Printf("%s - %d unit\n", b[i].nama, b[i].penjualan) } fmt.Println("============================================================") fmt.Println("| TOKO KEREN |") fmt.Println("============================================================") fmt.Println(" TEKAN [X] UNTUK KEMBALI KE HALAMAN UTAMA ") var A string fmt.Scan(&A) }
5. 主函数中调用修正后的删除逻辑
// 主函数内删除交易的代码修改为: if perintah_hapus_barang == "Y" { // 传入商品数组指针,用于回退销量 hapusTransaksi(&b, &t, &tgl, CTT, n) // 无需再调用hapusBarangTransaksi,因为整个交易已被删除 }
内容的提问来源于stack exchange,提问作者Autofat
相关产品推荐
相关产品推荐

