A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 追影 中级黑马   /  2013-10-6 18:55  /  3230 人查看  /  17 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 追影 于 2013-10-6 19:55 编辑

最近博客里都在贴校招题,我看到几题挺有意思,先献上一题,大家有空可以做做,我先去做做看
二、算法与程序设计题  1、给定任意一个正整数,求比这个数大且最小的“不重复数”,“不重复数”的含义是相邻两位不相同,例如1101是重复数,而1201是不重复数。(15分)

评分

参与人数 1技术分 +1 收起 理由
haxyek + 1

查看全部评分

17 个回复

倒序浏览
简单做了一下, 如果有BUG,还望告知
Console.WriteLine("请您输入一个数字");
            int number=Convert.ToInt32(Console.ReadLine())+1;
            bool flag=true;
            while (flag)
            {
                string strnumber = number.ToString();
                string[] array = { "00", "11", "22", "33", "44", "55", "66", "77", "88", "99" };
                string[] array1 = strnumber.Split(array,StringSplitOptions.None);  
                if (array1.Length > 1)  //如果此处大于1,则说明被分割了,不然就是没分割
                {
                    number++;
                }
                else
                {
                    flag=false;
                }
            }
            Console.WriteLine(number);
            Console.ReadKey();


评分

参与人数 1技术分 +2 收起 理由
追溯客 + 2 赞一个!

查看全部评分

回复 使用道具 举报
本帖最后由 haxyek 于 2013-10-6 21:56 编辑
黑色海 发表于 2013-10-6 20:41
简单做了一下, 如果有BUG,还望告知
Console.WriteLine("请您输入一个数字");
            int number=Con ...

想法一样。。

还可以用char数组,比较相邻两位是否相等。。
回复 使用道具 举报
黑色海 发表于 2013-10-6 20:41
简单做了一下, 如果有BUG,还望告知
Console.WriteLine("请您输入一个数字");
            int number=Con ...

好方法,最直接清晰的思路,不过有一个问题,如果是高位相同的话,而且给定的整数又很大,一位一位的加,效率有些太低了,可不可以一开始就定位到哪里相同,有几个地方相同,低位加1后,还有没有相同的地方
回复 使用道具 举报
haxyek 发表于 2013-10-6 21:52
想法一样。。

还可以用char数组,比较相邻两位是否相等。。

版主最近,光看也不加分么,人家这么好的代码
回复 使用道具 举报
本帖最后由 张慧 于 2013-10-7 11:17 编辑

  1. import java.util.regex.Matcher;
  2. import java.util.regex.Pattern;


  3. /**
  4. * 思路:不太会解释,拿个例子说吧。好比1223311:
  5. * 第一次查找,找到了22,就让1223311先变成1220000再加上10000,最后变为:1230000
  6. * 第二次查找,找到了00,就让1230000先变成1230000,在加上100,最后变为:1230100;
  7. * 第三次查找,找到00,就让1230100先变成1230100,在加入1,最后变为1230101;
  8. */
  9. public class Test1 {
  10. public static void main(String[] args) throws InterruptedException{

  11. String num = "1989";
  12. Pattern p = Pattern.compile("(\\d)\\1{1,}\\d*");
  13. Matcher m = p.matcher(num);

  14. int len = num.length();
  15. //添加一个标记,判断是否是第一次处理
  16. boolean flag = false;
  17. while(true){
  18. if(m.find()){
  19. //找到匹配的结尾下标
  20. int index = m.end(1);

  21. //得到下标之后的值,其实就是将相同的那一位加一,之后如果有位就变为0,避免一直加1.
  22. Integer value = (int)Math.pow(10, len-index-1);
  23. //获得末尾有多少个0
  24. String subStr0 = num.substring(0, index+1);
  25. //之前的字符串
  26. String subStr1 = value.toString().substring(1);
  27. //将两个串起来
  28. num = subStr0.concat(subStr1);
  29. //加值操作
  30. Integer sum = Integer.parseInt(num) + value;
  31. num = sum.toString();
  32. //重新匹配
  33. m = p.matcher(num);

  34. flag = true;
  35. //测试看每次打印的结果
  36. System.out.println(num);
  37. }else{
  38. if(!flag){
  39. Integer sum = Integer.parseInt(num) + 1;
  40. num = sum.toString();
  41. //重新匹配
  42. m = p.matcher(num);
  43. }else{
  44. break;
  45. }
  46. }
  47. }
  48. //最终结果
  49. System.out.println(num);
  50. }
  51. }
复制代码
想起没判断不匹配的了,又改了改

评分

参与人数 1技术分 +1 收起 理由
haxyek + 1

查看全部评分

回复 使用道具 举报
haxyek 金牌黑马 2013-10-7 03:07:46
7#
未解决,不加分
回复 使用道具 举报
追影 发表于 2013-10-7 00:36
好方法,最直接清晰的思路,不过有一个问题,如果是高位相同的话,而且给定的整数又很大,一位一位的加,效率有 ...


可以试一下用IndexOfAny加循环判断,判断出来坐标加(长度减坐标乘10)
PS:只是想法,还没测验过
回复 使用道具 举报
追影 发表于 2013-10-7 00:36
好方法,最直接清晰的思路,不过有一个问题,如果是高位相同的话,而且给定的整数又很大,一位一位的加,效率有 ...

这个道理最简单的方法应该已经很高效了啊,n位数字,最多只需要比较n-1次就行了。前面那个字符串分割的方法,其实比这个慢很多吧。那个最坏的情况是不是要检测10*(n-1)次
回复 使用道具 举报
追影 发表于 2013-10-7 00:36
好方法,最直接清晰的思路,不过有一个问题,如果是高位相同的话,而且给定的整数又很大,一位一位的加,效率有 ...

刚重新看了一下题,原来是要找到比输入数字大的最小不重复数,那确实可以优化算法的。
回复 使用道具 举报
手头没有VS,说下我的想法。

直接把输入的数字变为char类型数组num处理。
数字的最高位刚好是数组的首位。
先写个循环从num[0]遍历检测两个相邻的字符是否相等,循环参数i(这个i要定义在循环外面)初值为0,条件是i<num.length-1,直到遇到num[i]==num[i+1],break跳出循环。
分两种情况:
①、本身这个数字就是非重复数字,那么也就是循环没有被break,那么此时i==num.length-1
此时将num[num.length-1]自加1,检查此时的num[num.length-1]是否等于num[num.length-2],若不相等,则得到的这个num就是所要的(比如:给12345,得12346)。如果相等,再把num[num.length-1]自加1,得到的num就是所要的(比如:给12343,得12345)。

②、本身这个数字是重复数字。那么上面那个循环被break掉,此时i+1记录的就是低位重复数字的下标。我们把num[i+1]自加1。
接着写一个循环,将后面改成01010.....即可。所以循环参量继续使用j。初值为0。循环条件为j<num.length-i-2。循环内容是:num[i+2+j]=j%2。

回复 使用道具 举报
发现我上面说的有BUG ,比如12989这个数字就处理不对了。。。。。
而对于129890这个数字,更难处理了。
还有很多细节需要考虑啊
回复 使用道具 举报
大虾挂了 发表于 2013-10-8 13:36
发现我上面说的有BUG ,比如12989这个数字就处理不对了。。。。。
而对于129890这个数字,更难处理了。
还 ...

第二行搞错,想说的是129898989各种89结尾的
回复 使用道具 举报
大虾挂了 发表于 2013-10-8 13:42
第二行搞错,想说的是129898989各种89结尾的

每次加过后再检查一遍不就可以了。while()
回复 使用道具 举报
namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            bool flag = false;
            bool found = false;
            string input = Console.ReadLine();
            int num = int.Parse(input);

            while (!found)
            {
                flag = false;
                num = ++num;
                input = num.ToString();
                for (int i = 0; i < input.Length - 1 && !flag; i++)
                {
                    if (input[i] == input[i + 1])
                    {
                        flag = true;
                    }
                }
                if (!flag)
                {
                    found = true;
                }
            }
            Console.WriteLine(num);

            Console.ReadKey();
        }
    }
}

回复 使用道具 举报
改了下就解决了,浪费表情
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;

  5. namespace ConsoleApplication8
  6. {
  7.     class Program
  8.     {
  9.         static void Main(string[] args)
  10.         {
  11.             
  12.             int red; //用户输入的数字
  13.             bool fuHao = true; //表示加
  14.             Console.Write("请输入一串数字:");
  15.             while (!Int32.TryParse(Console.ReadLine(), out red)) //得到整数
  16.             {
  17.                 Console.WriteLine("输入的不是整数!\n输入数字:");
  18.             }
  19.             Fined(red, "最大且最小不重复的数是:", fuHao);
  20.             Fined(red, "\n最小且最大不重复的数是:", fuHao=false);
  21.             Console.ReadKey();
  22.         }
  23.         #region 找到不重复的数
  24.         /// <summary>
  25.         /// 找到不重复的数
  26.         /// </summary>
  27.         /// <param name="red"></param>
  28.         /// <param name="st"></param>
  29.         /// <param name="fuHao"></param>
  30.         static void Fined(int red,string st,bool fuHao)
  31.         {
  32.             bool fined = true; //控制比对循环
  33.             while (fined)
  34.             {
  35.                 if (fuHao)
  36.                 {
  37.                     red = red + 1; //找最大数且最小的不重复娄
  38.                 }
  39.                 else
  40.                 {
  41.                     red -= 1; //找最小数且最大的不重复娄
  42.                 }
  43.                 int i = 1;//控制数字的位数
  44.                 while (true)
  45.                 {
  46.                     if (i > red.ToString().Length)//如果超出了输入的数的位数,表明找到了这个不重复数
  47.                     {
  48.                         Console.Write(st + red.ToString());
  49.                         fined = false;
  50.                         break;
  51.                     }

  52.                     string one = red.ToString().Substring(red.ToString().Length - i, 1); //得到需要找的数
  53.                     i++;
  54.                     if (i > red.ToString().Length) //如果超出了输入的数的位数,表明找到了这个不重复数
  55.                     {
  56.                         Console.Write(st + red.ToString());
  57.                         fined = false;
  58.                         break;
  59.                     }

  60.                     string two = red.ToString().Substring(red.ToString().Length - i, 2); //得到二位数,用来比对
  61.                     if (two.LastIndexOf(one) == 1 && two.IndexOf(one) == 0)// 如果这二个数是重复的
  62.                     {
  63.                         int sum = 1;
  64.                         for (int j = 2; j < i - 1; j++) //重复那个数在整个数中是第几位就循环几次
  65.                         {
  66.                             sum *= 10; //每循环一次位数加一
  67.                         }
  68.                         if (fuHao)
  69.                         {
  70.                             red += sum - 1; //给重复位上的数加一
  71.                         }
  72.                         else
  73.                         {
  74.                             red -= sum; //给重复位上的数减一
  75.                             red++;
  76.                         }
  77.                         break;
  78.                     }
  79.                 }

  80.             }
  81.         }
  82.         #endregion

  83.     }
  84. }
复制代码
回复 使用道具 举报
本帖最后由 大虾挂了 于 2013-10-11 15:48 编辑

我的方法
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 判断是不是重复数
{
    class Program
    {
        //该字段的意义:
        //temp[0]:
        //初始赋值为:输入数字+1(因为后面chuli()函数运作时第一个数字是可取的,而题干要求大于输入数字)
        //中间过程用于存储:从高位开始判断数字出现相邻重复现象时,重复数字(包括重复的2个)左边所有数字组成的数字
        //最终:当给定数字已经完全处理完毕时的数字。
        //temp[1];
        //初值为0,
        //中间过程用于存储:从高位开始判断数字出现相邻重复现象时,重复数字(不包括重复的2个)右边一共有多少位数字        //最终用于表示给定数字处理完后,temp[0]这个数字还差多少位。
        //temp[2]:用于记录chuli()函数是否检测到重复数字,0表示未检测到(处理完成),1表示检测到(处理未完成)
        public static int[] temp=new int[3];

        //用复杂例子说明这个算法的工作原理:
        //用户输入989898。
        //程序先将这个数加一,也就是从989899开始判断。
        //进入do-while循环
        //chuli()函数第一次运行,temp数组变为{989899,0,1}(原始temp[2]为0)
        //由于检测到最后两个9相邻,所以表示处理未完成,temp[0]要自加1,变为989900。
        //循环继续运行,第二次运行chuli()函数,temp数组变为{9899,2,1}
        //temp[0]继续自加1,变为9900
        //循环继续运行,第三次运行chuli()函数,temp数组变为{99,4,1}
        //temp[0]继续自加1,变为100
        //循环继续运行,第四次运行chuli()函数,temp数组变为{100,4,1}
        //temp[0]继续自加1,变为101
        //循环继续运行,第五次运行chuli()函数,无法检测到相邻的数
        //temp数组最终变为{101,4,0},数组前两个数字是关键数字,
        //最终字符串是temp[0]+"0"+"1"+"0"+"1"。
        //后面的"0""1"部分只要建立一个循环,参数i初值为0,次数为temp[1],不断让字符串自加i%2即可
        static void Main(string[] args)
        {
            string num = "";
            Console.WriteLine("请输入一个数,我们将输出比这个数大的最小非重复数");
            temp[0]=Convert.ToInt32(Console.ReadLine ())+1;
            do
            {
                chuli();
                if(temp[2]==0)
                    break;
                else
                    temp[0]++;
            }while(true);

            num = temp[0].ToString();
            for (int i = 0; i < temp[1]; i++)
            {
                num += i % 2;
            }
            Console.WriteLine(num);

            Console.ReadKey();
        }

        //这个方法的作用:
        //对temp[0]这个数字进行处理,从高位检测,当遇到重复数字时,截取包括重复数字在内的左边所有数字
        //对于那些没有被截取到的数字,我们把它们一共的位数加到temp[1]中去
        //temp[2]表示是否检测到重复数字,0表示未检测到重复数字,1表示检测到重复数字
        
        //举例,当temp数字本身为{1234554321,0,0}时,运行chuli()函数,我们会截取123455给temp[0]
        //并且算不出后面还有四位数字,temp[1]自加4,检测到重复数字了,所以temp[2]赋值为1
        //这样temp数组就变为{123455,4,1}
        public static void chuli()
        {            
            int i=0;
            for (i = 0; i < temp[0].ToString().Length - 1; i++)
            {
                if (temp[0].ToString() == temp[0].ToString()[i + 1])
                    break;
            }
            if (i == temp[0].ToString().Length - 1)//此时表示num[0[本身就是一个无重复数字,无需处理
                temp[2] = 0;
            if (i < temp[0].ToString().Length - 1)//此时表示num[0]是个有相邻重复数字的数
            {
                temp[2] = 1;
                //注意下面不要把顺序写反num[0]的位数应该先用于计算num[1],再对num[0]进行截取
                temp[1] += temp[0].ToString().Length - 2 - i;
                temp[0] = Convert.ToInt32(temp[0].ToString().Substring(0, i + 2));
            }
        }
    }
}

评分

参与人数 1技术分 +1 收起 理由
haxyek + 1

查看全部评分

回复 使用道具 举报
思路比较怪,所以注释写的略多。。。。。。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马