T公司的一道机试题

题目:

五笔的编码范围是a ~ y的25个字母,从1位到4位的编码,如果我们把五笔的编码按字典序排序,形成一个数组如下:

a, aa, aaa, aaaa, aaab, aaac, … …, b, ba, baa, baaa, baab, baac … …, yyyw, yyyx, yyyy

其中a的Index为0,aa的Index为1,aaa的Index为2,以此类推。

1)编写一个函数,输入是任意一个编码,比如baca,输出这个编码对应的Index;

2)编写一个函数,输入是任意一个Index,比如12345,输出这个Index对应的编码。

思考:

这个是字典序计数,和五笔没毛的关系。

看到后不禁想到二十六进制数,但稍微看一下就知道不是,a和b之间的距离很远,不是1,不过似乎还有某种二十六进制数的影子.

显然编码与index之间是一一映射的关系,那么肯定有个函数表达这个映射,于是思考这个函数表达式。遗憾的是,思考了很久,也没找到公式。

编码的长度分别是1,2,3,4,而且没有遗漏某个编码。长度可以用某种层次关系来表达,在上一次的基础上增加一位得到更长的编码。合适的数据结构是:树。

于是,豁然开朗。构建树如下:

写了下实现,C#的,用孩子兄弟链表表示树。做一次先根遍历得到所有结点的序号。不知道有没有人能给出映射函数??

字典序计数
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace 字典序計數
{
class Node
{
/// <summary>
/// 字符
/// </summary>
public String symbol;
/// <summary>
/// 序號
/// </summary>
public int index;
/// <summary>
/// 孩子節點
/// </summary>
public Node child;
/// <summary>
/// 兄弟節點
/// </summary>
public Node brother;
}

class Tree
{
public static String [] Dict = {"a","b","c","d","e","f","g","h","i","j","k","l",
"m","n","o","p","q","r","s","t","u","v","w","x","y"};
public Node root;
public Tree()
{
root
= new Node();
root.symbol
="";
root.index
= -1;
root.child
= null;
root.brother
= null;
}

public void GenerateTree(Node root,int height)
{
if(height==5)
{
return;
}
Node child
= new Node();
child.symbol
= Dict[0];

root.child
= child;
GenerateTree(root.child, height
+ 1);


Node temp
= child;
for (int i = 1; i < Dict.Length; i++)
{
Node brother
= new Node();
brother.symbol
=Dict[i];
GenerateTree(brother, height
+ 1);
temp.brother
= brother;
temp
= brother;
}
}

public void TraverseTree(Node root, int index, StreamWriter sw,String result)
{
if (root != null)
{
root.index
= index;
sw.WriteLine(result
+ root.symbol + ",index=" + root.index);
//Console.WriteLine(result+root.symbol + ",index="+root.index);
TraverseTree(root.child, root.index+1,sw,result + root.symbol);

if (root.child == null)
{
TraverseTree(root.brother, root.index
+ 1, sw, result);
}
else
{
Node ctemp
= root.child;
Node btemp
= root.brother;
while (ctemp != null)
{
btemp
= ctemp.brother;
while (btemp.brother != null)
{
btemp
= btemp.brother;
}
ctemp
= btemp.child;
}
TraverseTree(root.brother, btemp.index
+ 1, sw, result);
}
}
}

public int GetIndex(String code)
{
Node temp
= root.child,goal=root.child;
int index = -1;
int len = code.Length;
int i = 0;

for (i = 0; i < len; i++)
{
if (temp.symbol.CompareTo(code[i].ToString()) == 0)
{
goal
= temp;
temp
= temp.child;
continue;
//i++;
}
if (temp.symbol.CompareTo(code[i].ToString()) < 0)
{
while (temp.symbol.CompareTo(code[i].ToString()) != 0)
{
temp
= temp.brother;
}
goal
= temp;
temp
= temp.child;
}
}

return goal.index;
}

public String GetCode(int index)
{
Node temp
= root,small=root.child,big=root.child;
String result
= "";

while (temp.index != index)
{
while (temp!=null&&temp.index < index)
{
small
= temp;
temp
= temp.brother;
}

if(temp==null)
{
result
+= small.symbol;
temp
= small.child;
if (temp.index == index)
{
result
+= temp.symbol;
break;
}
continue;
}
if (temp.index != index)
{
result
+= small.symbol;

big
= temp;
if (small.child != null)
{
temp
= small.child;
if(temp.index==index)
{
result
+= temp.symbol;
break;
}
}
else
{
temp
= small;
}
}
else
{
result
+= temp.symbol;
break;
}
}

return result;
}
}
class Program
{

static void Main(string[] args)
{
Tree T
= new Tree();
T.GenerateTree(T.root,
1);

FileStream fs
= new FileStream("result.txt", FileMode.Create);
StreamWriter sw
= new StreamWriter(fs);
int index = -1;
T.TraverseTree(T.root,index, sw,
"");
sw.Flush();
sw.Close();

String goal
= "";
while ((goal = Console.ReadLine())!="$")
{
index
= T.GetIndex(goal);
Console.WriteLine(index);
Console.WriteLine(T.GetCode(index));
}
Console.WriteLine(
25 + 25 * 25 + 25 * 25 * 25 + 25 * 25 * 25 * 25);
}
}
}

  

posted on 2011-09-01 18:21  小交响曲  阅读(3524)  评论(46编辑  收藏  举报

导航