编程沙龙(10)

IT商界

  本期题目

  对于任意两个字符串s1和s2(字符串中字符只限于26个小写的英文字母)的最长公共子序列lcs(s1,s2)是s1和s2中都出现的最长子序列。例如,tie是striped和tiger的最长公共子序列。

  要求写一个程序,用户输入s1和s2,计算并显示出它们的最长公共子序列lcs(s1,s2)。

  1.有朋友询问使用哪个API函数能实现程序关机?

  ExitWindowsEx函数就能完成这个任务。

  函数定义:BOOL ExitWindowsEx(UINT uOptions, DWORD dwReserved)

  参数uOptions指定执行的关机方式;参数dwReserved为保留参数,可忽略。

  以下是uOptions可选参数表

  参数名

  对应值

  说明

  EWX_LOGOFF

  0

  关闭当前用户的应用程序,然后注销当前用户。

  EWX_SHUTDOWN

  1

  关闭系统,进入可安全关闭电源的状态。所有的文件缓冲区都被更新到磁盘。所有运行中的进程都结束。

  EWX_REBOOT

  2

  关闭并重新启动系统。

  EWX_FORCE

  4

  不理会当前运行的应用程序,而强制关闭进程。(可能会造成应用程序丢失数据)

  EWX_POWEROFF

  8

  关闭系统及电源(系统必须支持关电的特性)

  EWX_FORCEIFHUNG

  16

  针对Windows2000的参数,不与EWX_FORCE同时使用。

  2.我想谈谈本期有奖征答的题目──“最长公共子序列”。朋友们寄来的源代码在测试的过程中,我发现有部分朋友的解题思路有问题,而且出现的问题都是同一种类型。下面给出了其中一位朋友用VB写的核心代码段,请大家帮助他分析一下其中的问题。有时候帮助别人找到程序中的错误,也是对自己编程能力的一种很好的锻炼。代码部分我未做精简,只在他原有注释的基础上略加补充,以方便大家更好地理解。

  …… '以上是获得s1、s2的代码(略)

  m = UBound(s1) '得出第一个数组的下标,用于循环变量 就是第一个字符串的长度

  n = UBound(s2) '得出第二个数组的下标,用于循环变量 就是第二个字符串的长度

  k = 0

  '计算两个字符串的最长公共子序列

  '核心思想就是以两个字符串中短的那个作为比较的基准,依次从短的字符串中提取一

  '个字符来和长的字符串中的第k个字符(不包括第k个字符)以后的字符依次进行比

  '较,如果找到有相同的字符,就将该字符存入最长公共子序列的最后并记录下该字符

  '在长字符串中的位置到变量k,换短字符串中的下一个字符进行上面的工作。

   If m >= n Then '先判断哪个字符串短,以它的下界为外循环的循环变量

   For l = 0 To n

   For j = k To m

   If s2(l) = s1(j) Then

   strlcs = strlcs & s2(l) '得出最大公共子序列

   k = j + 1

   Exit For '跳出内循环,用s2的下一个字符与s1的(j+1)比较

   End If

   Next

   Next

   Else

   For l = 0 To m

   For j = k To n

   If s1(l) = s2(j) Then

   strlcs = strlcs & s1(l)

   k = j + 1

   Exit For

   End If

   Next

   Next

    End If

    '此处strlcs里储存的就是我们找到的最长公共子串

    ……