CSharp: Enumeration Algorithms

 

/*
 # encoding: utf-8 
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Enumeration Algorithms
# Author    : geovindu,Geovin Du 涂聚文.
# IDE       : vs2026 c# .net 10
# os        : windows 10
# database  : mysql 9.0 sql server 2019, postgreSQL 17.0  Oracle 21c Neo4j
# Datetime  : 2026/07/05 22:16 
# User      :  geovindu
# Product   : Visual Studio 2026
# Project   : CSharpDesignPattern
# File      : RecommendEnum.cs

 */

using System;
using System.Collections.Generic;
using System.Text;

namespace CSharpAlgorithms.Enumeration
{
    /// <summary>
    /// 珠宝商品实体
    /// </summary>
    public class Jewelry
    {
        public string JID { get; set; }
        public string Category { get; set; }
        public string Material { get; set; }
        public decimal Price { get; set; }
        public int Stock { get; set; }
        public int Sales { get; set; }
        public List<string> SceneTags { get; set; }

        /// <summary>
        /// 计算折后价
        /// </summary>
        /// <param name="discount"></param>
        /// <returns></returns>
        public decimal GetDiscountPrice(decimal discount)
        {
            return Price * discount;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            var scenes = string.Join(",", SceneTags);
            return $"【{JID}】{Category} | {Material} | 原价:{Price:F0}元 | 库存:{Stock}件 | 销量:{Sales} | 适用场景:{scenes}";
        }
    }

    /// <summary>
    /// 带评分的推荐单品
    /// </summary>
    public class RecommendItem
    {
        public int Score { get; set; }
        public Jewelry Goods { get; set; }
    }

    /// <summary>
    /// 两件套装:项链+戒指
    /// </summary>
    public class ComboTwo
    {
        public Jewelry Necklace { get; set; }
        public Jewelry Ring { get; set; }
        public decimal Total { get; set; }
    }

    /// <summary>
    /// 三金套装:项链+手镯+戒指(三层循环枚举)
    /// </summary>
    public class ComboThree
    {
        public Jewelry Necklace { get; set; }
        public Jewelry Bracelet { get; set; }
        public Jewelry Ring { get; set; }
        public decimal Total { get; set; }
    }

    /// <summary>
    /// 五金套装:项链+手镯+戒指+耳饰+吊坠(五层循环枚举)
    /// </summary>
    public class ComboFive
    {
        public Jewelry Necklace { get; set; }
        public Jewelry Bracelet { get; set; }
        public Jewelry Ring { get; set; }
        public Jewelry Earrings { get; set; }
        public Jewelry Pendant { get; set; }
        public decimal Total { get; set; }
    }

    public class JewelryService
    {
        /// <summary>
        /// 单品枚举筛选 + 打分排序
        /// </summary>
        /// <param name="goodsList">全店商品</param>
        /// <param name="maxBudget">最高预算</param>
        /// <param name="discount">折扣系数 0~1 如0.95=95折</param>
        /// <param name="targetMaterial">指定材质,空=不限</param>
        /// <param name="targetCategory">指定品类,空=不限</param>
        /// <param name="targetScene">指定场景,空=不限</param>
        /// <returns>主推款(预算内),升级款(小幅超预算≤120%)</returns>
        public Tuple<List<Jewelry>, List<Jewelry>> EnumerateFilter(
            List<Jewelry> goodsList,
            decimal maxBudget,
            decimal discount,
            string targetMaterial,
            string targetCategory,
            string targetScene)
        {
            List<RecommendItem> candidates = new List<RecommendItem>();

            foreach (var item in goodsList)
            {
                // 无库存直接跳过
                if (item.Stock < 1)
                    continue;

                decimal realPrice = item.GetDiscountPrice(discount);
                // 超过预算120%直接过滤
                if (realPrice > maxBudget * 1.2m)
                    continue;

                // 材质筛选
                if (!string.IsNullOrEmpty(targetMaterial) && item.Material != targetMaterial)
                    continue;
                // 品类筛选
                if (!string.IsNullOrEmpty(targetCategory) && item.Category != targetCategory)
                    continue;

                int score = 0;
                decimal priceRatio = realPrice / maxBudget;

                // 价格打分
                if (priceRatio >= 0.7m && priceRatio <= 0.9m)
                    score += 50;
                else if (priceRatio <= 1.0m)
                    score += 30;
                else
                    score += 10;

                // 场景匹配加分
                if (!string.IsNullOrEmpty(targetScene) && item.SceneTags.Contains(targetScene))
                    score += 30;

                // 销量加分上限20
                int saleScore = item.Sales / 10;
                if (saleScore > 20) saleScore = 20;
                score += saleScore;

                candidates.Add(new RecommendItem { Score = score, Goods = item });
            }

            // 按分数降序排序
            var sorted = candidates.OrderByDescending(x => x.Score).ToList();

            List<Jewelry> mainList = new List<Jewelry>();
            List<Jewelry> upgradeList = new List<Jewelry>();

            foreach (var c in sorted)
            {
                decimal realPrice = c.Goods.GetDiscountPrice(discount);
                if (realPrice <= maxBudget)
                    mainList.Add(c.Goods);
                else
                    upgradeList.Add(c.Goods);
            }

            return Tuple.Create(mainList, upgradeList);
        }
        /// <summary>
        /// 两层循环:项链+戒指两件套枚举
        /// </summary>
        /// <param name="goodsList"></param>
        /// <param name="totalBudget"></param>
        /// <param name="discount"></param>
        /// <returns></returns>
        public List<ComboTwo> EnumerateTwoCombo(List<Jewelry> goodsList, decimal totalBudget, decimal discount)
        {
            List<ComboTwo> result = new List<ComboTwo>();
            var necklaces = goodsList.Where(g => g.Stock > 0 && g.Category == "项链").ToList();
            var rings = goodsList.Where(g => g.Stock > 0 && g.Category == "戒指").ToList();

            foreach (var n in necklaces)
            {
                foreach (var r in rings)
                {
                    decimal sum = n.GetDiscountPrice(discount) + r.GetDiscountPrice(discount);
                    if (sum <= totalBudget)
                    {
                        result.Add(new ComboTwo
                        {
                            Necklace = n,
                            Ring = r,
                            Total = sum
                        });
                    }
                }
            }
            return result;
        }

        /// <summary>
        /// 三层循环:婚嫁三金 项链+手镯+戒指
        /// </summary>
        /// <param name="goodsList"></param>
        /// <param name="totalBudget"></param>
        /// <param name="discount"></param>
        /// <returns></returns>
        public List<ComboThree> EnumerateThreeCombo(List<Jewelry> goodsList, decimal totalBudget, decimal discount)
        {
            List<ComboThree> result = new List<ComboThree>();
            var necklaces = goodsList.Where(g => g.Stock > 0 && g.Category == "项链").ToList();
            var bracelets = goodsList.Where(g => g.Stock > 0 && g.Category == "手镯").ToList();
            var rings = goodsList.Where(g => g.Stock > 0 && g.Category == "戒指").ToList();

            // 三层嵌套枚举全部组合
            foreach (var n in necklaces)
            {
                foreach (var b in bracelets)
                {
                    foreach (var r in rings)
                    {
                        decimal sum = n.GetDiscountPrice(discount) +
                                      b.GetDiscountPrice(discount) +
                                      r.GetDiscountPrice(discount);
                        if (sum <= totalBudget)
                        {
                            result.Add(new ComboThree
                            {
                                Necklace = n,
                                Bracelet = b,
                                Ring = r,
                                Total = sum
                            });
                        }
                    }
                }
            }
            return result;
        }

        /// <summary>
        /// 五层循环:婚嫁五金 项链+手镯+戒指+耳饰+吊坠
        /// </summary>
        /// <param name="goodsList"></param>
        /// <param name="totalBudget"></param>
        /// <param name="discount"></param>
        /// <returns></returns>
        public List<ComboFive> EnumerateFiveCombo(List<Jewelry> goodsList, decimal totalBudget, decimal discount)
        {
            List<ComboFive> result = new List<ComboFive>();
            var necklaces = goodsList.Where(g => g.Stock > 0 && g.Category == "项链").ToList();
            var bracelets = goodsList.Where(g => g.Stock > 0 && g.Category == "手镯").ToList();
            var rings = goodsList.Where(g => g.Stock > 0 && g.Category == "戒指").ToList();
            var earrings = goodsList.Where(g => g.Stock > 0 && g.Category == "耳饰").ToList();
            var pendants = goodsList.Where(g => g.Stock > 0 && g.Category == "吊坠").ToList();

            // 五层嵌套枚举全部五金搭配
            foreach (var n in necklaces)
            {
                foreach (var b in bracelets)
                {
                    foreach (var r in rings)
                    {
                        foreach (var e in earrings)
                        {
                            foreach (var p in pendants)
                            {
                                decimal sum = n.GetDiscountPrice(discount) +
                                              b.GetDiscountPrice(discount) +
                                              r.GetDiscountPrice(discount) +
                                              e.GetDiscountPrice(discount) +
                                              p.GetDiscountPrice(discount);
                                if (sum <= totalBudget)
                                {
                                    result.Add(new ComboFive
                                    {
                                        Necklace = n,
                                        Bracelet = b,
                                        Ring = r,
                                        Earrings = e,
                                        Pendant = p,
                                        Total = sum
                                    });
                                }
                            }
                        }
                    }
                }
            }
            return result;
        }

        /// <summary>
        /// 初始化门店商品数据
        /// </summary>
        public List<Jewelry> InitStoreData()
        {
            return new List<Jewelry>()
            {
                new Jewelry{JID="N001",Category="项链",Material="黄金",Price=5280,Stock=12,Sales=120,SceneTags=new List<string>{"婚嫁","送礼"}},
                new Jewelry{JID="N002",Category="项链",Material="铂金",Price=7600,Stock=3,Sales=60,SceneTags=new List<string>{"求婚","日常"}},
                new Jewelry{JID="N003",Category="项链",Material="钻石",Price=12800,Stock=5,Sales=45,SceneTags=new List<string>{"纪念日"}},
                new Jewelry{JID="N004",Category="项链",Material="K金",Price=3680,Stock=8,Sales=150,SceneTags=new List<string>{"日常"}},
                new Jewelry{JID="R001",Category="戒指",Material="黄金",Price=2150,Stock=15,Sales=200,SceneTags=new List<string>{"日常","婚嫁"}},
                new Jewelry{JID="R002",Category="戒指",Material="钻石",Price=9999,Stock=2,Sales=88,SceneTags=new List<string>{"求婚"}},
                new Jewelry{JID="R003",Category="戒指",Material="银饰",Price=599,Stock=30,Sales=320,SceneTags=new List<string>{"日常"}},
                new Jewelry{JID="B001",Category="手镯",Material="黄金",Price=8600,Stock=4,Sales=80,SceneTags=new List<string>{"婚嫁","送礼"}},
                new Jewelry{JID="B002",Category="手镯",Material="银饰",Price=1280,Stock=22,Sales=260,SceneTags=new List<string>{"日常"}},
                new Jewelry{JID="E001",Category="耳饰",Material="K金",Price=1680,Stock=18,Sales=190,SceneTags=new List<string>{"日常","纪念日"}},
                new Jewelry{JID="E002",Category="耳饰",Material="铂金",Price=4200,Stock=6,Sales=72,SceneTags=new List<string>{"求婚"}},
                new Jewelry{JID="E003",Category="耳饰",Material="钻石",Price=6500,Stock=0,Sales=30,SceneTags=new List<string>{"纪念日"}},
                new Jewelry{JID="P001",Category="吊坠",Material="黄金",Price=2600,Stock=9,Sales=110,SceneTags=new List<string>{"婚嫁","送礼"}},
                new Jewelry{JID="P002",Category="吊坠",Material="K金",Price=1200,Stock=14,Sales=170,SceneTags=new List<string>{"日常"}}
            };
        }
    }

}




/*
 # encoding: utf-8 
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Enumeration Algorithms
# Author    : geovindu,Geovin Du 涂聚文.
# IDE       : vs2026 c# .net 10
# os        : windows 10
# database  : mysql 9.0 sql server 2019, postgreSQL 17.0  Oracle 21c Neo4j
# Datetime  : 2026/07/05 22:16 
# User      :  geovindu
# Product   : Visual Studio 2026
# Project   : CSharpDesignPattern
# File      : EnumerationBll.cs

 */


using CSharpAlgorithms.Enumeration;
using System;
using System.Collections.Generic;
using System.Text;

namespace CSharpAlgorithms.Bll
{

    /// <summary>
    /// 
    /// </summary>
    public class EnumerationBll
    {

        /// <summary>
        /// 
        /// </summary>

        public void Demo()
        {

            JewelryService service = new JewelryService();
            List<Jewelry> allGoods = service.InitStoreData();
            decimal discount = 0.95m; // 全场95折

            Console.WriteLine("===== 珠宝门店全部商品(枚举全集)全场95折 =====");
            foreach (var item in allGoods)
            {
                Console.WriteLine($"{item} 折后价:{item.GetDiscountPrice(discount):F0}元");
            }
            Console.WriteLine(new string('-', 110));

            // 场景1:单品推荐 预算6000,不限材质品类场景
            Console.WriteLine("\n【顾客需求1】单品推荐|预算≤6000元,不限材质品类,全场95折");
            var filterResult = service.EnumerateFilter(allGoods, 6000, discount, "", "", "");
            List<Jewelry> mainList = filterResult.Item1;
            List<Jewelry> upgradeList = filterResult.Item2;
            if (mainList.Count == 0)
                Console.WriteLine("无符合条件单品");
            else
            {
                foreach (var g in mainList)
                {
                    Console.WriteLine($"{g} 折后价:{g.GetDiscountPrice(discount):F0}元");
                }
            }

            // 场景2:两件套 项链+戒指,组合预算10000
            Console.WriteLine("\n===== 两件套装(项链+戒指)总价≤10000(95折) =====");
            var twoCombo = service.EnumerateTwoCombo(allGoods, 10000, discount);
            if (twoCombo.Count == 0)
                Console.WriteLine("无两件套组合");
            else
            {
                foreach (var c in twoCombo)
                {
                    Console.WriteLine($"套装组合:");
                    Console.WriteLine($"  {c.Necklace}");
                    Console.WriteLine($"  {c.Ring}");
                    Console.WriteLine($"  折后合计:{c.Total:F0}元");
                    Console.WriteLine("----------------------------------------");
                }
            }

            // 场景3:三层循环 婚嫁三金(项链+手镯+戒指)预算16000
            Console.WriteLine("\n===== 婚嫁三金套装(三层循环枚举)总价≤16000(95折) =====");
            var threeCombo = service.EnumerateThreeCombo(allGoods, 16000, discount);
            if (threeCombo.Count == 0)
                Console.WriteLine("无三金组合");
            else
            {
                foreach (var c in threeCombo)
                {
                    Console.WriteLine($"三金套装:");
                    Console.WriteLine($"  {c.Necklace}");
                    Console.WriteLine($"  {c.Bracelet}");
                    Console.WriteLine($"  {c.Ring}");
                    Console.WriteLine($"  折后合计:{c.Total:F0}元");
                    Console.WriteLine("----------------------------------------");
                }
            }

            // 场景4:五层循环 婚嫁五金 预算22000
            Console.WriteLine("\n===== 婚嫁五金套装(五层循环枚举)总价≤22000(95折) =====");
            var fiveCombo = service.EnumerateFiveCombo(allGoods, 22000, discount);
            if (fiveCombo.Count == 0)
                Console.WriteLine("无五金组合");
            else
            {
                foreach (var c in fiveCombo)
                {
                    Console.WriteLine($"五金套装:");
                    Console.WriteLine($"  {c.Necklace}");
                    Console.WriteLine($"  {c.Bracelet}");
                    Console.WriteLine($"  {c.Ring}");
                    Console.WriteLine($"  {c.Earrings}");
                    Console.WriteLine($"  {c.Pendant}");
                    Console.WriteLine($"  折后合计:{c.Total:F0}元");
                    Console.WriteLine("----------------------------------------");
                }
            }

            // 小幅超预算升级单品展示
            Console.WriteLine("\n【预算6000升级备选单品(小幅超预算)】");
            foreach (var g in upgradeList)
            {
                Console.WriteLine($"{g} 折后价:{g.GetDiscountPrice(discount):F0}元");
            }

            Console.ReadLine();
        

        }
    }
}

  

介绍了一个珠宝商品推荐系统的C#实现,包含单品推荐和套装组合功能。系统通过枚举算法实现:

  1. Jewelry类定义珠宝商品属性和折扣计算

  2. JewelryService提供核心算法:

    • EnumerateFilter():单品筛选打分排序
    • EnumerateTwoCombo():项链+戒指两件套组合
    • EnumerateThreeCombo():三金套装组合
    • EnumerateFiveCombo():五金套装组合
  3. 业务逻辑层EnumerationBll演示了:

    • 单品推荐(预算6000元)
    • 两件套(预算1万元)
    • 三金套装(预算1.6万元)
    • 五金套装(预算2.2万元)

系统支持价格折扣、库存检查、场景标签匹配等功能,通过多层循环枚举所有可能组合,输出符合预算的推荐方案。

输出:

image

 

posted @ 2026-07-15 22:05  ®Geovin Du Dream Park™  阅读(9)  评论(0)    收藏  举报