Bayangkan dua bilangan bulat positif A dan B. Saya ingin menggabungkan keduanya menjadi satu bilangan bulat C.
Tidak mungkin ada bilangan bulat D dan E lainnya yang digabungkan ke C. Jadi menggabungkannya dengan operator tambahan tidak berfungsi. Umpamanya 30 + 10 = 40 = 40 + 0 = 39 + 1 Tidak juga concatination bekerja. Misalnya "31" + "2" = 312 = "3" + "12"
Operasi kombinasi ini juga harus deterministik (selalu menghasilkan hasil yang sama dengan input yang sama) dan harus selalu menghasilkan bilangan bulat baik di sisi positif atau negatif dari bilangan bulat.
10,001*A + B
?Jawaban:
Anda sedang mencari
NxN -> N
pemetaan bijektif . Ini digunakan untuk misalnya pas . Lihatlah PDF ini untuk pengantar apa yang disebut fungsi pasangan . Wikipedia memperkenalkan fungsi pemasangan khusus, yaitu fungsi pemasangan Cantor :Tiga komentar:
ZxZ -> N
pemetaan bijektif . Fungsi Cantor hanya bekerja pada angka non-negatif. Namun ini bukan masalah, karena mudah untuk mendefinisikan suatu penambanganf : Z -> N
, seperti:sumber
Fungsi pemasangan pasangan benar-benar salah satu yang lebih baik di luar sana mengingat itu sederhana, cepat dan efisien ruang, tetapi ada sesuatu yang lebih baik diterbitkan di Wolfram oleh Matthew Szudzik, di sini . Batasan fungsi pasangan Cantor (relatif) adalah bahwa kisaran hasil yang disandikan tidak selalu tetap dalam batas-batas
2N
integer bit jika inputnya adalahN
integer bit dua . Artinya, jika input saya adalah16
bilangan bulat dua mulai dari0 to 2^16 -1
, maka ada2^16 * (2^16 -1)
kombinasi input yang mungkin, sehingga dengan angka bit Prinsip Pigeonhole yang , kita memerlukan output ukuran setidaknya , yang sama dengan , atau dengan kata lain, peta jelas harus layak idealnya. Ini mungkin tidak terlalu penting praktis dalam dunia pemrograman.2^16 * (2^16 -1)
2^32 - 2^16
32
Fungsi pemasangan penyanyi :
Masukkan fungsi Szudzik :
Sekarang mempertimbangkan fakta bahwa kita biasanya berurusan dengan implementasi yang ditandatangani dari sejumlah ukuran dalam bahasa / kerangka kerja, mari kita pertimbangkan
signed 16
bilangan bulat mulai dari-(2^15) to 2^15 -1
(nanti kita akan melihat bagaimana memperluas bahkan ouput untuk menjangkau rentang yang ditandatangani). Karenaa
danb
harus positif, mereka berkisar dari0 to 2^15 - 1
.Fungsi pemasangan penyanyi :
Sekarang fungsi Szudzik :
Mari memperhitungkan bilangan bulat negatif. Itu di luar pertanyaan awal yang saya tahu, tetapi hanya menguraikan untuk membantu pengunjung masa depan.
Fungsi pemasangan penyanyi :
Fungsi Szudzik :
Sekarang semua ini sementara output selalu positif. Di dunia yang ditandatangani, akan lebih menghemat ruang jika kita bisa mentransfer setengah output ke sumbu negatif . Anda bisa melakukannya seperti ini untuk Szudzik:
Apa yang saya lakukan: Setelah menerapkan bobot
2
pada input dan melalui fungsi, saya kemudian membagi ouput dengan dua dan mengambil beberapa dari mereka ke sumbu negatif dengan mengalikan dengan-1
.Lihat hasilnya, untuk input apa pun dalam kisaran
16
nomor bit yang ditandatangani , outputnya berada dalam batas32
integer bit yang ditandatangani yang keren. Saya tidak yakin bagaimana cara yang sama untuk fungsi pemasangan Cantor tetapi tidak mencoba sebanyak tidak efisien. Selain itu, lebih banyak perhitungan yang terlibat dalam fungsi pemasangan Cantor berarti lebih lambat .Berikut ini adalah implementasi C #.
Karena perhitungan menengah dapat melebihi batas
2N
integer yang ditandatangani, saya telah menggunakan4N
tipe integer (pembagian terakhir dengan2
mengembalikan hasilnya ke2N
).Tautan yang saya berikan pada solusi alternatif menggambarkan grafik fungsi yang memanfaatkan setiap titik di ruang angkasa. Sungguh menakjubkan melihat bahwa Anda dapat secara unik menyandikan sepasang koordinat ke angka tunggal secara terbalik! Dunia angka yang ajaib !!
sumber
(0,0)
melalui(65535,65535)
satu nomor, makaa<<16 + b
pada dasarnya lebih baik dalam segala hal (lebih cepat, lebih sederhana, lebih mudah dimengerti, lebih jelas) . Jika Anda ingin(-32768,-32768)
melakukannya(327687,327687)
, cukup tundukkan 32768 terlebih dahulu.Jika A dan B dapat diekspresikan dengan 2 byte, Anda dapat menggabungkannya dalam 4 byte. Letakkan A di bagian paling signifikan dan B di bagian paling tidak signifikan.
Dalam bahasa C ini memberi (dengan asumsi sizeof (pendek) = 2 dan sizeof (int) = 4):
sumber
combine()
harusreturn (unsigned short)(A<<16) | (unsigned short)(B);
Agar angka negatif dapat dikemas dengan benar.A<<16
akan keluar batas. Seharusnyareturn (unsigned int)(A<<16) | (unsigned short)(B);
Apakah ini mungkin?
Anda menggabungkan dua bilangan bulat. Keduanya memiliki kisaran -2,147.483.648 hingga 2.147.483.647 tetapi Anda hanya akan mengambil yang positif. Itu membuat 2147483647 ^ 2 = 4,61169E + 18 kombinasi. Karena setiap kombinasi harus unik DAN menghasilkan bilangan bulat, Anda akan memerlukan semacam bilangan bulat ajaib yang dapat berisi jumlah angka ini.
Atau apakah logika saya cacat?
sumber
Cara matematika standar untuk bilangan bulat positif adalah dengan menggunakan keunikan faktorisasi prima.
The downside adalah bahwa gambar cenderung menjangkau rentang bilangan bulat yang cukup besar sehingga ketika datang untuk mengekspresikan pemetaan dalam algoritma komputer Anda mungkin memiliki masalah dengan memilih jenis yang sesuai untuk hasilnya.
Anda dapat memodifikasi ini untuk menangani negatif
x
dany
dengan meng-encode sebuah flag dengan kekuatan 5 dan 7 syarat.misalnya
sumber
Biarkan angka
a
menjadi yang pertama,b
yang kedua. Membiarkanp
menjadia+1
bilangan prima -th,q
menjadib+1
bilangan prima -thKemudian, hasilnya adalah
pq
, jikaa<b,
atau2pq
jikaa>b
. Jikaa=b
, biarkan sajap^2
.sumber
Tidak sulit untuk membuat pemetaan:
Mencari tahu bagaimana mendapatkan nilai untuk a sewenang-wenang, b sedikit lebih sulit.
sumber
f(a, b) = s(a+b) + a
dimanas(n) = n*(n+1)/2
s(a+b+1)-s(a+b) = a+b+1 < a
.Saya tidak mengerti apa yang Anda maksud dengan:
Bagaimana saya bisa menulis (lebih besar dari), (kurang dari) karakter di forum ini?
sumber
backtick escapes
.Meskipun jawaban Stephan202 adalah satu-satunya yang benar-benar umum, untuk bilangan bulat dalam rentang terbatas Anda dapat melakukan lebih baik. Misalnya, jika rentang Anda adalah 0..10.000, maka Anda dapat melakukan:
Hasil dapat masuk dalam satu integer untuk rentang hingga akar kuadrat dari kardinalitas tipe integer. Paket ini sedikit lebih efisien daripada metode yang lebih umum Stephan202. Juga lebih mudah untuk memecahkan kode; tidak membutuhkan akar kuadrat, sebagai permulaan :)
sumber
Untuk bilangan bulat positif sebagai argumen dan di mana urutan argumen tidak penting:
Inilah fungsi pemasangan yang tidak teratur :
Untuk x ≠ y, inilah fungsi pairing unordered yang unik :
sumber
Lihat ini: http://en.wikipedia.org/wiki/Pigeonhole_principle . Jika A, B dan C memiliki tipe yang sama, itu tidak dapat dilakukan. Jika A dan B adalah bilangan bulat 16-bit, dan C adalah 32-bit, maka Anda cukup menggunakan shifting.
Sifat utama dari algoritma hashing adalah bahwa mereka tidak dapat memberikan hash yang unik untuk setiap input yang berbeda.
sumber
Berikut ini adalah ekstensi kode @DoctorJ ke bilangan bulat tak terikat berdasarkan metode yang diberikan oleh @nawfal. Itu dapat menyandikan dan mendekode. Ini bekerja dengan array normal dan array numpy.
sumber
Bagaimana dengan sesuatu yang lebih sederhana: Diberikan dua angka, A dan B biarlah rangkumannya: 'A' + ';' + 'B'. Kemudian biarkan output berupa hash (str). Saya tahu bahwa ini bukan jawaban matematis, tetapi skrip python sederhana (yang memiliki fungsi hash bawaan) harus melakukan tugasnya.
sumber
Apa yang Anda sarankan tidak mungkin. Anda akan selalu memiliki tabrakan.
Untuk memetakan dua objek ke set tunggal lainnya, set yang dipetakan harus memiliki ukuran minimum dari jumlah kombinasi yang diharapkan:
Dengan asumsi bilangan bulat 32-bit, Anda memiliki 2147483647 bilangan bulat positif. Memilih dua dari ini di mana pesanan tidak menjadi masalah dan dengan pengulangan menghasilkan kombinasi 2305843008139952128. Ini tidak cocok dengan himpunan bilangan bulat 32-bit.
Namun, Anda dapat menyesuaikan pemetaan ini dalam 61 bit. Menggunakan integer 64-bit mungkin paling mudah. Atur kata tinggi ke integer yang lebih kecil dan kata rendah ke yang lebih besar.
sumber
Katakanlah Anda memiliki integer 32 bit, mengapa tidak hanya memindahkan A ke 16 bit pertama dan B ke yang lain?
Selain ini sebagai ruang seefisien mungkin dan murah untuk dihitung, efek samping yang sangat keren adalah Anda dapat melakukan matematika vektor pada angka yang dikemas.
sumber
mari kita memiliki dua angka B dan C, yang menyandikannya menjadi satu nomor A
A = B + C * N
dimana
B = A% N = B
C = A / N = C
sumber
Diberikan bilangan bulat positif A dan B, misalkan D = jumlah digit yang dimiliki A, dan E = jumlah digit yang dimiliki B Hasilnya dapat berupa gabungan dari D, 0, E, 0, A, dan B.
Contoh: A = 300, B = 12. D = 3, E = 2 hasil = 302030012. Ini mengambil keuntungan dari kenyataan bahwa satu-satunya angka yang dimulai dengan 0, adalah 0,
Pro: Mudah dikodekan, mudah didekodekan, dapat dibaca manusia, angka signifikan dapat dibandingkan terlebih dahulu, potensi untuk dibandingkan tanpa perhitungan, pengecekan kesalahan sederhana.
Cons: Ukuran hasil adalah masalah. Tapi tidak apa-apa, mengapa kita menyimpan bilangan bulat tanpa batas di komputer.
sumber
Jika Anda ingin lebih banyak kontrol seperti mengalokasikan bit X untuk angka pertama dan bit Y untuk angka kedua, Anda bisa menggunakan kode ini:
Saya menggunakan total 32 bit. Idenya di sini adalah bahwa jika Anda ingin misalnya bahwa angka pertama akan hingga 10 bit dan angka kedua akan hingga 12 bit, Anda dapat melakukan ini:
Sekarang Anda dapat menyimpan dalam
num_a
jumlah maksimum2^10 - 1 = 1023
dannum_b
nilai maksimum2^12 - 1 = 4095
.Untuk menetapkan nilai untuk num A dan num B:
Sekarang
bnum
adalah semua bit (total 32 bit. Anda dapat memodifikasi kode untuk menggunakan 64 bit) Untuk mendapatkan num:Untuk mendapatkan angka b:
EDIT:
bnum
dapat disimpan di dalam kelas. Saya tidak melakukannya karena kebutuhan saya sendiri saya membagikan kode dan berharap itu akan membantu.Terima kasih untuk sumber: https://www.geeksforgeeks.org/extract-k-bits-given-position-number/ untuk fungsi untuk mengekstrak bit dan terima kasih juga untuk
mouviciel
menjawab di posting ini. Menggunakan ini untuk sumber saya bisa mencari solusi yang lebih majusumber