假设我有这个arraylist [“ a”,“ b”,“ c”,“ d”] 我想展示 6次 b-2 c-4 d-1
我想按特定顺序在另一个arraylist中显示这些 但除了最后一个
,不应将相同的元素彼此相邻你能帮我写这个算法吗?
输出示例: a b c d a b c a c a c a a
答案 0 :(得分:2)
您可以使用该计数生成一个数组,并使用Map
并进行迭代,直到没有更多元素可用为止。
在map.forEach
中,将密钥推到结果集中,并使用递减的计数进行检查,如果它不为零,则将此新的count
设置为{{1} }。
否则,带有实际密钥的条目将被删除。这也减少了map
,这表示map.size
中的元素数。
map
答案 1 :(得分:2)
在此处https://jsfiddle.net/7vsgxyde/检查性能。比Nina快6倍,比User633183快12倍。现代JavaScript很性感,但请小心使用:-)
function roundRobinRepeat(elems, repeats) {
var l = repeats.reduce((x, y) => x + y);
var w = Array(l), i = j = r = 0;
while (i < l) {
if (repeats[j] > r) w[i++] = elems[j];
j = (j + 1) % elems.length;
if (j === 0) r++;
}
return w;
}
console.log(
roundRobinRepeat(
["a", "b", "c", "d"],
[ 6, 2, 4, 1 ]
).join("")
);
console.log(JSON.stringify(
roundRobinRepeat(
[{id:1}, {id:2}],
[2, 3]
)
));
用语言很难解释,所以我给您留下了执行的痕迹。我希望你不要介意:-|
初始化(l
表示“长度”,w
表示“单词”):
elems = ["a", "b", "c", "d"]
repeats = [6, 2, 4, 1]
l = repeats.reduce((x, y) => x + y) // = 6 + 2 + 4 + 1 = 13
w = Array(l) // = [empty × 13]
i = j = r = 0
迭代(r
表示“回合”,i
和j
是索引):
while (i < l) {
if (repeats[j] > r) w[i++] = elems[j];
j = (j + 1) % elems.length; // 0, 1, 2, 3, 0, ...
if (j === 0) r++; // 0, 0, 0, 0, 1, ...
}
j | repeats[j] | r | take | i | elems[j] | w.join("")
---|------------|---|------|----|----------|-----------------
0 | 6 | 0 | y | 0 | "a" | "a"
1 | 2 | 0 | y | 1 | "b" | "ab"
2 | 4 | 0 | y | 2 | "c" | "abc"
3 | 1 | 0 | y | 3 | "d" | "abcd"
---|------------|---|------|----|----------|-----------------
0 | 6 | 1 | y | 4 | "a" | "abcda"
1 | 2 | 1 | y | 5 | "b" | "abcdab"
2 | 4 | 1 | y | 6 | "c" | "abcdabc"
3 | 1 | 1 | n | 6 | "d" | "abcdabc"
---|------------|---|------|----|----------|-----------------
j | repeats[j] | r | take | i | elems[j] | w.join("")
---|------------|---|------|----|----------|-----------------
0 | 6 | 2 | y | 7 | "a" | "abcdabca"
1 | 2 | 2 | n | 7 | "b" | "abcdabca"
2 | 4 | 2 | y | 8 | "c" | "abcdabcac"
3 | 1 | 2 | n | 8 | "d" | "abcdabcac"
---|------------|---|------|----|----------|-----------------
0 | 6 | 3 | y | 9 | "a" | "abcdabcaca"
1 | 2 | 3 | n | 9 | "b" | "abcdabcaca"
2 | 4 | 3 | y | 10 | "c" | "abcdabcacac"
3 | 1 | 3 | n | 10 | "d" | "abcdabcacac"
---|------------|---|------|----|----------|-----------------
j | repeats[j] | r | take | i | elems[j] | w.join("")
---|------------|---|------|----|----------|-----------------
0 | 6 | 4 | y | 11 | "a" | "abcdabcacaca"
1 | 2 | 4 | n | 11 | "b" | "abcdabcacaca"
2 | 4 | 4 | n | 11 | "c" | "abcdabcacaca"
3 | 1 | 4 | n | 11 | "d" | "abcdabcacaca"
---|------------|---|------|----|----------|-----------------
0 | 6 | 5 | y | 12 | "a" | "abcdabcacacaa"
答案 2 :(得分:0)
这是一种与索引或其他中间值无关的递归方法-
const puzzle =
( [ x, count = 0 ] = []
, ...rest
) =>
count === 0
? rest.length === 0
? ""
: puzzle (...rest)
: x + puzzle (...rest, [ x, count - 1 ])
const result =
puzzle (["a", 6], ["b", 2], ["c", 4], ["d", 1])
console .log (result)
// abcdabcacacaa
还有一些细微的变化,可能使它更容易看到正在发生的事情-
const puzzle =
( x
, count = 0
, ...rest
) =>
count === 0
? rest.length === 0
? ""
: puzzle (...rest)
: x + puzzle (...rest, x, count - 1)
const result =
puzzle ("a", 6, "b", 2, "c", 4, "d", 1)
console .log (result)
// abcdabcacacaa
答案 3 :(得分:0)
与https://stackoverflow.com/a/54835972/1636522相同。有趣的算法,但相当慢,甚至比Nina https://jsfiddle.net/7vsgxyde/还要慢:-\无论如何,至少对于初学者来说,以下版本在我看来更具可读性。
function puzzle (x, count = 0, ...rest) {
if (count !== 0) {
return x + puzzle(...rest, x, count - 1);
} else if (rest.length !== 0) {
return puzzle(...rest);
} else {
return "";
}
}
console.log(puzzle(
"a", 6, "b", 2, "c", 4, "d", 1
));