c# - 有多少种不同的方法可以从大小为 n 的数组中选择 K 个元素但不重复
问题描述
基本上我想知道如何从 n 数组中选择 k 的方式中删除重复项
这是我的代码,它显示了所有可能的组合,例如 32 、 32 、33 、 22 、 23 、 23 :
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
namespace Techniques
{
public static class Program
{
private static void Main()
{
int[] data = { 3, 2, 2, 3 };
int k = 2;
foreach (string comb in CombinationsOfK(data, k).Select(c => string.Join(" ", c)))
{
Console.WriteLine(comb);
}
}
public static IEnumerable<IEnumerable<T>> CombinationsOfK<T>(T[] data, int k)
{
int size = data.Length;
IEnumerable<IEnumerable<T>> Runner(IEnumerable<T> list, int n)
{
int skip = 1;
foreach (var headList in list.Take(size - k + 1).Select(h => new T[] { h }))
{
if (n == 1 )
yield return headList;
else
{
foreach (var tailList in Runner(list.Skip(skip), n - 1))
{
yield return headList.Concat(tailList);
}
skip++;
}
}
}
return Runner(data, k);
}
}
}
我想知道如何从我得到的组合中删除重复项,例如 23 、 22 、 33 没有两个组合应该是相同的。
解决方案
对于问答解决方案,我的建议:
你有这个代码,打印出组合:
foreach (string comb in CombinationsOfK(data, k).Select(c => string.Join(" ", c)))
{
Console.WriteLine(comb);
}
该子句的最终结果:
CombinationsOfK(data, k).Select(c => string.Join(" ", c))
...将是一个IEnumerable<string>
. 你可以应用Distinct
它,字符串将根据它们作为字符串的值被细化。
所以:
var combStrings = CombinationsOfK(data, k).Select(c => string.Join(" ", c));
foreach (var comb in combStrings.Distinct())
{
Console.WriteLine(comb);
}
但是,免责声明:我是从内存中执行此操作的,并且无法测试这台机器上的代码。
另外:如果这是一个课程作业,并且部分作业是为了防止重复,您的教师可能会认为这是一个无效的解决方案,因为它利用了如何处理字符串的特性,而不是改进您的算法。
ETA:使用缓存(a HashSet<T>
)的答案:
您将不得不对代码进行一些重构,或者在多个位置(在每个位置之前yield
)对缓存进行检查。
基本上,每次你知道你想要什么值时yield
,检查它与缓存。
在某处定义缓存(可能在您定义之后size
):
var cache = HashSet<string>();
您将在缓存中使用字符串,因为涉及它们的比较使用基于值的比较。我错了,早些时候,当我认为这也是正确的int[]
。
然后,在你拥有的任何地方yield return
,用这个包装它:
var cacheValue = <whatever you were going to return>.Select(c => string.Join(" ", c));
if(!cache.Contains(cacheValue))
{
cache.Add(cacheValue);
yield return <whatever you were going to return>;
}
推荐阅读
- python - QUdpSocket 在 PyQt5 中没有 writeDatagram() 函数吗?
- d3.js - d3.js 中的时间格式 (%"Y")
- java - 有没有更好的方法来使用 Java 中的特定本地 IP 地址执行 ICMP Ping
- angular7 - 如何在 Angular 中动态显示 404
- godot - 如何将 queue_free() 与 Area2D 一起使用
- javascript - 如何通过对象数组中的键值合并或连接数据?
- javascript - 让 react-dropzone 接受 *all* 文件
- c# - 如何为所有控件、面板、文本块等设置背景属性?
- r - 在数据框中创建变量的正则表达式循环
- batch-file - 批处理字符串中的空格