C#求一算法

songcaizi2009 2014-06-04 01:46:57
算法:
用C#写一个函数。功能如下:
任意给定一组数,例如{12,60,-8,99,15,35,17,18},
找出任意数相加(不能重复)之后的结果为35(任意设定)的情况,可以有误差,误差自设
例如:12+8+15; 35; 17+18
...全文
483 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
我现在在路上 2014-06-05
  • 打赏
  • 举报
回复
感觉最好不要直接给代码: 1、代码,有种太伸手的感觉 2、有时候就算给代码,有的时候看不懂。。 3、给思路或提示,然后自己编码也能锻炼下
jiaoshiyao 2014-06-05
  • 打赏
  • 举报
回复
引用 1 楼 hzj0208 的回复:
先遍历剔除大于35的,在把剩余的排序,剩下的我就不知到了。
负数呢
lpms26086 2014-06-05
  • 打赏
  • 举报
回复
O(N*log(N))的算法 先排序,再二分答案
tony4geek 2014-06-05
  • 打赏
  • 举报
回复
引用 2 楼 hbu_pig 的回复:
 static void Main(string[] args)
        {
            int[] values = { 12, 60, 8, 99, 15, 35, 17, 18 };
            var testdata = values.Select((n, i) => new { id = i + 1, total = n }).ToArray();
            var total = 35;

            Func<IEnumerable<int[]>, int[], IEnumerable<int[]>> comb = (x, y) =>
                from a in x
                from b in y
                where a.Count() == 0 || a.Last() < b
                select a.Concat(new[] { b }).ToArray();

            var indices = Enumerable.Range(0, testdata.Length).ToArray();
            var list = new int[][] { new int[] { } }.AsEnumerable();
            var result = Enumerable.Range(1, testdata.Length)
                .SelectMany(i => list = comb(list, indices))
                .Where(c => c.Sum(i => testdata[i].total) == total)
                .Select(c => c.Select(i => testdata[i]));

            foreach (var c in result)
                Console.WriteLine("({0})\t {1} = {2}",
                    string.Join(", ", c.Select(d => d.id)),
                    string.Join(" + ", c.Select(d => d.total)),
                    total);
            Console.Read();}
tanta 2014-06-04
  • 打赏
  • 举报
回复
点错了,继续 3、无负数,递归调用求组合,如果组合的和大于35,退出。 4、负数,也是递归调用求组合,组合的和大于35+所有负数和的绝对值,退出
tanta 2014-06-04
  • 打赏
  • 举报
回复
看情况: 如果数据量少,那就用最简单的全排列组合,轮开膀子干就是。 数据量大,就复杂些: 首先,排序是肯定的。 其次,判断有无负数
天堂的鸽子 2014-06-04
  • 打赏
  • 举报
回复
这个题目有意思,给个思路: 1,排序,将35插入到数列中去; 2,如果数列中不存在负数,则剔除数列中大于35的数字;否则寻找负数和大于35的组合 3,在小于35数字寻找符合条件的组合(依次循环)
YangYun 2014-06-04
  • 打赏
  • 举报
回复
最好理解,也最容易想到的方法,就是先全排列,然后计算所有排列的值,将符合要求的输出。
assky124 2014-06-04
  • 打赏
  • 举报
回复
1.排序 2.将所有数字减去最小值,让最小值归零 3.判断Σ(35)在排序中的位置,大于Σ(35)的值明显可以排除掉 4.得到一个新的数组,用二分法什么的,计算可能的组合 随便想想的!
tinydyw 2014-06-04
  • 打赏
  • 举报
回复
当然我这里用的都是最基本的算法 如果有更好的 欢迎提出...
tinydyw 2014-06-04
  • 打赏
  • 举报
回复
好吧 这样发
 public class Program
    {
        static Dictionary<int, List<int>> testResults = new Dictionary<int, List<int>>();
        static List<List<int>> results = new List<List<int>>();
        private static int[] test;
        private static int index;
        private static int sum;
        private static int inaccuracy;

        public static void Main(string[] args)
        {
            test = new int[] { 12, 60, 8, 99, 15, 35, 17, 18 };
            sum = 35;
            inaccuracy = 0;
            Calc(test);

            foreach (var item in results)
            {
                foreach (var num in item)
                {
                    Console.WriteLine(num+",");
                }
                Console.WriteLine(" ");
            }

            Console.ReadLine();
        }

        public static void Calc(int [] paras)
        {
            for (int i = 0; i < paras.Length; i++)
            {
                if (paras[i] >= sum - inaccuracy && paras[i] <= sum + inaccuracy)
                    results.Add(new List<int>() { paras[i] });

                for (int j = i + 1; j < paras.Length; j++)
                {
                    index = j + 1;
                    Calc(null, paras[i], paras[j]);
                    index = 0;
                    testResults.Clear();
                }
            }
        }

        public static void Calc(int? num,int num1,int num2) 
        {
            if (num1 > sum + inaccuracy || num2 > sum + inaccuracy) return;
            if (num == null)
            {
                if (num1 + num2 < sum - inaccuracy)
                {
                    testResults.Add(num1 + num2, new List<int>() { num1, num2 });
                    if (++index < test.Length)
                        Calc(num1 + num2, num1 + num2, test[index]);
                }
                else if (num1 + num2 >= sum - inaccuracy && num1 + num2 <= sum + inaccuracy)
                    results.Add(new List<int> { num1, num2 });
            }
            else
            {
                List<int> current = testResults[num.Value];
                int count = 0;
                foreach (var item in current)
                {
                    count += item;
                }

                if (count + num2 < sum - inaccuracy)
                {
                    testResults[num.Value].Add(num2);
                    if (++index < test.Length)
                        Calc(num.Value, count + num2, test[index]);
                }
                else if (count + num2 >= sum - inaccuracy && count + num2 <= sum + inaccuracy)
                {
                    testResults[num.Value].Add(num2);
                    results.Add(testResults[num.Value]);
                }
            }
        }
    }
tinydyw 2014-06-04
  • 打赏
  • 举报
回复
public class Program { static Dictionary<int, List<int>> testResults = new Dictionary<int, List<int>>(); static List<List<int>> results = new List<List<int>>(); private static int[] test; private static int index; private static int sum; private static int inaccuracy; public static void Main(string[] args) { test = new int[] { 12, 60, 8, 99, 15, 35, 17, 18 }; sum = 35; inaccuracy = 0; Calc(test); foreach (var item in results) { foreach (var num in item) { Console.WriteLine(num+","); } Console.WriteLine(" "); } Console.ReadLine(); } public static void Calc(int [] paras) { for (int i = 0; i < paras.Length; i++) { if (paras[i] >= sum - inaccuracy && paras[i] <= sum + inaccuracy) results.Add(new List<int>() { paras[i] }); for (int j = i + 1; j < paras.Length; j++) { index = j + 1; Calc(null, paras[i], paras[j]); index = 0; testResults.Clear(); } } } public static void Calc(int? num,int num1,int num2) { if (num1 > sum + inaccuracy || num2 > sum + inaccuracy) return; if (num == null) { if (num1 + num2 < sum - inaccuracy) { testResults.Add(num1 + num2, new List<int>() { num1, num2 }); if (++index < test.Length) Calc(num1 + num2, num1 + num2, test[index]); } else if (num1 + num2 >= sum - inaccuracy && num1 + num2 <= sum + inaccuracy) results.Add(new List<int> { num1, num2 }); } else { List<int> current = testResults[num.Value]; int count = 0; foreach (var item in current) { count += item; } if (count + num2 < sum - inaccuracy) { testResults[num.Value].Add(num2); if (++index < test.Length) Calc(num.Value, count + num2, test[index]); } else if (count + num2 >= sum - inaccuracy && count + num2 <= sum + inaccuracy) { testResults[num.Value].Add(num2); results.Add(testResults[num.Value]); } } } }
wg5945 2014-06-04
  • 打赏
  • 举报
回复
以前收藏过一个全排列,借来用用~~

    private static readonly int[] values = { 12, 60, 8, 99, 15, 35, 17, 18 };
    private const int total = 35;
    private static void GetString(Dictionary<string, int> dd)
    {
        Dictionary<string, int> dic = new Dictionary<string, int>();
        foreach (KeyValuePair<string, int> kv in dd)
        {
            for (int i = kv.Value + 1; i < values.Length; i++)
            {
                string calc = kv.Key + "+" + values[i];
                if (Convert.ToInt32(new DataTable().Compute(calc, null)) == total)
                {
                    Console.WriteLine(calc);
                }
                dic.Add(kv.Key + "+" + values[i], i);
            }
        }
        if (dic.Count > 0)
        {
            GetString(dic);
        }
    }

    public static void Main()
    {
        Array.ForEach(Array.FindAll(values, x => x == total), Console.WriteLine);

        Dictionary<string, int> dic = new Dictionary<string, int>();
        for (int i = 0; i < values.Length; i++)
        {
            dic.Add(values[i].ToString(), i);
        }        
        GetString(dic);
        Console.ReadLine();
    }
风吹腚腚凉 2014-06-04
  • 打赏
  • 举报
回复
引用 2 楼 hbu_pig 的回复:
 static void Main(string[] args)
        {
            int[] values = { 12, 60, 8, 99, 15, 35, 17, 18 };
            var testdata = values.Select((n, i) => new { id = i + 1, total = n }).ToArray();
            var total = 35;

            Func<IEnumerable<int[]>, int[], IEnumerable<int[]>> comb = (x, y) =>
                from a in x
                from b in y
                where a.Count() == 0 || a.Last() < b
                select a.Concat(new[] { b }).ToArray();

            var indices = Enumerable.Range(0, testdata.Length).ToArray();
            var list = new int[][] { new int[] { } }.AsEnumerable();
            var result = Enumerable.Range(1, testdata.Length)
                .SelectMany(i => list = comb(list, indices))
                .Where(c => c.Sum(i => testdata[i].total) == total)
                .Select(c => c.Select(i => testdata[i]));

            foreach (var c in result)
                Console.WriteLine("({0})\t {1} = {2}",
                    string.Join(", ", c.Select(d => d.id)),
                    string.Join(" + ", c.Select(d => d.total)),
                    total);
            Console.Read();}
大牛你好
MR00009 2014-06-04
  • 打赏
  • 举报
回复
引用 1 楼 hzj0208 的回复:
先遍历剔除大于35的,在把剩余的排序,剩下的我就不知到了。
去除大于35也是错的,人家还有负数呢。 一个个减,一个个找。
欢乐的小猪 2014-06-04
  • 打赏
  • 举报
回复
 static void Main(string[] args)
        {
            int[] values = { 12, 60, 8, 99, 15, 35, 17, 18 };
            var testdata = values.Select((n, i) => new { id = i + 1, total = n }).ToArray();
            var total = 35;

            Func<IEnumerable<int[]>, int[], IEnumerable<int[]>> comb = (x, y) =>
                from a in x
                from b in y
                where a.Count() == 0 || a.Last() < b
                select a.Concat(new[] { b }).ToArray();

            var indices = Enumerable.Range(0, testdata.Length).ToArray();
            var list = new int[][] { new int[] { } }.AsEnumerable();
            var result = Enumerable.Range(1, testdata.Length)
                .SelectMany(i => list = comb(list, indices))
                .Where(c => c.Sum(i => testdata[i].total) == total)
                .Select(c => c.Select(i => testdata[i]));

            foreach (var c in result)
                Console.WriteLine("({0})\t {1} = {2}",
                    string.Join(", ", c.Select(d => d.id)),
                    string.Join(" + ", c.Select(d => d.total)),
                    total);
            Console.Read();}
汤森路透 2014-06-04
  • 打赏
  • 举报
回复
先遍历剔除大于35的,在把剩余的排序,剩下的我就不知到了。

111,125

社区成员

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

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

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