微软必应·英雄会第三届在线编程大赛:几个bing?

    本届大赛由微软必应词典冠名,必应词典(http://cn.bing.com/dict/?form=BDVSP4&mkt=zh-CN&setlang=ZH)是微软推出的新一代英语学习引擎,里面收录了很多我们常见的单词。但现实生活中,我们也经常能看到一些毫无规则的字符串,导致词典无法正常收录,不过,我们是否可以从无规则的字符串中提取出正规的单词呢?

   例如有一个字符串"iinbinbing",截取不同位置的字符‘b’、‘i’、‘n’、‘g’组合成单词"bing"。若从1开始计数的话,则‘b’ ‘i’ ‘n’ ‘g’这4个字母出现的位置分别为(4,5,6,10) (4,5,9,10),(4,8,9,10)和(7,8,9,10),故总共可以组合成4个单词”bing“。

  咱们的问题是:现给定任意字符串,只包含小写‘b’ ‘i’ ‘n’ ‘g’这4种字母,请问一共能组合成多少个单词bing?

  字符串长度不超过10000,由于结果可能比较大,请输出对10^9 + 7取余数之后的结果。

选择方法二,结果失败了!
方法一:递归过多堆栈溢出(字符串长度不能超过几百)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Bing个数
{
    /// <summary>
    /// 一、首先去掉字符串首尾的无关字符,使其成为如下格式:b......g
    /// 二、确定"b"后第一个"i"后"n"的个数计数;再找第二个"i"后"n"的个数计数...直到所有的"i"后"n"都被找完。
    /// 三、确定倒数第二个"g"字符(去掉字符串右端的无关字符),递归步骤二...直到第一个有用的"g"被找完
    /// 四、确定第二个"b"(去掉字符串左端的无关字符),重复步骤二、三...直到最后一个有用的"b"被找完
    /// </summary>
    class Program
    {
        /// <summary>
        /// b......g间所能组成bing所有方案个数
        /// </summary>
        /// <param name="oldstr"> 原先字符串 </param>
        /// <param name="newstr"> 操作字符串,通过"i"找到后面"n"的个数 </param>
        /// <param name="count"> 个数</param>
        /// <returns></returns>
        public static void getCount( string oldstr, string newstr, ref int count)
        {
            //newstr = "hjsdhifdnnsi";
            int indexI = newstr.IndexOf('i' );
            if (indexI > 0)
            {
                StringBuilder m = new StringBuilder();
                StringBuilder n = new StringBuilder();
                //m = new StringBuilder(newstr.Substring(indexI));
                m = new StringBuilder (newstr).Remove(0, indexI);
                //此"i"位置后所有"n"的个数
                count += ( from c in m.ToString() where c == 'n' select c).Count();
                //去掉当前"i"
                //newstr = newstr.Remove(indexI, 1);
                n = new StringBuilder (newstr).Remove(indexI, 1);
                newstr = n.ToString();
                m.Clear();
                n.Clear();
                //递归
                getCount(oldstr, newstr, ref count);
            }
            else
            {
                if (oldstr.IndexOf('i' ) > 0 && oldstr.Length >= 4)
                {
                    //b...g,找到字符串末端第2个"g"字符递归
                    oldstr = oldstr.Remove(oldstr.Length - 1, 1).TrimEnd( new char [] { 'i', 'n', 'b' });
                    newstr = oldstr;
                    getCount(oldstr, newstr, ref count);
                }
            }
        }


        static void Main(string[] args)
        {
            int n = 0, count = 0, totalCount = 0;
            string[] bing = new [] { "b", "i", "n" , "g" };
            StringBuilder bingStringBuilder = new StringBuilder();
            Random r = new Random();
            for (int i = 0; i < 10000; i++)
            {
                n = r.Next(0, 4);
                bingStringBuilder = bingStringBuilder.Append(bing[n]);
            }
            //创建只包含字符‘b’、‘i’、‘n’、‘g’且长度不超过10000的字符串
            string bingStr = bingStringBuilder.ToString();
            //去掉首尾不能组合成bing的字符即b......g
            bingStr = bingStr.TrimStart( new char [] { 'i', 'n', 'g' }).TrimEnd( new char [] { 'i', 'n', 'b' });


            while ((from c in bingStr where c == 'b' select c).Count() != 0)
            {
                //b......g格式下bing个数
                getCount(bingStr, bingStr, ref count);
                totalCount += count;
                //去掉字符"b"
                bingStr = bingStr.Remove(0, 1);
                //b......g,确定下一个"b"字符
                bingStr = bingStr.TrimStart( new char [] { 'i', 'n', 'g' });
                count = 0;
            }
            Console.WriteLine("包含字符‘b’、‘i’、‘n’、‘g’且长度不超过10000的字符串为:" + bingStringBuilder);
            Console.WriteLine();
            Console.WriteLine("组合成单词\"bing\"的个数:" + totalCount);
            Console.WriteLine();
            Console.WriteLine("输出对10^9 + 7取余数之后的结果:" + totalCount % 1000000007 );
            Console.ReadLine();
        }
    }
}
方法二:当字符串长度为10000时运行超时(整个下来会非常耗时,用Stopwatch测了下差不多要8分钟)改为1000了,对10^9 + 7取余数之后的结果(悲催的写成1000000007 % totalCount了)挑战失败!
using System;
using System.Collections;
using System.Collections.Generic;
//using System.Linq;
using System.Text;
/// <summary>
/// 解题思路:
/// 一、创建只包含字符‘b’、‘i’、‘n’、‘g’且长度不超过10000的字符串bingStr,用两个数据集合iList与gList记录下字符"i","g"的所在位置
/// 二、遍历iList集合,记录字符"i"前字符"b"的个数;在遍历中嵌套循环gList集合,记录字符"i"与字符"g"间字符"n"的个数。两者相乘累加即为所求
/// </summary>
public class Test 
{
   public static  int howmany(string s)
    {
        return 0;
    }
    //start 提示:自动阅卷起始唯一标识,请勿删除或增加。 
    public static void Main()
    {
        int n = 0;
        long totalCount = 0;
        string[] bing = new[] { "b", "i", "n", "g" };
        StringBuilder bingStringBuilder = new StringBuilder();
        List<int> iList = new List<int>();
        List<int> gList = new List<int>();
        Random r = new Random();
        for (int i = 0; i < 1000; i++)
        {
            n = r.Next(0, 4);
            bingStringBuilder = bingStringBuilder.Append(bing[n]);
            if (bing[n] == "i")
            {
                iList.Add(i);
            }
            if (bing[n] == "g")
            {
                gList.Add(i);
            }
        }
        //创建只包含字符‘b’、‘i’、‘n’、‘g’且长度不超过10000的字符串
        string bingStr = bingStringBuilder.ToString();
        foreach (int i in iList)
        {
            //当前字符"i"前的字符串子串
            string bingStrLeft = bingStr.Substring(0, i);
            //当前字符"i"前字符"b"的个数
            //int bCount = (from c in bingStrLeft where c == 'b' select c).Count();
            int bCount = bingStrLeft.Replace("i", "").Replace("n", "").Replace("g", "").Length;
            if (bCount > 0)
            {
                foreach (int g in gList)
                {
                    //字符"i"在字符"g"前
                    if (g > i)
                    {
                        //当前字符"i"后字符"g"前(不包含字符"g")的字符串子串
                        string subBingStr = bingStr.Substring(i, g - i);
                        //此字符串间字符"n"的个数
                        //int nCount = (from c in subBingStr where c == 'n' select c).Count();
                        int nCount = subBingStr.Replace("b", "").Replace("i", "").Replace("g", "").Length;
                        //字符"i"字符"g"固定时所能组成"bing"的总个数
                        totalCount += bCount * nCount;
                    }
                }
            }
        }
        Console.WriteLine("包含字符‘b’、‘i’、‘n’、‘g’且长度不超过10000(实际长度为1000)的字符串为:" + bingStr);
        Console.WriteLine();
        Console.WriteLine("组合成单词\"bing\"的个数:" + totalCount);
        Console.WriteLine();
        Console.WriteLine("输出对10^9 + 7取余数之后的结果:" + (totalCount == 0 ? 0 : (totalCount % 1000000007)));
    }
    //end //提示:自动阅卷结束唯一标识,请勿删除或增加。
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 适合毕业设计、课程设计作业。这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。 所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值