C# 字符串 数组 不重复 组合!求助...

leeyon4151 2010-11-09 11:43:06

string[] m_Data={"我","是","好","人"};//这里的 数组长度不一定4个,可能 10个 100个

我要返回所有 不重复 组合!如:
{"我","是","好","人"},
{"我","好","是","人"},
{"我","人","是","好"},
{"是","好","人","我"},
{"好","人","我","是"},
{"人","我","是","好"},
...
..
.

帮忙写出一个

private List<string[]> LS(string[] Data)
{
//...这里不知道怎么写!
}

...全文
837 13 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
whrspsoft3723 2010-11-20
  • 打赏
  • 举报
回复
已所不为,勿施于人。
你要发贴,可以注明“禁止贴代码”
wangtaiping 2010-11-20
  • 打赏
  • 举报
回复
为啥这么鼓噪的贴代码
给他说个思路不就行了 说白了就是有重复元素的排列呗 先查查算法 然后自己写 实现都是大同小异 关键在于算法
whrspsoft3723 2010-11-19
  • 打赏
  • 举报
回复

上边代码还是错了,少考虑一种情况。下边是正确的源代码。递归也一样,第二个函数要改。
 #region MyRegion 递推
List<List<string>> DoGetAll(List<string> lst) {
List<List<string>> lstRet = new List<List<string>>();
if (lst == null || lst.Count < 2) {
lstRet.Add(lst);
return lstRet;
}

List<List<string>> temp = new List<List<string>>();
for (int i = 0; i < lst.Count - 1; i++) {
List<string> a = lst.GetRange(0, i + 1);
string b = lst[i + 1];
if (i == 0) temp.Add(a);

temp = DoGetAtom(temp, b);
}

return temp;
}

List<List<string>> DoGetAtom(List<List<string>> lst,string b){
List<List<string>> lstRet = new List<List<string>>();
if (lst == null) return lst;

foreach (List<string> sub in lst) {
for(int i = 0; i < sub.Count + 1;i++){
List<string> temp = new List<string>();
temp.AddRange(sub);
temp.Insert(i,b);
lstRet.Add(temp);
}
}

return lstRet;
}



#endregion



whrspsoft3723 2010-11-13
  • 打赏
  • 举报
回复
非递归算法的实现,会节省一部分资源:
List<List<string>> DoGet(List<string> lst) {
if (lst == null || lst.Count == 0) return null;
List<List<string>> a = new List<List<string>>();

List<List<string>> lstRet = new List<List<string>>();
for (int i = 0; i < lst.Count ; i++) {
//如果是开始时,则给a一个初值
if(i == 0) a.Add(lst.GetRange(0, i + 1));

//退出条件 ,到了最后时break
if (i == lst.Count - 1) break;

a = DoGetUnion(a, lst[i + 1]);
}

return a;
}

List<List<string>> DoGetUnion(List<List<string>> lst,string b) {
if (lst == null) return null;
List<List<string>> result = new List<List<string>>();

foreach (List<string> sub in lst) {
result.Add(new List<string>());
result[result.Count - 1].AddRange(sub);
result[result.Count - 1].Add(b);

result.Add(new List<string>());
result[result.Count - 1].Add(b);
result[result.Count - 1].AddRange(sub);
}

return result;
}

缺点:大于32个元素时,事实上会出错。改进List<List<string>>部分用链表代替。突破list中4G的长限制。


leeyon4151 2010-11-10
  • 打赏
  • 举报
回复
{"我","是","好","人"},
{"我","好","是","人"},
{"我","人","是","好"},
{"是","好","人","我"},
{"好","人","我","是"},
{"人","我","是","好"},
...
..
.
我要的是 这样都
而不是

a
a,b
b,a,c

{"我","是","好","人"} 数组 有多少个,就 有 多少个组合。
whrspsoft3723 2010-11-10
  • 打赏
  • 举报
回复
顶6楼,算法挺好的。
zrrsj 2010-11-10
  • 打赏
  • 举报
回复
已解决了啊。
[Quote=引用 6 楼 lishenghu365 的回复:]
C# code

public class PermutationCombination
{
/// <summary>
/// 交换两个变量
/// </summary>
/// <param name="a">变量1</param>
/// <param name="b">变量2</par……
[/Quote]
  • 打赏
  • 举报
回复

public class PermutationCombination
{
/// <summary>
/// 交换两个变量
/// </summary>
/// <param name="a">变量1</param>
/// <param name="b">变量2</param>
public static void Swap(ref int a, ref int b)
{

int temp = a;
a = b;
b = temp;
}
/// <summary>
/// 递归算法求数组的组合(私有成员)
/// </summary>
/// <param name="list">返回的范型</param>
/// <param name="t">所求数组</param>
/// <param name="n">辅助变量</param>
/// <param name="m">辅助变量</param>
/// <param name="b">辅助数组</param>
/// <param name="M">辅助变量M</param>
private static void GetCombination(ref List<int []> list, int [] t, int n, int m, int[] b, int M)
{
for (int i = n; i >= m; i--)
{
b[m - 1] = i - 1;
if (m > 1)
{
GetCombination(ref list, t, i - 1, m - 1, b, M);
}
else
{
int [] temp = new int [M];
for (int j = 0; j < b.Length; j++)
{
temp[j] = t[b[j]];
}
if (GetSum(temp) == 21)
{
list.Add(temp);
}
}
}
}
private static int GetSum(int[] temp)
{
int result = 0;
foreach (int s in temp)
{
result += s;
}
return result;
}
/// <summary>
/// 递归算法求排列(私有成员)
/// </summary>
/// <param name="list">返回的列表</param>
/// <param name="t">所求数组</param>
/// <param name="startIndex">起始标号</param>
/// <param name="endIndex">结束标号</param>
private static void GetPermutation(ref List<int []> list, int [] t, int startIndex, int endIndex)
{
if (startIndex == endIndex)
{
if (list == null)
{
list = new List<int []>();
}
int [] temp = new int [t.Length];
t.CopyTo(temp, 0);
list.Add(temp);
}
else
{
for (int i = startIndex; i <= endIndex; i++)
{
Swap(ref t[startIndex], ref t[i]);
GetPermutation(ref list, t, startIndex + 1, endIndex);
Swap(ref t[startIndex], ref t[i]);
}
}
}
/// <summary>
/// 求从起始标号到结束标号的排列,其余元素不变
/// </summary>
/// <param name="t">所求数组</param>
/// <param name="startIndex">起始标号</param>
/// <param name="endIndex">结束标号</param>
/// <returns>从起始标号到结束标号排列的范型</returns>
public static List<int []> GetPermutation(int [] t, int startIndex, int endIndex)
{
if (startIndex < 0 || endIndex > t.Length - 1)
{
return null;
}
List<int []> list = new List<int []>();
GetPermutation(ref list, t, startIndex, endIndex);
return list;
}
/// <summary>
/// 返回数组所有元素的全排列
/// </summary>
/// <param name="t">所求数组</param>
/// <returns>全排列的范型</returns>
public static List<int []> GetPermutation(int [] t)
{
return GetPermutation(t, 0, t.Length - 1);
}
/// <summary>
/// 求数组中n个元素的排列
/// </summary>
/// <param name="t">所求数组</param>
/// <param name="n">元素个数</param>
/// <returns>数组中n个元素的排列</returns>
public static List<int []> GetPermutation(int [] t, int n)
{
if (n > t.Length)
{
return null;
}
List<int []> list = new List<int []>();
List<int []> c = GetCombination(t, n);
for (int i = 0; i < c.Count; i++)
{
List<int []> l = new List<int []>();
GetPermutation(ref l, c[i], 0, n - 1);
list.AddRange(l);
}
return list;
}
/// <summary>
/// 求数组中n个元素的组合
/// </summary>
/// <param name="t">所求数组</param>
/// <param name="n">元素个数</param>
/// <returns>数组中n个元素的组合的范型</returns>
public static List<int []> GetCombination(int [] t, int n)
{
if (t.Length < n)
{
return null;
}
int[] temp = new int[n];
List<int []> list = new List<int []>();
GetCombination(ref list, t, t.Length, n, temp, n);
return list;
}
}
whrspsoft3723 2010-11-10
  • 打赏
  • 举报
回复

争论可以暂告一段落了,这是我的代码,递归实现的。
c#实现的
直接copy到窗体中,加个按钮,加个Listbox, 包括输出都写好了。 这个问题挺有意思 。
List<List<string>> GetN(List<string> lst){
List<List<string>> lstRet = new List<List<string>>();
if (lst == null) return null;
if (lst.Count == 0) return null;

if(lst.Count == 1){
lstRet.Add(lst);
return lstRet;
}

string b = lst[lst.Count - 1];
List<string> a = lst.GetRange(0, lst.Count - 1);
if (a.Count == 1) {
return GetUnion(a, b);
}

//如果多于两个,则进行拆分操作
List<List<string>> lstN = GetN(a);
if (lstN == null) return null;

foreach (List<string> subList in lstN) {
List<List<string>> single = GetUnion(subList,b);

if (single != null && single.Count > 0) {
lstRet.AddRange(single);
}
}

return lstRet;
}

List<List<string>> GetUnion(List<string> lst,string b) {
//程序的思路是递归,
//任意两个数,总好排列吧? A,B 只有两种组合,A,B / B,A
//同样,当A= List<string> 时,组合也只有两种, List<String>A,b /b,List<String>A
//

if (lst == null) return null;
List<List<string>> result = new List<List<string>>(100);

//b 在后 , A B 组合
List<string> x = new List<string>();
x.AddRange(lst);
x.Add(b);

result.Add(x);

//-----------b 在前(b,a组合)
List<string> y = new List<string>();
y.Add(b);
y.AddRange(lst);

result.Add(y);

return result;
}

private void button1_Click(object sender, EventArgs e) {
//init ,这是Demo数据,生成了10个数字,你可以调大一点,
//不要太大哟,太大了堆栈会溢出
List<string> lst = new List<string>(100);
for (int i = 0; i < 10; i++) {
lst.Add(i.ToString());
}

//返回值就是所有的组合,每个元素是List<string>,表示一种组合
//
List<List<string>> lstRet = this.GetN(lst);


//这是输出结果的过程,
if (lstRet == null) return;
foreach (List<string> sub in lstRet) {
if (sub == null || sub.Count == 0) continue;

string sAll = "";
foreach (string ss in sub) {
sAll += "," + ss;
}

Debug(sAll);
}

}


//这里输出结果,随便 在窗体上加个 ListBox
void Debug(string s) {
listBox1.Items.Add(s);
}



输入现在是个List<string>,你可以认为他是个数组。
为了便于大家理解,代码写得啰嗦了点。
有兴趣的可以转为非递归算法,
数组不要太大,否则,你的机器吃不消。
colorall 2010-11-10
  • 打赏
  • 举报
回复
看看我这个哈

public List<string> GetFullArray(string str)
{
List<string> list = new List<string>();
if (str.Length < 2)
{
list = new List<string>();
list.Add(str);
return list;
}
for (int i = 0; i < str.Length; i++)
{
List<string> list2 = new List<string>();
list2 = GetFullArray(str.Remove(i, 1));

list = new List<string>();
foreach (string item in list2)
{
for (int j = 0; j < item.Length + 1; j++)
{
list.Add(item.Insert(j, str[i].ToString()));
}
}
}
return list;
}

兔子-顾问 2010-11-09
  • 打赏
  • 举报
回复
http://topic.csdn.net/u/20090217/21/f41ed9f6-f929-451c-a5c9-80d2e408422a.html?6080

111,094

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • AIGC Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

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

试试用AI创作助手写篇文章吧