Обратите внимание, что std::map
в C ++ является отсортированной структурой данных, в то время как ассоциативный массив в D имеет неупорядоченный .std.algorithm.setIntersection
предполагает отсортированный диапазон , поэтому вы не сможете использовать эту функцию, пока не преобразуете ассоциативный массив в отсортированный диапазон, например ( result )
import std.typecons;
import std.array;
import std.algorithm;
import std.stdio;
auto byItemSorted(K,V)(V[K] dict) {
auto app = appender!(Tuple!(K,V)[])();
foreach (k, v; dict)
app.put(tuple(k, v));
auto res = app.data; // if there's byItem() we don't need this appender stuff.
sort(res);
return res;
}
auto dictIntersection(K,V)(V[K] map1, V[K] map2) {
return setIntersection(byItemSorted(map1), byItemSorted(map2));
}
void main () {
auto map1 = ["red":4, "blue":6],
map2 = ["blue":2, "green":1],
map3 = ["blue":6, "purple":8];
writeln("map1 & map2 = ", array(dictIntersection(map1, map2)));
writeln("map1 & map3 = ", array(dictIntersection(map1, map3)));
}
Но этот метод неэффективен - для сортировки диапазона требуется O (N log N).
Более эффективный метод подобен написанию собственной подпрограммы пересечения, которая принимает только O (N) ( результат ):
import std.stdio;
struct DictIntersection(K,V) {
V[K] m1, m2;
this(V[K] map1, V[K] map2) { m1 = map1; m2 = map2; }
int opApply(int delegate(ref K, ref V) dg) {
int res = 0;
foreach (k, v; m1) {
V* p = k in m2;
if (p && v == *p) {
res = dg(k, v);
if (res)
break;
}
}
return res;
}
}
DictIntersection!(K,V) dictIntersection(K,V)(V[K] map1, V[K] map2) {
return typeof(return)(map1, map2);
}
void main () {
auto map1 = ["red":4, "blue":6],
map2 = ["blue":2, "green":1],
map3 = ["blue":6, "purple":8];
write("map1 & map2 = ");
foreach (k, v; dictIntersection(map1, map2)) write(k, "->", v, " ");
write("\nmap1 & map3 = ");
foreach (k, v; dictIntersection(map1, map3)) write(k, "->", v, " ");
}
Однако, поскольку opApply не считается входным диапазоном, все алгоритмы диапазона не будут работать с этим.(Я не знаю, как это можно сделать в диапазоне ввода.)