使用ansi C中的字典将完整的字符串解析为单词

时间:2017-03-27 13:05:11

标签: c parsing dictionary ansi

我是ansi C学生的开始。我的教授要求我编写一个程序,使用字典加密,解密和解析不间断的字符串。

我的加密和解密算法运行得很好,但我对如何解析字符串感到很茫然。

示例:

不间断的字符串: Idontknowwhatto

字典: 一世 别 知道 什么 至 做

如果任何机构可以提供指导或指出我可以帮助我理解这一过程的资源,我将不胜感激。

谢谢

3 个答案:

答案 0 :(得分:1)

我建议你使用贪婪的策略:

  • 找到字典中与连续字符串匹配的最长字词。
  • 重复直到你到达终点。
  • 如果找不到匹配项,请备份并使用下一个较短的匹配项。如果没有剩下较短的匹配,则备份另一步。

注意:这将找到一个解决方案(如果存在)。正如@ikegami在评论中指出的那样,可能不止一个。

答案 1 :(得分:0)

解决方案可以是检查字典中的第一个字母。如果存在则检查从下一个字母开始的下一组单词,如果找到所有字母,则打印它。并且再次使用与其匹配的字典的更大元素开始处理并且满足整个内容来自字典。因此可以对所有组合进行排序。

答案 2 :(得分:0)

如果您尝试从I don't know what to获取idontknowwhatto,则有效的方法类似于解决longest common substring problem的动态编程方法。更具体地说,以下是有效的算法:

#!/usr/bin/perl

use utf8;
use open ':std', ':encoding(UTF-8)';
use strict;
use warnings;
use feature qw( say );

use Algorithm::Loops qw( NestedLoops );

my $dict_qfn = '/usr/share/dict/words';

sub add :lvalue {
   my $p = \shift;
   $p = \( $$p->{$_} ) for @_;
   $$p
}

my $trie;
{
   open(my $fh, '<', $dict_qfn)
      or die("Can't open dictionary \"$dict_qfn\": $!\n");

   while (my $word = <$fh>) {
      chomp($word);
      my @key = split(//, lc( $word =~ s/\PL//gr ));
      push @{ add($trie, @key, '') }, $word;
   }
}

for my $phrase (@ARGV) {
   say("$phrase:");

   my @key = split(//, lc( $phrase =~ s/\PL//gr ));

   my @results = map { [] } 0..$#key;
   {
      my @tries = ( $trie ) x (@key+1);
      for my $i (1..@key) {
         for my $j (reverse $i..@key) {
            for my $trie ($tries[$j]) {
               $trie = $tries[$j-1]
                  or next;

               $trie = $trie{ $key[$j-1] }
                  or next;

               if ( my $word_group = $trie->{''} ) {
                  push @{ $results[$j-1] }, [ $i, $word_group ];
               }
            }
         }

         $tries[$i-1] = undef;
      }
   }

   {
      my @todo = [ 0+@key ];
      while (@todo) {
         my ($i, @word_groups) = @{ shift(@todo) };
         if ($i) {
            for (@{ $results[$i-1] }) {
               my ($len, $word_group) = @$_;
               push @todo, [ $i-$len, $word_group, @word_groups ];
            }
         } else {
            my $iter = NestedLoops(\@word_groups);
            while (my @words = $iter->()) {
               say(join(" ", @words));
            }
         }
      }
   }

   say("");
}

我会留给你在C中实现算法。