Pertanyaan Menghasilkan daftar yang diberikan panjang daftar, item, dan item pengisi


Pertama-tama, maaf untuk judul yang buruk, saya benar-benar tidak tahu harus menyebutnya apa. Ini adalah pertanyaan ke salah satu tugas pekerjaan rumah saya:

"Tulis dan uji definisi fungsi Haskell (polimorfik) center yang dibutuhkan tiga argumen:

  1. sebuah daftar arg1 tipe [a],
  2. sebuah lebar arg2 tipe Int, dan
  3. item isian arg3 tipe a,

dan kembali

daftar panjang arg2 tipe [a],

mengandung daftar arg1 berpusat dalam isi item (yaitu, perbedaan antara jumlah item sebelumnya arg1 dan orang-orang yang mengikuti arg1 paling banyak 1).

Contohnya, center "abcd" 7 '-' bisa menghasilkan "--abcd-" atau "-abcd--" (seperti yang Anda pilih). "

Saya tidak ingin Anda benar-benar mengkodekan fungsi ini bagi saya karena ini adalah pekerjaan rumah, tetapi saya hanya memerlukan beberapa arahan tentang cara menyelesaikan masalah ini dan mungkin daftar fungsi Haskell yang mungkin saya temukan berguna dalam memecahkan masalah ini.


4
2018-03-08 00:39


asal


Jawaban:


Tidak diperlukan rekursi (pada bagian Anda). Hasilnya akan terdiri dari daftar input yang diapit di antara daftar isi kiri dan kanan. Itu ++ operator dapat menggabungkan daftar:

center s w f = lfill ++ s ++ rfill where
  n = ... -- compute the total amount of fill required
  nl = ... -- divide the total fill into left  amount
  nr = ... -- divide the total fill into right amount
  lfill = ... -- replicate f nl times
  rfill = ... -- replicate f nr times

Itu where klausa berisi kode untuk membuat daftar isi kiri dan kanan.

Jumlah total item isi (n) akan menjadi perbedaan antara w dan panjangnya s. Jumlah item isi harus dibagi antara kiri (nl) dan kanan (nr) dengan membagi 2 dan membulatkan ke atas (ceiling) atau ke bawah (floor). Anda dapat menghitung jumlah kiri, dan kemudian menghitung jumlah yang tepat dengan mengurangkan dari jumlah kiri dari jumlah total, atau Anda dapat menghitung kiri sebagai floor dan kanan sebagai ceiling dari divisi. Setelah Anda memiliki jumlah pengisian kiri dan kanan, Anda dapat menggunakan replicate untuk membuat daftar f barang.


3
2018-03-08 16:27



Ketik Panduan

Tuliskan jenis anotasi secara eksplisit

Anda berkata (hanya beberapa kata),

Tulis dan uji definisi pusat fungsi Haskell (polimorfik) yang mengambil tiga argumen:
  arg1 dari tipe [a], arg2 dari tipe Int, arg3 dari tipe a, mengembalikan daftar jenis [a]

Di sini saya rasa hal pertama yang harus Anda lakukan adalah menuliskan jenis tanda tangan dari fungsi Anda.
Menulis secara eksplisit tipe anotasi (tanda tangan) dari fungsi adalah panduan yang sangat besar,

Untuk membantu Anda, ada sebuah contoh,

Jika fungsi saya mengambil dua argumen:
  arg1 dari tipe Int, arg2 atau ketik [a] dan kembalikan tipe a

Saya akan menulis anotasi jenis berikut ini,

fun :: Int -> [a] -> a

Maka fungsi Anda, menjadi,

center :: ... -> ... -> ... ->

Perhatikan, pada terminologi Anda

Ada beberapa ketidaksesuaian antara definisi fungsi Anda dan contoh yang diberikan,

Mempertimbangkan ini,

kembalikan daftar panjang arg2 dari jenis [a]

Daftar jenis [a] terdengar untuk saya, seperti tipe [[a]], tetapi Anda meletakkan contoh ini,

Misalnya, pusat "abcd" 7 '-' dapat menghasilkan "--abcd-" atau "-abcd--" (seperti yang Anda pilih). "

Apakah Anda melihat jenis [[a]]?
Ini merupakan panduan yang baik untuk mencoba memperbaiki ini.


algoritmik, Panduan

Sekarang, mari kita lihat bagian yang jahat, yang algoritmik,

Kami memiliki dua kasus utama untuk dikelola.

Bound case

jika argumen pertama lebih kecil atau sejajar dengan panjang daftar, maka Anda bisa,
melempar pengecualian atau cukup ambil daftar asli tanpa ada perubahan. Pokoknya di kedua sub-kasus kita seharusnya tidak peduli tentang nilai argumen ketiga, bukan?

Sebagai latihan, cobalah menerjemahkan kalimat sebelumnya di Haskell.

Selanjutnya, Apa yang seharusnya terjadi ketika daftar yang dilewati kosong?
Perlu diingat, tidak ada daftar kosong yang dapat diekspresikan sebagai (x: xs), dengan x = head list dan xs = tail list.
Kemudian sebagian besar waktu ketika Anda bertemu fungsi yang berhubungan dengan daftar sebagai masukan, Anda harus mengelola kasus-kasus ini juga.

Mungkin pusat bisa terlihat sedikit seperti ini,

center []     .. .. = ....  
center (x:xs) .. .. = ....  

Kasus umum

Tidak apa-apa, kasus terikat telah dikelola di atas, kita bisa lebih fokus pada fungsi, jika kita mengacu pada contoh Anda dan kita memecahnya dalam hal input.

"--abcd-" <=> ("--" ++ ("abcd" ++ "-"))  

dengan, (++) menjadi operator gabungan,

"left," ++ "middle," ++ "right" => "left,middle,right"  

Sekarang, apakah Anda memperhatikan bahwa mengikuti pembekuan properti?

(length "--") + (length "abcd") + (length "-") = 7   

Inspirasi apa saja?

Tips terakhir, cobalah untuk mengevaluasi instruksi berikut ke ghci,

replicate 2 '-'

Biar saya tahu, jika Anda masih memiliki pertanyaan lain, tetapi bagian aritmatika yang tersisa tampaknya cukup mudah, maksud saya, itu tidak bergantung pada beberapa pengetahuan Haskell.


2
2018-03-08 12:00



Menggunakan lebar dan membaginya dengan setengah untuk menemukan median. Anda akan memiliki kasus khusus berakhir dengan median non-integer. Ini dapat diselesaikan dengan menggunakan fungsi langit-langit dan lantai. Maka Anda bisa melakukan sesuatu dengan median ... seperti indeks isi.


1
2018-03-08 00:41



Anda mungkin butuh

mengulangi, panjangnya, lantai, ++

Kerangka fungsi bisa seperti itu

mereplikasi ... ++ ... ++ mereplikasi ....

... harus diisi dengan sesuatu.


-3
2018-03-08 01:17