检查或搜索字段-a以获取字段b的内容

时间:2015-08-27 23:13:36

标签: cobol

pic x(100) field-a

pic x(100) field-b

两者都是左对齐的&资本化。 Field-b-length是其最后一个非空字节的位置。

我需要进行匹配才能看到field-b(长度为field-b-length)是否出现在field-a的任何位置,即如果field-b = 'DOG'field-a = 'MANY PEOPLE LIKE DOGS BUT SOME PREFER CATS (followed by spaces to a length of 100)'匹配他们。

我查看了INSPECT语句,但它匹配文字值,而不是变量名称。就像我可以Inspect field-a tallying cnt-1 for all 'DOG',而不是INSPECT field-a tallying cnt-1 for all field-b (1 : field-b-length),在这种情况下=' DOG'。

Field-a位于包含2000万条记录的文件中,field-b位于包含400个条目的文件中,因此作业运行时间超过10小时,我必须运行25个以上的作业,所以我必须针对field-a文件中的每个条目检查field-b(读入程序中的数组)。

目前,我确定field-b的长度并将其与field-a进行比较,以字节为单位,长度为field-b。如果任何字节不匹配,我退出,并将field-a转移到左边,然后再试一次,直到我尝试了(100 - field-b-length)次。它很难看,但它确实有效。

我一直在寻找更高效,更优雅的东西。

3 个答案:

答案 0 :(得分:3)

哪个COBOL不将标识符-3作为标记标准?

这应该有效

   01 field-a            pic x(100) value 
      "MANY PEOPLE LIKE DOGS AND CATS AND MORE DOGS".
   01 field-b            pic x(100) value "DOG".
   01 comparison-length  pic 999 value 3.
   01 found-count        pic 999.
   01 position-tally     pic 999.

...

   inspect field-a tallying
       found-count for all field-b(1:comparison-length)
   if found-count greater than zero then
       display "Found " found-count " occurrences" end-display
   else
       display
          "No " field-b(1:comparison-length) " found"
       end-display
   end-if

   move "HORSE" to field-b
   move zero to comparison-length
   inspect field-b tallying comparison-length
       for characters before initial space

   inspect field-a tallying position-tally
       for characters before initial field-b(1:comparison-length)
   if position-tally less than length of field-a then
       display "Found at " position-tally end-display
   else
       display
           "No " field-b(1:comparison-length) " found"
      end-display
   end-if

Found 002 occurrences
No HORSE found

但是,这是用GnuCOBOL测试的,所以我对你的特定编译器感到好奇。

编辑;由于比尔伍德的评论,代码略有变化。留下两种检测子串的样式,只是因为

答案 1 :(得分:2)

首先,您的数据名称不会编译,至少是标准。忽略您忽略了级别编号,字段的名称(如果存在)必须遵循级别编号。然后,数据定义的子句可以按您喜欢的任何顺序排列。

其次,“丑陋但工作”不起作用,你只是没有测试极限。将DOG置于位置98,99和100,然后尝试(100-3)尝试从位置1找到DOG。第一次尝试将从位置1开始,第97次尝试将从位置97开始。第98个字节将永远不会用作起点,因此尾随的DOG永远不会匹配。关接一个。关闭的情况的青蛙。关逐狗。

正如Brian Tanner所说,INSPECT确实做了你想做的事。 INSPECT的优势在于,对于三字节参考修改,您的数据可以从位置98开始并仍然匹配。 INSPECT已经为您编码。

由于您没有说您需要所有DOG的计数,只是知道它在那里,然后使用FIRST,而不是ALL。找到匹配项后,INSPECT将“停止”。这只会影响“匹配”的表现,但仍然不需要额外做其他事情。

INSPECT是否是最快的方法,取决于您使用的实际编译器中的实现。因此,如果急需速度(每天需要的任务,每天五次)测试它,并看看它如何影响您的性能要求。

如果您需要寻找更快的速度,您需要更好地了解数据。

在IBM的企业COBOL中,使用TALLYING,ALL进行INSPECT(不能像我最初建议的那样使用FIRST,只能在INSPECT上使用REPLACING)和参考修改字段是最快的通用方式,并且只有如果你要求表现出比你更好的表现,你应该去别处看看。

有许多“搜索”任务可以考虑INSPECT,通常是:它是否存在(你的任务);那里有多少;在哪里?

对于前两个,用TALLYING和ALL进行检查。虽然如果唯一的需要是知道存在或其他方面,计算所有这些似乎是迟钝的,这个版本的INSPECT是最快的方法。如果它计数一个,然后继续到最后仍在搜索,它只会在匹配的记录上执行此操作。 INSPECT的替代使用,在......之前计算所有字符,是“非常慢”(相对术语)。

要以最有效的方式罚款起始位置,首先要检查是否有需要寻找的东西。然后,使用循环查找数据(您将知道它在那里,因此您不需要检查该字段的“溢出”)。

这些对INSPECT性能的引用可能不适用于您的特定编译器,因为它完全取决于实现。

与往常一样,由于性能问题,数据的实际性质将帮助您选择最佳方式。上面的建议持有(给定编译器)“正常”数据。如果您的数据不是特别“正常”,那么专注于不正常的数据将有所帮助。

假设2000万条记录中有90%的数据要搜索的数据为30字节或更少。

01  field-to-search.
    05  mostly-data-here                PIC X(30).
    05  sometimes-data-here             PIC X(70).
        88  only-the-short-data         VALUE SPACE.

IF only-the-short-data
    INSPECT mostly-data-here ...
ELSE
    INSPECT field-to-search ...
END-IF

因此,90%的INSPECT只会占用30个字节,代价是使用88测试空间的IF。这只是你可以做的一个变化 - 最好的取决于数据。理解数据。考虑几种可行的方法。测试以确认它们是否有效。使用反映现实的数据进行体积测试。还有完全不同数据的体积测试。根据数据的不同,不同的解决方案可以更快或更慢。

答案 2 :(得分:-1)

听起来好像你应该使用数据库。将两个文件加载到表中然后使用SELECT ... WHERE子句执行LIKE是值得的。我希望整个过程能在几分钟内完成。