Jenis ini menyadap saya untuk sementara waktu sehingga saya harus datang untuk melihat apakah itu sudah terpecahkan. Ini ideku. Dari awal, bukan aplikasi dari algoritma apa pun yang saya ketahui. Ini akan menjadi algoritma brute force yang agak mahal, tetapi harus cukup efektif. Itu dengan asumsi Anda berurusan dengan set data kecil yang Anda jelaskan (100 baris 4 kolom) dan bekerja pada komputer modern dengan ram yang cukup.
Tinjauan Umum : Kami menggunakan algoritme rekursif pada daftar yang disortir untuk membubarkan rekaman serupa dengan jarak maxiumumnya dalam rekaman serupa. Setelah setiap panggilan, semua catatan dengan orang tua yang sama berada pada jarak maksimum. Panggilan teratas mencakup semua catatan. Jadi itu dibatalkan dari dalam ke luar.
Struktur data :
newIndexes
adalah sebuah array<integer>
. Indeks array adalah indeks baris yang ada. Nilai akan menjadi indeks baru, dimulai dengan -1
data
adalah a array<array<string>>
. Kuncinya adalah indeks, array dalam adalah representasi string dari nilai-nilai dalam satu baris. Tidak perlu menjadi string jika Anda memiliki cara pengelompokan data. Elemen array pertama adalah elemen dengan bobot terbesar.
Urutkan data
berdasarkan urutan berat. Urutkan terlebih dahulu dengan kolom dengan bobot terbesar, di dalamnya dengan kolom dengan bobot terbesar ke-2, dll. Hasilnya adalah kebalikan dari apa yang Anda inginkan. Indeks berurutan.
Berikut ini adalah algorythm (dalam kode psudo).
// siblingCount: On first call is the number of rows in the table,
// on recursive calls it is the number of elements with the same parent
// index: the index of current row in `data` - starts 0
// depth: The element index - starts 0
void unsort(int siblingCount, int index, int depth)
{
int count = 1;
string hash = concatColumns(index, depth + 1);
while ((index + count < data.count) && (hash == concatColumns(index + count, depth + 1)))
{
count++;
}
if (depth < columnCount)
unsort(count, index, depth);
else if (index < data.count)
unsort(count, index + count, 0);
int spacing = siblingCount / count;
for (int i = 0; i < count; i++)
{
var offset = 0;
while ((newIndexes[index + i + offset] > -1) & (index + i + offset + 1 < newIndexes.count))
offset++;
if (newIndexes[index + i + offset] > -1) throw new Exception("Shouldn't happen.");
newIndexes[index + i + offset] = index + spacing * i;
}
}
string concatColumns(int index, int count) // returns count columns concatinated
{
// 1,1 = "1"
// 1,2 = "1, blue"
// 1,3 = "1, blue, apple"
return "1, blue, apple";
}
Kemudian terapkanIndeks baru ke data yang akan dibatalkan.
Pikiran tentang pendekatan: Tidak menguji ini, tetapi penyimpananindeks baru dan penyelesaian konflik mungkin bermasalah karena indeks pertama ditugaskan berdasarkan kolom paling tidak signifikan, jadi jika ada banyak konflik maka kolom signifikan lebih besar dapat mengelompok. Mungkin coba terapkan offset sebagai positif pertama, lalu negatif. Atau mungkin melakukannya semacam penyisipan dalam daftar tertaut, bukan array.