Replace heads to match a pattern
replaceHeads[expr_, h_, new_] :=
ReplacePart[expr, Thread[Position[expr, h] -> new]]
replaceHeads[f[f[f[]]], f, {a, b, c}]
(*a[b[c[]]]*)
replaceHeads[f[f[], f[]], f, {a, b, c}]
(*a[b[], c[]]*)
Quick and dirty:
replaceHeadWithSet[expr_, h_, heads_] := Module[{j = 0},
ReplaceAll[expr,
h :> (j = Mod[j + 1, Length[heads], 1]; heads[[j]])]]
Example:
replaceHeadWithSet[f[f[f[], f[]]], f, {a, b, c}]
(* Out[84]= a[b[c[], a[]]] *)
A different interpretation: the heads to replace are not all the same but the structure is fixed.
rep[h_@x___, {n_, r___}] := n @ rep[x, {r}]
rep[x___, {}] := x
Use:
rep[f[g[h[]]], {a, b, c}]
a[b[c[]]]