最近也没遇到什么实际问题,于是常“胡思乱想”,今突冒出这样一下算法,供算法爱好者玩玩,请听题:算法描述:计算出所有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附:个人认为重点难点应该是第四个,还有一个难点是效率问题,应该方法是很多的,但效率高低肯定有区别的。
如此大的数据,算法不好的话,就算能得到结果,显然也没意义的。各位,感兴趣就试试看吧!
一、字符串长度只允许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附:个人认为重点难点应该是第四个,还有一个难点是效率问题,应该方法是很多的,但效率高低肯定有区别的。
如此大的数据,算法不好的话,就算能得到结果,显然也没意义的。各位,感兴趣就试试看吧!
可能我表述得也不好,这样吧,我规定下,位数多的,比位数少的ascii大(如:a1111比aaaa大),相同位数的,先比先第一个(左边算起,如比较cd与ab,先比较c与a的ascii值,谁大谁就大,这里结果是cd大)
注:这个规定合不合理先不讨论,大家就按这样做就行了.
先写在纸上然后 System.out.print(..................);
出个hello world 的题,人人都会,也就没什么价值的了.
期待高人出现........
估计你没看我后面的回复,运算量你自己可以控制,要不是非要10位啊.
估计这个算法又无解了,建议版主推存到首页下吧,不然,只在java版,范围太小了,高人要常不在啊
,你看现在都达到50楼了.....
还有算法也算是通用的,其它语言的也没问题...还是希望更多人参与吧.
二、不允许数字开头或下划线结尾,如: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
2.从全排列的组合中,通过正则来去掉部分。
3.在从2中得到的结果中,在通过正则去掉部分。
4.将剩余部分通过实现compare,来实现你的排序!
把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次方了。
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);
}
}
}
}
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);
}
}
}
}
如果只考虑小写的话
其实不过是把字母,数字,下划线的Ascii码进行组合,然后按Ascii码去掉不符合条件的
剩下的把Ascii码直接换成数字比大小排序
排完了再转换回字符就完了也就是不是字母,数字,下划线按题目来而是,97~122,48~57,95按题目来而已这么简单个问题