发新话题
打印

[原创]动词过去式还原程序

[原创]动词过去式还原程序

文章作者:sudami
信息来源:邪恶八进制信息安全团队(www.eviloctal.com

刚上经常逛的另一个论坛,收到一个求助者的短信,让我帮他做这个题目:
引用:
            动词过去式还原程序:
1.内容
设计程序, 输入一组过去式程序,输出相应的动词原型

2. 要求
程序具有不规则动词表输入功能.
不规则动词以文件形式存储,可以从文件读入 存入安字母排序的结构体数组
对于不是动词过去式的输入应给予提示!
--------------------------------------------------------------------------------------------------------
大致做了,实现了以下功能:

1.过滤不是字母的字符. 比如输入:2%read#ed,会得到:read
2.具有添加不规则动词的功能,但我发现一个bug:
 我用CFile::modeCreate | CFile::modeNoTruncate来保证打开存在的文件时仅仅是打开而不是截去,但运行时总是把文件截断为0,很是不解.
复制内容到剪贴板
代码:
// 打开文件
    CStdioFile  fText;
    CFileException FileExc;
    UINT nOpenFlags;
    CString str;
   
    nOpenFlags = CFile::modeReadWrite | CFile::modeCreate | CFile::modeNoTruncate;
    if (!fText.Open(szBuffer, nOpenFlags, &FileExc))
    {
      FileExc.ReportError ();
      return 0;
    }
----------------------------(这个问题已经解决,原来问题不是出在这里,是在 wt 这个上)---------------
复制内容到剪贴板
代码:
if ((fp = fopen (szBuffer, "wt")) == NULL)
  {
    ::MessageBox (NULL, "Can not open it!", "sudami", MB_OK);
    exit (1);
  }
这里的wt 应该改成 at+, 即以读写形式打开文件


3."对于不是动词过去式的输入应给予提示!"
这个功能我想了半天都不知道如何实现,怎么能判断一个不规则的词是动词过去式还是其他的呢~~

4.
*******代码优化...*******
复制内容到剪贴板
代码:
     
       if (temp[i-3] == temp[i-4])
      {
        i = i - 3;
        j = i - 1;
        cout << "---->Result:" ;
        while (i--)
        {
          cout << temp[j-i];
        }
        cout << endl;
        
        cout << "Input:";
        cin.getline (g_buffer, MAX_PATH);
        Convert (g_buffer);  
      }

      else
      {
        cout << "---->Result:" ;
        i = i - 2;
        j = i - 1;
        while (i--)
        {
          cout << temp[j-i];
        }
        cout << endl;
        cout << "Input:";
        cin.getline (g_buffer, MAX_PATH);
        Convert (g_buffer);  
      } // if
这里if和else里的内容差不多,累赘.,应该改成:
复制内容到剪贴板
代码:
i=(temp[i-3]==temp[i-4])?(i-3):(i-2);
        j = i - 1;
        cout << "---->Result:" ;
        while (i--)
        {
          cout << temp[j-i];
        }
        cout << endl;
        
        cout << "Input:";
        cin.getline (g_buffer, MAX_PATH);
        Convert (g_buffer);  
********算法问题***********
复制内容到剪贴板
代码:
     
if (temp[i-1] == &#39;d&#39;)
    {
    if (temp[i-2] == &#39;e&#39;)        //注意:下面没有else与这个if对应
    {
      if (temp[i-3] == temp[i-4])
      {
       .....
      }

      else
      {
       ....
      }
    }
  }
  
  else
  {
  ....//处理倒数第2个字母不是e的情况
  }
由于第二个if没有else对应....程序会忽略很多这种最后一个字母是d而倒数第二个字母不是e的不规则动词..
譬如:did,could,should,read....

其实,...这里的算法本身就有问题...没有考虑很多不规则动词的情况...
根据算法...
fled------->fl(应该为fleed)
bled------>bl(应该为bleed)
led-------->l(应该为lead)
added---->ad(应该为add)
loved----->lov(应该为love)
married--->marri(应该为marry)
......
还有很多例子...

由于写这个的时候把这些遗忘了,故补充进来供有兴趣的深入~

--------------------------------------------
程序运行截个图:



-----------------------------------------------------------------------------------------------------------

程序代码如下:
复制内容到剪贴板
代码:
/******************************************************
* FileName  :  1.cpp
* Author   :  sudami
* FinishTime :  2007/07/10
* Comment  :  converse a verb to
******************************************************/

#include <iostream.h>
#include <string.h>
#include <afx.h>
#include <stdlib.h>
#include <stdio.h>
#include <conio.h>
#include <fstream.h>

char g_buffer[MAX_PATH];   // globle array in order to preserve strings
TCHAR szBuffer[MAX_PATH+1]; // current directory
HANDLE hFile;


////////////////////////////////////////////////////////////////////////////

int ShowMessage ();    // 显示提示信息
int Convert (char *str);  // 负责动词的查找、添加和显示
int Dispart (char *s);   // 将数据写入文件

////////////////////////////////////////////////////////////////////////////

int main ()
{
  ShowMessage ();
  Convert (g_buffer);
  
  return 0;
}

/***********************************************************************
*                                   *
*      Module: Convert ()                     *
*      Function : convert some vertb past tense to Prototype   *      
*                                   *
************************************************************************/

int Convert (char *s)
{
  int i = 0;
  int j = 0;
  int k = 0;
  char temp[MAX_PATH]; // array intend to preserve letters
  
  // filters the character string,only left with letters
  do
  {
    while (*s >= &#39;A&#39; && *s <= &#39;Z&#39; || *s >= &#39;a&#39; && *s <= &#39;z&#39;)
    {
      temp[i] = *s;
      ++i;
      ++s;
    }
  }while (*s++);
  
  // check if it iterminates with &#39;d&#39;(ignore the &#39;\0&#39; character)
  if (temp[i-1] == &#39;d&#39;)
  {
    if (temp[i-2] == &#39;e&#39;)
    {
      if (temp[i-3] == temp[i-4])
      {
        i = i - 3;
        j = i - 1;
        cout << "---->Result:" ;
        while (i--)
        {
          cout << temp[j-i];
        }
        cout << endl;
        
        cout << "Input:";
        cin.getline (g_buffer, MAX_PATH);
        Convert (g_buffer);  
      }

      else
      {
        cout << "---->Result:" ;
        i = i - 2;
        j = i - 1;
        while (i--)
        {
          cout << temp[j-i];
        }
        cout << endl;
        cout << "Input:";
        cin.getline (g_buffer, MAX_PATH);
        Convert (g_buffer);  
      } // if
    }
  }

  /*********************************************************************
  **** 下面的else是判断的重点,如果是不规则动词就按照下面的方式处理 ****
  *********************************************************************/
  
  else
  {
    cout << "this is not a regular verb,if it is not find int test.txt,you could build it." << endl;
   
    // 取得当前目录
    ::GetCurrentDirectory (MAX_PATH + 1, szBuffer);
    if (szBuffer[lstrlen(szBuffer) - 1] != &#39;\\&#39;)
      lstrcat (szBuffer, TEXT("\\"));
   
    lstrcat (szBuffer, "text.txt");
   
    // 打开文件
    CStdioFile  fText;
    CFileException FileExc;
    UINT nOpenFlags;
    CString str;
   
    nOpenFlags = CFile::modeReadWrite | CFile::modeCreate | CFile::modeNoTruncate;
    if (!fText.Open(szBuffer, nOpenFlags, &FileExc))
    {
      FileExc.ReportError ();
      return 0;
    }
    DWORD dwBytes = fText.GetLength ();
    fText.Close ();
   
    // 判断文件是否为空
    if (dwBytes == 0) // 是空文件
    {
      char choice;
      cout << "There are no characters macth the current string,do you want to create it? y/n" <<endl;
      choice = getchar ();
      if (choice == &#39;y&#39;)
      {
        char szBuild[1024];
        cout << "\t* [+] Usage: intput &#39;broke@break&#39; *\n"
           << "\t* [-] Example: broke@break *\n"
           << "\t* [-] Result: Your input is now preserved in test.txt *\n"
           << endl;
        cout << "Build:";
        cin.getline (szBuild, 1024);
      
        // 写到文件中
        Dispart (szBuild);
        cout << "Your input is now preserved in " << szBuffer <<endl;
        
        cout << "Input:";
        cin.getline (g_buffer, MAX_PATH);
        Convert (g_buffer);
      }

      else
      {
        cout << "Input:";
        cin.getline (g_buffer, MAX_PATH);
        Convert (g_buffer);
      } // if
    }
   
    else // 非空文件
    {
      // 打开文件
      CStdioFile  Text;
      CFileException FileExc;
      UINT nOpenFlags;
      CString str;
      
      nOpenFlags = CFile::modeReadWrite | CFile::modeCreate | CFile::modeNoTruncate;
      
      if (!Text.Open(szBuffer, nOpenFlags, &FileExc))
      {
        MessageBox(NULL, "不能打开非空文件", "sudami", MB_OK);//显示出来
        FileExc.ReportError ();
        return 0;
      }
      
      BOOL bCheck = FALSE;
      CString szstr;
      
      // 一行一行的读取文件中的内容
      while (Text.ReadString (szstr))
      {
        // MessageBox(NULL, szstr, "sudami", MB_OK);//显示出来
        UINT t = szstr.Find("@");
        UINT n = szstr.GetLength ();
        int l = n - t - 1;
        CString szLeft = szstr.Left (t);
        
        
        // 如果此行中@前面的值与用户输入的匹配,则输出@后面的值
        if (strcmp (g_buffer, szLeft) == 0)
        {
          bCheck = TRUE;
          CString szRight = szstr.Right (l);
          cout << "---->Result:" << szRight <<endl;
        //  cout << "Input:";
        //  cin.getline (g_buffer, MAX_PATH);
        //  Convert (g_buffer);
        //  break;
        }  
      }
      Text.Close ();

      if (!bCheck) // 在文件中没有找到可以匹配的, 新建
      {
        cout << "There are no characters macth the current string,do you want to create it? y/n" <<endl;
      
        char szBuild[1024];
        cout << "\t* [+] Usage: intput &#39;broke@break&#39; *\n"
          << "\t* [-] Example: broke@break *\n"
          << "\t* [-] Result: Your input is now preserved in test.txt *\n"
          << endl;
        cout << "Build:";
        cin.getline (szBuild, 1024);
        
        // 写入文件
        Dispart (szBuild);
        cout << "Your input is now preserved in " << szBuffer <<endl;
        
        cout << "Input:";
        cin.getline (g_buffer, MAX_PATH);
        Convert (g_buffer);
      }
      
    } // if
   
  } // if
  
  return 0;
}

/***********************************************************************
*                                   *
*    Module: Dispart ()                      *
*    Function: Read data from test.txt,dispart into two characters *      
*                                   *
************************************************************************/

int Dispart (char *s)
{
  int i = 0;
  int j = 0;
  int k = 0;
  int r = 0;
  char szBuildBuffer1[20];
  char szBuildBuffer2[20];
  
  /************************************************************
  * 获取用户输入的对应字符串,将其分开分别保存在2个数组中
  * eg:用户输入---> broke@break,则szBuildBuffer1[1024]保存broke
  * szBuildBuffer2[1024]保存break
  ************************************************************/
  do
  {
    if (*s == &#39;@&#39;)
    {
      char szBuild[1024];
      cout << "Error,please input again!\n";
      cout << "Build:";
      cin.getline (szBuild, 1024);
      Dispart (szBuild);
    }
   
    while (*s >= &#39;@&#39; && *s <= &#39;Z&#39; || *s >= &#39;a&#39; && *s <= &#39;z&#39;)
    {
      if (*s == &#39;@&#39;)
      {
        s++;
        do
        {
         
          while (*s >= &#39;A&#39; && *s <= &#39;Z&#39; || *s >= &#39;a&#39; && *s <= &#39;z&#39;)
          {
            szBuildBuffer2[j] = *s;
            j++;
            s++;
          }
        }while (*s++);
      }
      
      else
      {
        if (*s == &#39;\0&#39;)
          break;
        
        szBuildBuffer1[i] = *s;
        i++;
        s++;
      }
    }
  }while (*s++);
  
  /*******************************************************************
  * 将所得到的2个数组内容写入到test.txt文件中
  * 用到fstream库中的函数 fputc
  *******************************************************************/
  
  char a = &#39;@&#39;;
  char b = &#39;\n&#39;;
  FILE *fp;
  if ((fp = fopen (szBuffer, "at+")) == NULL)
  {
    ::MessageBox (NULL, "Can not open it!", "sudami", MB_OK);
    exit (1);
  }
  
  k = i - 1;
  while (--i)
  {
    fputc (szBuildBuffer1[k - i], fp);
  }
  
  fputc (a,fp);
  r = j - 1;
  while (j--)
  {
    fputc (szBuildBuffer2[r - j], fp);
  }
  fputc (b,fp);
  fclose (fp);
  return 0;
}

/***********************************************************************
*                                   *
*      Module: ShowMessage ()                   *
*      Function : Display some Information to the user      *      
*                                   *
************************************************************************/

int ShowMessage ()
{
  system ("color F");
  system ("title sudami");
  cout << "--- a little subject made by sudami ---\n"
    << "--- You may contact with me through the mail: <[email]xiao_rui_119@163.com[/email]> ---\n\n"
    << "\t* Please input some verb past tense here... *\n"
    << "\t* [+] Usage: intput &#39;1r+%e3a@4d5e6d&#39;,return &#39;read&#39; *\n"
    << "\t* [-] Example: 1r+%e3a@4d5e6d *\n"
    << "\t* [-] ---->Result: read *\n"
    << endl;
  cout << "Input:";
  cin.getline (g_buffer, MAX_PATH);
  
  return 0;
}
代码写的很垃圾, 请批评指正,
有兴趣的大牛能否丢个更简练高效的代码出来小弟借鉴一下啊~
WINDOWS内核疯狂爱好者

TOP

东西到不是很难  只是C 那一堆符号 真迷糊  只是你想提高质量吧

zshoucheng 说过一本书 林锐高质量C++编程 你可以看看 网上有电子书的

偶是小兵 传不了附件............... 要的话 也可以传给你

TOP

<高质量C++编程>
这书图书馆有,我看过了.

这代码不完善,仅仅就是一点C语言的运用,弄个GUI界面,优化下算法,和数据库再挂接下应该效果会比较好.
WINDOWS内核疯狂爱好者

TOP

发新话题