最近也没遇到什么实际问题,于是常“胡思乱想”,今突冒出这样一下算法,供算法爱好者玩玩,请听题:算法描述:计算出所有4-10位的字母、数字、下划线组合成的字符串。要求如下:
一、字符串长度只允许4-10位,只能是字母、数字、下划线组成。
二、不允许数字开头或下划线结尾,如:2abc、abc_这两个字符串都是非法的。
三、同一字符不允许重复出现5次以上,如:ab111111、abbb12bbb、a_b_c_d_e_f_g_h这三个都是非法的。
四、要求按ascll码从小到大生成,最小的应该是:_000,最大的应该是:zzzzzyyyyy例:生成的部分字符串格式如下:_000,_001,_002,.....,zzzzzyyyyu,zzzzzyyyyv,zzzzzyyyyw,zzzzzyyyyx,zzzzzyyyyy附:个人认为重点难点应该是第四个,还有一个难点是效率问题,应该方法是很多的,但效率高低肯定有区别的。
如此大的数据,算法不好的话,就算能得到结果,显然也没意义的。各位,感兴趣就试试看吧!

解决方案 »

  1.   

    最大的应该是yyyyyzzzzz吧(ascii从小到大)...如果你想按照ascii码输出从小到大的话我感觉一个hash就好了...
      

  2.   

    被你这么一说我有点糊涂了,不知道是不是我记错了,高位的比低位的ascii大吧?01应该小于10吧?同理,yz是不是小于zy呢?(离开学校好久了,基本东西也记不大清楚了,有误还请多指教.)
      

  3.   

    不明白你的意思,是不是说如何判断两个字符串ascii值呢?
    可能我表述得也不好,这样吧,我规定下,位数多的,比位数少的ascii大(如:a1111比aaaa大),相同位数的,先比先第一个(左边算起,如比较cd与ab,先比较c与a的ascii值,谁大谁就大,这里结果是cd大)
    注:这个规定合不合理先不讨论,大家就按这样做就行了.
      

  4.   

    ....
    先写在纸上然后 System.out.print(..................);
      

  5.   

    下划线的ascii码是95,而0的ascii码是48.所以最小的应该是0
      

  6.   

    呵,"高手"与"非高手"之间,只要通过"有难度",才能区分啊.
    出个hello world 的题,人人都会,也就没什么价值的了.
    期待高人出现........
      

  7.   

    呵,这应该不是写不来的理由吧?
    估计你没看我后面的回复,运算量你自己可以控制,要不是非要10位啊.
    估计这个算法又无解了,建议版主推存到首页下吧,不然,只在java版,范围太小了,高人要常不在啊
    ,你看现在都达到50楼了.....
    还有算法也算是通用的,其它语言的也没问题...还是希望更多人参与吧.
      

  8.   

    一、字符串长度只允许4-10位,只能是字母、数字、下划线组成。
    二、不允许数字开头或下划线结尾,如:2abc、abc_这两个字符串都是非法的。
    三、同一字符不允许重复出现5次以上,如:ab111111、abbb12bbb、a_b_c_d_e_f_g_h这三个都是非法的。 可以用一个函数来对他们进行判别。四、要求按ascll码从小到大生成,最小的应该是:_000,最大的应该是:zzzzzyyyyy 就算是按照ASCII码来排序,那么针对所有N个字符串来说,用HEAPSORT的复杂度也是O(N×logN)问题在于两个字符串之间的判断的问题。如果LZ懂Java的话,我有以下例子:
    我们有字符串队列ArrayList<String> [] unSorted;
    我们用的还是Collection.sort(unSorted, new comp());我们需要优化的只有comp这个类最坏的方法当然是把字符串的一个一个char按顺序来对比,假设,字符串数组里面最长的字符串的长度是L
    那么我们的排序算法的时间复杂度就去到O(L×N×logN)
    我这里有个想法,因为从_012345.....abcd....ABCD.....一共有1+10+26+26个字母,也就是说有53个字母需要有一个方式把这些字符串直接映射到一个整数上,用来排序。字符串的长度最长是10位,那么就是说,如果用一个十进制的整数来描述任意一个字符串,那么最大的整数是53^10 < 2 ^16哇,我们可以用一个unsigned int就可以描述。从而我们就可以把字符串K看作是一个53进制的整数,用公式A_n * 53^n + A_n-1 * 53^(n-1)...A_1 * 53 + A_0 * 1 = Z,那么Z就是字符串K的对应的整数。假设我们需要对比字符串K1和K2进行比较,那么他们对应的Z1和Z2相减,如果Z1<Z2,那么K1就排在K2的前面。P.S.计算Z值的应该在进行步骤一至三的时候对字符串进行加工,如果在第四步才进行,那么其复杂度不亚于直接一个个字符比较。一、字符串长度只允许4-10位,只能是字母、数字、下划线组成。
    二、不允许数字开头或下划线结尾,如:2abc、abc_这两个字符串都是非法的。
    三、同一字符不允许重复出现5次以上,如:ab111111、abbb12bbb、a_b_c_d_e_f_g_h这三个都是非法的。 
    这三部可以在一个循环里面进行对字符串进行合法校验,并且计算出他们相应的Z(上面提到的)值。四、要求按ascll码从小到大生成,最小的应该是:_000,最大的应该是:zzzzzyyyyy 
      

  9.   

    1.首先我觉得第1步是相对来说麻烦,你的做到4-10位的数字,字母以及下划线的全排列。
    2.从全排列的组合中,通过正则来去掉部分。
    3.在从2中得到的结果中,在通过正则去掉部分。
    4.将剩余部分通过实现compare,来实现你的排序!
      

  10.   

    我的想法是这样的。
    把0~9 _ a~z 建一个hash map或者一个array,我们简单些用array吧。这样就是一个0~36(包括_)的对应关系了,那么array[0]就输出0 array[36]就输出z。先是n = 4 n <= 10从4位开始,用m = 0; m <= n; 开始(这里n是目前输出的字符串的总长,m是目前所在的位上输出array[0] ~ array[36]的字符)。
     
    这样就从_000 从低开始输出,遇到超过36,m就+1,遇到n那位超过36,n就+1从头再来。例如n+1 =5 就从 _0000 从低开始输出,依此类推。
    很明显,这个算法的效率也不是很好,用了嵌套循环了,时间复杂度是n的2次方了。
      

  11.   

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;namespace ConsoleApplication5
    {
        class Program
        {
            static void Main(string[] args)
            {
                //String Keys = "_0123456789abcdefghijklmnopqrstuvwxyz"; // 会死人的
                String Keys = "_0ab"; // 从小到大            GetIt(Keys, String.Empty);
                Console.Read();
            }        static void GetIt(String S, String TempResult)
            {
                if (TempResult.Length > 3) // 最大3位
                    return;
                for (int i = 0; i < S.Length; i++)
                {
                    String Value = TempResult + S[i];                if (Value.Length >= 1) // 最小1位
                        Console.Write(Value + "\t");
                    if (Value.ToCharArray().Count(delegate(Char C) { return C == S[i]; }) < 2) // 每个字符最大重复2次
                        GetIt(S, Value);
                }
            }
        }
    }
      

  12.   

    修正一下
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;namespace ConsoleApplication5
    {
        class Program
        {
            static void Main(string[] args)
            {
                //String Keys = "_0123456789abcdefghijklmnopqrstuvwxyz"; // 会死人的
                String Keys = "_0ab"; // 从小到大            GetIt(Keys, String.Empty);
                Console.Read();
            }        static void GetIt(String S, String TempResult)
            {
                if (TempResult.Length > 3) // 最大3位
                    return;
                for (int i = 0; i < S.Length; i++)
                {
                    String Value = TempResult + S[i];                if (Value.ToCharArray().Count(delegate(Char C) { return C == S[i]; }) > 2) // 每个字符最大重复2次
                        continue;
                    if (Value.Length >= 1) // 最小1位
                        Console.Write(Value + "\t");
                    GetIt(S, Value);
                }
            }
        }
    }
      

  13.   

    楼主题目有漏洞,字母分大小写
    如果只考虑小写的话
    其实不过是把字母,数字,下划线的Ascii码进行组合,然后按Ascii码去掉不符合条件的
    剩下的把Ascii码直接换成数字比大小排序
    排完了再转换回字符就完了也就是不是字母,数字,下划线按题目来而是,97~122,48~57,95按题目来而已这么简单个问题