背景是给定一个单词,比如说least ,然后再给你一部英语字典,在里面找出拥有相同字母的单词(书中称为变位词),比如有这样一些,setal stale steal .etc...我实在是没有这么一部电子版的字典,所以干脆自己生成了一部字典(当然字典里的单词都是乱七八糟的),然后我把给定的单词也随机产生,定为是5包含五个字母的单词,字典中的所有单词也都是只有5位数,(我后来这么一算的话发现这个字典撑死只有26^5个单词≈25^5=(100/4)^5=100^5/4^5=10,000,000,000 /1024≈10,000,000个单词 )
这个方法最核心的就是要把所有单词都分别排序,就是说,如果有一个单词是thank,那么排序以后是ahknt,看是不是变位词只要看排序后是否相等即可
static void Main(string[] args)
{
int seed = 0;
string s0 = getRandomStr(5,seed);
seed++;
string s0_sort = sortStr(s0);
string t1 = "";
string t2 = "";
string t3 = "";
StopWatch sw1 = new StopWatch();//秒表类,可以删除,用于测试运行时间
StopWatch sw2 = new StopWatch();
int num = 10000000;//生成一部字典中单词的数量
string[] s = new string[num];
sw1.setStart();
for (int i = 0; i < num; i++)
{
s[i] = getRandomStr(5,seed);
seed++;
}
Console.WriteLine();
sw1.setEnd();
sw2.setStart();
for (int i = 0; i < num; i++)
{
t = s[i];
t3 = sortStr(s[i]);
if (s0_sort== t3)
{
t2 += (t + " ");
}
}
sw2.setEnd();
Console.WriteLine("随机选定的单词是:" + s0);
Console.WriteLine("获取的那些变位词为:" + t2);
Console.WriteLine("获取字典所用的时间:" + sw1.getTime());
Console.WriteLine("查找所用的时间(包含排序的时间):" + sw2.getTime());
Console.ReadLine();
}
//随机制造一个单词
static string getRandomStr(int n,int seed)
{
Random r = new Random(seed);
string str = "";
int j;
for(int i = 0; i < n; i++)
{
j = r.Next(97,122);
str += (char)j;
}
return str;
}
//给单词按照从a~z的顺序排队
static string sortStr(string str)
{
int count = str.Length;
string s = "";
int[] letterArray = new int[26];
for (int i=0; i < count; i++)
{
letterArray[(int)str[i]-97]++;
}
int t = 0;
for (int j = 0; j < 26; j++)
{
t=letterArray[j];
while (t > 0)
{
s += (char)(j + 97);
t--;
}
}
return s;
}
以下是结果
有这样一些说明:
1.我的字典做的不好,有重复的单词,这个从获取的变位词中也可以看到
2.之所以选的单词只有5位,不是我不想刺激一点,只是,每增加一位,得到变位词的概率越是小,就像买7位数的彩票肯定比买3位数的彩票容易中奖,而选择5位,既能找到变位词,又使得变位词不是太多直至刷屏。
3.单词的拼写其实是有规律可循的,所以如果是拿一部真正的字典去寻找有的时候可以找到很多变位词,就比如说在中国找一个同名同姓的人如果是名叫”李伟“的话应该很多的。但是有些名字,其实基本上根本不可能会有人取。