posts - 403, comments - 310, trackbacks - 0, articles - 7
  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

1. {a, b, c}上的串S中,任何两个b都不相连,用正则表达式表示为
(a|c|ba|bc)*(b|空)

 
2. Pascal注释的表示

{(~})*}
{ } 中间为任意非}的符号,注意表达的严谨

 

3. C注释的表示就困难很多

例如要表示ba ...(没有ab)... ab这样的字符串,不能简单的写成

ba(~(ab))*ab

因为~非运算符通常只适用于单字符,否则容易产生混淆。

b*(a*~(a|b)b*)*a*

像这样的定义很难读,而且难以证明其正确性,因此在真正的扫描程序中通常用特殊方法解决。

posted @ 2007-07-17 20:46 ZelluX 阅读(413) | 评论 (0)编辑 收藏

今天收获真不小啊
看懂了第一个汇编程序,尽管简单得不能再简单了
然后就是新闻组,尽管以前也去过微软的中文新闻组,但没有太多感兴趣的内容。今天发现了个news.cn99.com,海量的信息(包括反动信息-,-),人气也很高,刚问了个如何查看已经安装的python-doc,10分钟后就有人回复
最后是一个关于bbs的彩色效果,其实qterm登录bbs后本来就只是提供了一个shell,像
<ESC><ESC>[1;31m
之类的ANSI记号不是bbs提供的类似api的东西,而是会保存在bbs的原始数据里,qterm端接收这些符号,然后以指定的效果显示。一个例子就是把这些符号("\033\033[1;31mhello world")显示在gnome-terminal终端的时候就是用红色字体显示的。

posted @ 2007-07-16 23:38 ZelluX 阅读(303) | 评论 (0)编辑 收藏

突然想通了一开始一直超时的原因。
每次我都是把新的suspect并入第一个元素所在的集合中,但是由于使用了优化后的并集操作,有可能是第一个元素所在的集合并入了新的suspect所在的集合,也就是说此后last变量并没有指向第一个元素所在集合的跟结点。于是在Union方法中,parent[root1]可能得到一个正整数,并导致Find方法死循环(根结点的parent为正)

后来把Find方法放到Union方法中,问题解决了。

#include <iostream>

using namespace std;

const int DEFAULT_SIZE = 100;

class UFSets
{
private:
    
int *parent;
    
int size;
public:
    UFSets(
int s = DEFAULT_SIZE);
    
~UFSets() { delete [] parent; }
    
void Union(int root1, int root2);
    
int Find(int x);
    
void Clear(int n);
};

UFSets::UFSets(
int s)
{
    size 
= s;
    parent 
= new int[size + 1];
    
for (int i = 0; i <= size; i++)
        parent[i] 
= -1;
}

int UFSets::Find(int x)
{
    
int result = x;
    
while (parent[result] >= 0)
        result 
= parent[result];
    
return result;
}

void UFSets::Union(int root1, int root2)
{
    
// The old version didn't contain the following 3 setences.
    root1 = Find(root1);
    root2 
= Find(root2);
    
if (root1 == root2) return;

    
int temp = parent[root1] + parent[root2];
    
if (parent[root2] < parent[root1])
    {
        parent[root1] 
= root2;
        parent[root2] 
= temp;
    }
    
else
    {
        parent[root2] 
= root1;
        parent[root1] 
= temp;
    }
}

void UFSets::Clear(int n)
{
    
for (int i = 0; i < n; i++)
        parent[i] 
= -1;
}

int main()
{
    UFSets sets(
30000);
    
int n, m;
    
while (true)
    {
        cin 
>> n >> m;
        
if (n == 0break;
        sets.Clear(n);
        
for (int i = 0; i < m; i++)
        {
            
int t;
            cin 
>> t;
            
int last, x;
            cin 
>> last;
            last 
= sets.Find(last);
            
for (int j = 1; j < t; j++)
            {
                cin 
>> x;
                sets.Union(last, x);
                
// int temp = sets.Find(x);
                
// if (temp != last)
                
//     sets.Union(last, temp);
            }
        }
        
int result = 1;
        
int target = sets.Find(0);
        
for (int i = 1; i < n; i++)
            
if (sets.Find(i) == target)
                result 
++;
        cout 
<< result << endl;
    }
    
return 0;
}


posted @ 2007-07-15 11:12 ZelluX 阅读(473) | 评论 (0)编辑 收藏

     摘要: 转载自http://blog.csdn.net/fisher_jiang/archive/2006/08/25/1116918.aspx并查集 (Union-Find Sets) 并查集: (union-find sets)是一种简单的用途广泛的集合. 并查集是若干个不相交集合,能够实现较快的合并和判断元素所在集合的操作,应用很多。一般采取树形结构来存储并查集,并利用一个rank数组来存储集合的...  阅读全文

posted @ 2007-07-14 14:13 ZelluX 阅读(504) | 评论 (0)编辑 收藏

PKU1330,普通树的LCA问题。把结点A的所有父结点都保存在一个hash数组中,然后从结点B开始向上搜索,直到发现hash数组中存在的元素为止。
#include <stdio.h>
#include 
<stdlib.h>

typedef 
struct TreeNode *pTree;

struct TreeNode
{
    
int value;
    pTree father;
};

main()
{
    
int cases, n, i;
    scanf(
"%d"&cases);
    pTree nodes[
10000];
    
for (i = 0; i < 10000; i++)
    {
        nodes[i] 
= malloc(sizeof(struct TreeNode));
        nodes[i]
->value = i;
    }
    
int flag[10000];
    
while (cases > 0)
    {
        cases 
--;
        scanf(
"%d"&n);
        
for (i = 0; i < n; i++)
        {
            nodes[i]
->father = NULL;
        }
        
int x, y;
        
for (i = 0; i < n - 1; i++)
        {
            scanf(
"%d %d"&x, &y);
            nodes[y 
- 1]->father = nodes[x - 1];
        }
        scanf(
"%d %d"&x, &y);
        
for (i = 0; i < n - 1; i++)
            flag[i] 
= 0;
        pTree p 
= nodes[x - 1];
        
while (p != NULL)
        {
            flag[p
->value] = 1;
            p 
= p->father;
        }
        p 
= nodes[y - 1];
        
while (p != NULL)
        {
            
if (flag[p->value])
            {
                printf(
"%d\n", p->value + 1);
                
break;
            }
            p 
= p->father;
        }
    }
    
return 0;
}


posted @ 2007-07-14 13:24 ZelluX 阅读(474) | 评论 (0)编辑 收藏

LCA (Lowest Common Ancestor)
一篇转载的文章,是对于二叉搜索树的算法
http://blog.csdn.net/AmiRural/archive/2006/06/07/777966.aspx

[题目]:已知二元搜索树(Binary Search Tree)上两个结点的值,请找出它们的公共祖先。你可以假设这两个值肯定存在。这个函数的调用接口如下所示:
      int FindLowestCommonAncestor(node *root, int value1, int value2);

    根据树的存储结构,我们可以立刻得到一个这样的算法:从两个给定的结点出发回溯,两条回溯路线的交点就是我们要找的东西。这个算法的具体实现办法是:从根 结点开始,先用这两个结点的全体祖先分别生成两个链表,再把这两个链表第一次出现不同结点的位置找出来,则它们的前一个结点就是我们要找的东西。
    这个算法倒没有什么不好的地方,但是它没有利用二元搜索树的任何特征,其他类型的树也可以用这个算法来处理。二元搜索树中左结点的值永远小于或者等于当前 结点的值,而右结点的值永远大于或者等于当前结点的值。仔细研究,4和14的最低公共祖先是8,它与4和14的其他公共祖先是有重要区别的:其他的公共祖 先或者同时大于4和4,或者同时小于4和14,只有8介于4和14之间。利用这一研究成果,我们就能得到一个更好的算法。
    从根结点出发,沿着两个给定结点的公共祖先前进。当这两个结点的值同时小于当前结点的值时,沿当前结点的左指针前进;当这两个结点的值同时大于当前结点的 值时,沿当前结点的右指针前进;当第一次遇到当前结点的值介于两个给定的结点值之间的情况时,这个当前结点就是我们要找的最的最低公共祖先了。
    这是一道与树有关的试题,算法也有递归的味道,用递归来实现这一解决方案似乎是顺理成章的事,可这里没有这个必要。递归技术特别适合于对树的多个层次进行 遍历或者需要寻找某个特殊结点的场合。这道题只是沿着树结点逐层向下前进,用循环语句来实现有关的过程将更简单明了。

     int FindLowestCommonAncestor(node *root, int value1, int value2)
     {
      node 
*curnode = root;
      
while(1)
         {
           
if (curnode->data>value1&&curnode->data>value2)
             curnode 
= curnode->left;
           
else if(curnode->data<value1&&curnode->data<value2)
             curnode 
= curnode->right;
           
else
             
return curnode->data;
          }
      }

C语言实现:

/*二叉排序树的生成及树,任意两结点的最低公共祖先        Amirural设计*/
#include 
<stdio.h>
#define  null  0

int counter=0;
typedef 
struct btreenode
{
int data;
 
struct btreenode *lchild;
 
struct btreenode *rchild;
}bnode;

bnode 
*creat(int x,bnode *lbt,bnode *rbt)   //生成一棵以x为结点,以lbt和rbt为左右子树的二叉树
{bnode *p;
 p
=(bnode*)malloc(sizeof(bnode));
 p
->data=x;
 p
->lchild=lbt;
 p
->rchild=rbt;
 
return(p);
}

bnode 
*ins_lchild(bnode *p, int x)    //x作为左孩子插到二叉树中
{bnode *q;
if(p==null)
  printf(
"Illegal insert.");
else
 {q
=(bnode*)malloc(sizeof(bnode));
  q
->data=x;
  q
->lchild=null;
  q
->rchild=null;
  
if(p->lchild!=null)                //若p有左孩子,则将原来的左孩子作为结点x的右孩子
     q->rchild=p->lchild;
  p
->lchild=q;
 }
 
return(p);
}

bnode 
*ins_rchild(bnode *p, int x)   //x作为右孩子插入到二叉树
{bnode *q;
 
if(p==null)
    printf(
"Illegal insert.");
 
else
 {q
=(bnode*)malloc(sizeof(bnode));
  q
->data=x;
  q
->lchild=null;
  q
->rchild=null;
  
if(p->rchild!=null)                //若x有右孩子,则将原来的右孩子作为结点x的的左孩子
     q->lchild=p->rchild;
  p
->rchild=q;
 }
  
return(p);
}

void prorder(bnode *p)
{
if(p==null)
   
return;
 printf(
"%d\t%u\t%d\t%u\t%u\n",++counter,p,p->data,p->lchild,p->rchild);
 
if(p->lchild!=null)
   prorder(p
->lchild);
 
if(p->rchild!=null)
   prorder(p
->rchild);
}

void print(bnode *p)                //嵌套括号表示二叉树,输出左子树前打印左括号,
{                                   //输出右子树后打印右括号。
  if(p!=null)
  {printf(
"%d",p->data);
   
if(p->lchild!=null||p->rchild!=null)
   {printf(
"(");
  print(p
->lchild);
  
if(p->rchild!=null)
   printf(
",");
  print(p
->rchild);
  printf(
")");
 }
}
}

int FindLowestCommonAncestor(bnode *root, int value1, int value2)
{
  bnode 
*curnode = root;
  
while(1)
  {
   
if (curnode->data>value1&&curnode->data>value2)
       curnode 
= curnode->lchild;
   
else if(curnode->data<value1&&curnode->data<value2)
       curnode 
= curnode->rchild;
   
else
       
return curnode->data;
   }
}

 
main()
{
 bnode 
*bt,*p,*q;
 
int x,y,v1,v2;
 printf(
"输入根结点:");
 scanf(
"%d",&x);
 p
=creat(x,null,null);
 bt
=p;                                   //使bt p都指向根结点
 printf("输入新的结点值:");
 scanf(
"%d",&x);
 
while(x!=-1)
   {p
=bt;
    q
=p;                    
 
while(x!=p->data&&q!=null)              //q记录当前根结点
   {p=q;
    
if(x<p->data)
    q
=p->lchild;
    
else
    q
=p->rchild;
   }
  
if(x==p->data)
  {printf(
"元素%d已经插入二叉树中!\n",x);
  }
  
else
   
if(x<p->data)    ins_lchild(p,x);
      
else             ins_rchild(p,x);
   scanf(
"%d",&x);
   }
 p
=bt;
 printf(
"struct of the binary tree:\n");
 printf(
"number\taddress\tdata\tlchild\trchild\n");
 prorder(p);
 printf(
"\n");
 printf(
"用括号形式输出二叉树:");
 print(p);

 printf(
"\n请任意输入树中存在的两个结点:");
 scanf(
"%d,%d",&v1,&v2);
 y 
= FindLowestCommonAncestor(p, v1, v2);
 printf(
"输出%d和%d的最低公共祖先:",v1,v2);
 printf(
"%d\n",y);
}

 

 运行结果:
输入根结点:20
输入新的结点值:8 22 4 12 10 14 -1       (以-1结束结点的输入)
struct of the binary tree:
number   addresss      data      lchild         rchild
1               4391168       20        4391104   4391040
2               4391104       8          4390976   4399072
3               4390976      4           0                 0
4               4399072     12          4399008  4398944
5               4399008     10          0                0
6               4398644     14          0                0
7               4391040     22          0                0
用括号形式输出:20(8(4,12(10,14)),22)   (输出左子树打印左括号,输出右子树后打印括号)
请任意输入树中存在的两个结点:4,14
输出4和14的最低祖先:8



posted @ 2007-07-14 10:57 ZelluX 阅读(2823) | 评论 (2)编辑 收藏

1.一行代码解决的辗转相除法
for(;;){if ((m %= n) == 0) return n;if ((n %= m) == 0) return m;}


2.推进式的前缀表达式求值,没见过这种递归@@
char *a; int i;
int eval()
{
    
int x = 0;
    
while (a[i] == ' ') i++;
    
if (a[i] == '+')
    {
        i
++;
        
return eval() + eval();
    }
    
if (a[i] == '*')
    {
        i
++;
        
return eval() * eval();
    }
    
while ((a[i] >= '0'&& (a[i] <= '9'))
        x 
= 10 * x + (a[i++- '0');
    
return x;
}

posted @ 2007-07-13 11:43 ZelluX 阅读(354) | 评论 (0)编辑 收藏

1. 二维数组内存分配
Algorithm in C上的方法,这种方法好处在于t[i]是指向各行首的指针,类似于Java的数组;而如果直接用malloc分配m*n*sizeof(int)大小的空间,则没有这种效果,类似于C#中的[,]数组
int **malloc2d(int r, int c)
{
    int i;
    int **t = malloc(r * sizeof(int *));
    for (i = 0; i < r; i++)
        t[i] = malloc(c * sizeof(int));
    return t;
}

posted @ 2007-07-12 19:33 ZelluX 阅读(317) | 评论 (0)编辑 收藏

1. 函数接收一维数组的形参声明
func1(str)
char str[10];
{
}
表示有界数组,数组的下标只能小于或等于传递数组的大小。10可省略,表示无界数组。

但事实上两者区别很小,编译器只是让函数接收一个指针。

二维数组类似

char str[][10];

2. 宏

#define MIN(a, b) (a<b) ? a : b

使用该宏时表达式被直接替换,增加了代码的速度,但因此增加了程序的长度。

posted @ 2007-07-10 16:33 ZelluX 阅读(282) | 评论 (0)编辑 收藏

1.
由于Python的判断语句返回值的特殊性,and-or语句可以达到类似三元运算符的效果。
bool ? a : b
可以写成
bool and a or b

2.
print None 不会输出任何信息
需要显示None,要使用print str(None)

posted @ 2007-07-10 11:00 ZelluX 阅读(455) | 评论 (0)编辑 收藏

仅列出标题
共39页: First 上一页 20 21 22 23 24 25 26 27 28 下一页 Last