求个算法,M个数,取N个排列,N>M

marmothac 2021-04-30 10:37:21
求个算法,M个数,取N个排列,N>M
比如有数字,1,2,3,取4个进行排列。
结果如下:
1 1 1 1
1 1 1 2
1 1 1 3
1 1 2 2
1 1 2 3
1 1 3 3
1 2 2 2
1 2 2 3
1 2 3 3
1 3 3 3
2 2 2 2
2 2 2 3
2 2 3 3
2 3 3 3
3 3 3 3
不可以重复,顺序可以任意。
...全文
2437 21 打赏 收藏 举报
写回复
21 条回复
切换为时间正序
请发表友善的回复…
发表回复
marmothac 2021-05-05
谢谢大家,不考虑效率确实很多种方法都可以。 这个也确实不是排列组合,有一些特定的条件在里。 我自己也写了一个,和groovy2007的python一个道量,因为取的数据量不是很大,所以倒也无妨。
  • 打赏
  • 举报
回复
yyfhz 2021-05-05
本来以为是一个单纯的N进制枚举问题,加上去重后就不是了。。。
groovy2007的解答或许不是最优,但确实是对的。
引用 17 楼 groovy2007 的回复:
很简单,十几行代码的事。

def next(indexes, m, n):
for i in range(n):
index = indexes[i]
# find the first one that can be increased
if index < m-1:
# fill 0 .. i with the increased value
for j in range(i+1):
indexes[j] = index+1
return True
return False

def indexToNum(index, num):
return [num[i] for i in index]

nums = [1,2,3]
indexes = [0,0,0,0]
print(indexToNum(indexes, nums))
while next(indexes, 3, 4):
print(indexToNum(indexes, nums))

'''Output
[1, 1, 1, 1]
[2, 1, 1, 1]
[3, 1, 1, 1]
[2, 2, 1, 1]
[3, 2, 1, 1]
[3, 3, 1, 1]
[2, 2, 2, 1]
[3, 2, 2, 1]
[3, 3, 2, 1]
[3, 3, 3, 1]
[2, 2, 2, 2]
[3, 2, 2, 2]
[3, 3, 2, 2]
[3, 3, 3, 2]
[3, 3, 3, 3]'''
  • 打赏
  • 举报
回复
qishewl 2021-05-04
那我就也来试试好了,嘿嘿佩服,佩服,一篇绝世好文!
  • 打赏
  • 举报
回复
Harrison_2009 2021-05-02
路过,顺便膜拜一下大神们。每天回帖即可获得10分可用分!
  • 打赏
  • 举报
回复
丁劲犇 2021-05-01
https://blog.csdn.net/goldenhawking/article/details/80037669
  • 打赏
  • 举报
回复
groovy2007 2021-05-01
很简单,十几行代码的事。

def next(indexes, m, n):
for i in range(n):
index = indexes[i]
# find the first one that can be increased
if index < m-1:
# fill 0 .. i with the increased value
for j in range(i+1):
indexes[j] = index+1
return True
return False

def indexToNum(index, num):
return [num[i] for i in index]

nums = [1,2,3]
indexes = [0,0,0,0]
print(indexToNum(indexes, nums))
while next(indexes, 3, 4):
print(indexToNum(indexes, nums))

'''Output
[1, 1, 1, 1]
[2, 1, 1, 1]
[3, 1, 1, 1]
[2, 2, 1, 1]
[3, 2, 1, 1]
[3, 3, 1, 1]
[2, 2, 2, 1]
[3, 2, 2, 1]
[3, 3, 2, 1]
[3, 3, 3, 1]
[2, 2, 2, 2]
[3, 2, 2, 2]
[3, 3, 2, 2]
[3, 3, 3, 2]
[3, 3, 3, 3]'''
  • 打赏
  • 举报
回复
marmothac 2021-04-30
引用 6 楼 wanghui0380 的回复:
哦,的确是个障眼法,我也迷了,不过结论正确,压根不值得考虑 上面被迷,修复一下,还是M进制 谁说10进制数不能表达11位数据了,所以压根不要去考虑撒N》M,这条件就是用来迷惑人的
谢谢回复。
  • 打赏
  • 举报
回复
marmothac 2021-04-30
引用 3 楼 飞天凤凰601 的回复:
两个循环解决的事
引用 4 楼 guanyinsishengzi 的回复:
O(n^m) 递归,n=3,m=4,得到81个数。 不会递归直接写4层循环。
神仙打架,哈哈,到 底几个循环
  • 打赏
  • 举报
回复
wanghui0380 2021-04-30
哦,的确是个障眼法,我也迷了,不过结论正确,压根不值得考虑 上面被迷,修复一下,还是M进制 谁说10进制数不能表达11位数据了,所以压根不要去考虑撒N》M,这条件就是用来迷惑人的
  • 打赏
  • 举报
回复
wanghui0380 2021-04-30
这样把,如果楼主还看不清,我们换个更简单直白的说法 0,1,2,3,4,5,6,7,9 取3位 无非就是 000 001 002 003 ----- 009 010 ------ 999 他全排没有,重复没有 至于啥N>M,其实完全就是个障眼法,根本就不值得考虑 N>M 是把?也就是用N当进制而已,不用M当进制, 你该怎么进位就怎么进位,无非是 最后显示的时候 取个余数(模),也就是 当前位的值%M
  • 打赏
  • 举报
回复
guanyinsishengzi 2021-04-30
O(n^m) 递归,n=3,m=4,得到81个数。 不会递归直接写4层循环。
  • 打赏
  • 举报
回复
飞天凤凰601 2021-04-30
两个循环解决的事
  • 打赏
  • 举报
回复
wanghui0380 2021-04-30
对啊,不想废脑筋。 把你的题目换成,大家一眼就明白的,你自己就可以做 12取3,你觉着呢?? 一个钟表表盘,时分秒3个指针,12小时,转一圈下来,是不是全排列了,是不是不会重复 所以,自己按照钟表那么写就好,秒针转一圈,分针进1位,分针转一圈,时针进一位 说白了就是N进制拉
  • 打赏
  • 举报
回复
marmothac 2021-04-30
这种费脑袋的看来都不愿意想啊
  • 打赏
  • 举报
回复
xuzuning 2021-04-30
P(M,N) 是 从 M 个 元素中取 N个做排列 那么 你能从 4 个数中取出 5 个数吗
  • 打赏
  • 举报
回复
morliz子轩 2021-04-30
demo:

   int[] array = {1, 2, 3, 4};
            int a1, a2, a3, a4;
            int iCount = 0;
            for (int i1 = 0; i1 < array.Length; i1++)
            {
                for (int i2 = 0; i2 < array.Length; i2++)
                {
                    if (i2 == i1)
                    {
                        continue;
                    }
                    for (int i3 = 0; i3 < array.Length; i3++)
                    {
                        if (i3 == i1 || i3 == i2)
                        {
                            continue;
                        }
                        for (int i4 = 0; i4 < array.Length; i4++)
                        {
                            if (i4 == i1 || i4 == i2 || i4 == i3)
                            {
                                continue;
                            }
                            a1 = array[i1];
                            a2 = array[i2];
                            a3 = array[i3];
                            a4 = array[i4];
                            iCount++;
                            Console.WriteLine("{0}-{1}-{2}-{3}", a1, a2, a3, a4);
                        }
                    }
                }
            }
            Console.WriteLine("AllCount == {0}", iCount);
            Console.ReadKey();
        }

  • 打赏
  • 举报
回复
wanghui0380 2021-04-30
引用 12 楼 marmothac 的回复:
首先谢谢啊,真是辛苦了。 但对果不对啊, 要求有一条是,不能重复, 1,1,1,2 和2,1,1,1是重复的。。。 像你说的,只在最后一位加1,不停的向前进位即可。
额,这到底求排列啊,还是求组合???1,1,1,2 和2,1,1,1是重复的。也就是这2个相等,这是组合好吧 我还真懒写了,你把这81个按余弦相似度做个Distinct就是结果了
  • 打赏
  • 举报
回复
marmothac 2021-04-30
首先谢谢啊,真是辛苦了。 但对果不对啊, 要求有一条是,不能重复, 1,1,1,2 和2,1,1,1是重复的。。。 像你说的,只在最后一位加1,不停的向前进位即可。
  • 打赏
  • 举报
回复
wanghui0380 2021-04-30
引用 9 楼 marmothac 的回复:
[quote=引用 6 楼 wanghui0380 的回复:]哦,的确是个障眼法,我也迷了,不过结论正确,压根不值得考虑 上面被迷,修复一下,还是M进制 谁说10进制数不能表达11位数据了,所以压根不要去考虑撒N》M,这条件就是用来迷惑人的
M>N,还是M<N,是有点说法的,实现起来还真不是一样的[/quote] 没你想的那么复杂,你弄明白了,他就是进位随便写,反正要放假了,无心写代码,俺就随手写一个,也不讲究啥效率,性能,最优。你看看,到底所谓的N,M大小对你实现有没有啥区别,反正对于我下面的代码来说,没有任何区别
 test test = new test(3, 4);
            int[] dic = new int[] { 1, 2, 3 };

            do
            {
                Console.WriteLine(string.Join(",", test.GetCcurentIndex().Reverse().Select(p => dic[p])));

            } while (test.Increment());


     public class test
        {
            private readonly int _m;
            private readonly int _n;

            private node nodel;
            public test(int M, int N)
            {
                _m = M;
                _n = N;
                nodel = new node(M);

                node ccurentnode = nodel;
                for (int i = 0; i < _n - 1; i++)
                {
                    node tempnode = new node(M);
                    ccurentnode.parent = tempnode;
                    ccurentnode = tempnode;
                }
            }

            public bool Increment()
            {
                var lst = GetCcurentIndex();
                if (!lst.All(p => p == _m - 1))
                {
                    nodel.Increment();



                    return true;
                }
                else
                {
                    return false;
                }

            }
                public IEnumerable<int> GetCcurentIndex()
                {
                    return Show(nodel);
                }

                private IEnumerable<int> Show(node node)
                {
                    yield return node.Value;
                    if (node.parent != null)
                    {
                        var temp = Show(node.parent);
                        foreach (var item in temp)
                        {
                            yield return item;
                        }
                    }
                    else
                    {
                        yield break;
                    }

                }

           //位node
            public class node
            {
                private readonly int _n;

                public int Value { get; set; } = 0;
                public node parent { get; set; }

                public node(int N)
                {

                    _n = N;
                }

                //模拟+1,判定是否要进位
                public void Increment()
                {
                    Value = Value + 1;
                    if (Value == _n)
                    {

                        parent?.Increment();

                    }

                    Value = Value % _n;
                }
            }


        }
运行结果 1,1,1,1 1,1,1,2 1,1,1,3 1,1,2,1 1,1,2,2 1,1,2,3 1,1,3,1 1,1,3,2 1,1,3,3 1,2,1,1 1,2,1,2 1,2,1,3 1,2,2,1 1,2,2,2 1,2,2,3 1,2,3,1 1,2,3,2 1,2,3,3 1,3,1,1 1,3,1,2 1,3,1,3 1,3,2,1 1,3,2,2 1,3,2,3 1,3,3,1 1,3,3,2 1,3,3,3 2,1,1,1 2,1,1,2 2,1,1,3 2,1,2,1 2,1,2,2 2,1,2,3 2,1,3,1 2,1,3,2 2,1,3,3 2,2,1,1 2,2,1,2 2,2,1,3 2,2,2,1 2,2,2,2 2,2,2,3 2,2,3,1 2,2,3,2 2,2,3,3 2,3,1,1 2,3,1,2 2,3,1,3 2,3,2,1 2,3,2,2 2,3,2,3 2,3,3,1 2,3,3,2 2,3,3,3 3,1,1,1 3,1,1,2 3,1,1,3 3,1,2,1 3,1,2,2 3,1,2,3 3,1,3,1 3,1,3,2 3,1,3,3 3,2,1,1 3,2,1,2 3,2,1,3 3,2,2,1 3,2,2,2 3,2,2,3 3,2,3,1 3,2,3,2 3,2,3,3 3,3,1,1 3,3,1,2 3,3,1,3 3,3,2,1 3,3,2,2 3,3,2,3 3,3,3,1 3,3,3,2 3,3,3,3
  • 打赏
  • 举报
回复
xuzuning 2021-04-30
对于 M个数,取N个排列,N>M N>M 是错误的条件 因为条件没有满足的机会 写作 M个数,取N个排列,M>N 你可以先求组合,在对组合的结果求 排列 求排列和组合 的代码有很多,是程序员的永久话题,因为效率总是第一位的
  • 打赏
  • 举报
回复
加载更多回复(1)
相关推荐
发帖
C#

10.8w+

社区成员

.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
帖子事件
创建了帖子
2021-04-30 10:37
社区公告

让您成为最强悍的C#开发者