鱼C论坛

 找回密码
 立即注册
查看: 2491|回复: 0

[学习笔记] 顺序串

[复制链接]
发表于 2018-4-24 21:59:00 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
《数据结构C++描述》 清华大学出版社   任燕编著

小弟改了程序中的一个bug,看来数据结构还是要自己来运行一下,不能光看不练啊
  1. #include <iostream>
  2. #include <assert.h>
  3. using namespace std;

  4. class SqString{
  5. public:
  6.         //把顺序串置空
  7.         void clear();

  8.         //获取第i个字符
  9.         bool getChar(int i, char &c);

  10.         //求顺序串的长度
  11.         int getLength();

  12.         //求模式串的next数组
  13.         void get_next(int *next, int display = 1);

  14.         //串的朴素匹配(有回溯查找)
  15.         int index(SqString p, int pos);

  16.         //模式匹配(无回溯KMP查找)
  17.         int index_KMP(SqString p, int pos);

  18.         //在第i个字符前插入另一个字符串
  19.         bool insert(int i, SqString t);

  20.         //判断顺序串是否为空
  21.         bool isEmpty();

  22.         //重载赋值运算符   char类型字符串
  23.         SqString operator=(char *s);

  24.         //重载赋值运算符  SqString类型顺序串
  25.         SqString operator=(SqString s);

  26.         //重载加法运算符    被加是char类型
  27.         SqString operator+(char* s);

  28.         //重载加法运算符   SqString类型顺序串
  29.         SqString operator+(SqString s);

  30.         //重载是否小于运算符  SqString类型
  31.         bool operator <(SqString s);

  32.         //重载是否相等运算符  char
  33.         int operator ==(char *s);

  34.         //重载是否相等运算符   SqString
  35.         int operator==(SqString s);

  36. protected:
  37.         //把char类型的顺序串赋值给当前顺序串的赋值函数
  38.         void strAssign_aux(char *s);

  39. public:
  40.         //删除第i个字符起的长度为len的子串
  41.         bool strDelete(int i, int len);

  42.         //取顺序串的子串
  43.         bool subString(SqString& sub, int i, int len);

  44.         SqString();
  45.         virtual ~SqString();

  46.         SqString(char* s);
  47.         SqString(SqString &s);


  48.         //重载输出函数
  49.         friend ostream& operator <<(ostream& out, SqString s);

  50. protected:
  51.         int length;//顺序串长度
  52.         char *ch;//顺序串动态存储空间的首地址
  53. };

  54. void SqString::clear(){
  55.         if (ch){
  56.                 delete[]ch;
  57.                 ch = NULL;
  58.                 length = 0;
  59.         }
  60. }

  61. bool SqString::getChar(int i, char &c){
  62.         if (i<1 || i>length){
  63.                 return false;
  64.         }
  65.         c = ch[i - 1];
  66.         return true;
  67. }

  68. int SqString::getLength(){
  69.         return length;
  70. }


  71. void SqString::get_next(int *next, int display){
  72.         int j = -1, i = 0;//前后字符指针,初始化为-1和0
  73.         int first_i;//当前组第一个元素的下标
  74.         char no[5] = "[ i]";

  75.         //生成next数组每个元素的值
  76.         next[0] = -1;//-1为终止标志
  77.         while (i < length){
  78.                 if (j == -1 || ch[j] == ch[i]){
  79.                         j++;
  80.                         i++;
  81.                         next[i] = j;
  82.                 }
  83.                 else{
  84.                         j = next[j];
  85.                 }
  86.         }
  87.         if (display == 1){
  88.                 cout << "   当前模式串的next[]数组为:" << endl;
  89.                 first_i = 0;
  90.                 while (first_i < length){
  91.                         i = first_i;
  92.                         cout << "       ";
  93.                         do{
  94.                                 //修正元素下标的字符表示
  95.                                 if (i < 10){
  96.                                         no[2] = i + '0';//数组中元素的小标小于10
  97.                                 }
  98.                                 else{
  99.                                         no[1] = i / 10 + '0';//数组中元素的下标大于等于10
  100.                                         no[2] = i % 10 + '0';
  101.                                 }
  102.                                 //每个元素的序号显示占5个字符,不足以空格补齐,靠右对齐
  103.                                 cout.width(5);
  104.                                 cout.fill(' ');
  105.                                 cout.setf(ios::right, ios::adjustfield);
  106.                                 cout << no;
  107.                                 i++;
  108.                         } while (i % 10 && i < length);

  109.                         cout << endl;
  110.                         cout << "      ";//显示模式串中的字符
  111.                         i = first_i;
  112.                         do{
  113.                                 cout.width(5);
  114.                                 cout.fill(' ');
  115.                                 cout.setf(ios::right, ios::adjustfield);
  116.                                 cout << ch[i];
  117.                                 i++;
  118.                         } while (i % 10 && i < length);
  119.                         cout << endl;

  120.                         //显示next[]数组中每个元素的值
  121.                         cout << "    ";
  122.                         i = first_i;
  123.                         do{
  124.                                 cout.width(5);
  125.                                 cout.fill(' ');
  126.                                 cout.setf(ios::right, ios::adjustfield);
  127.                                 cout << ch[i];
  128.                                 i++;
  129.                         } while (i % 10 && i < length);

  130.                         first_i = i;//下一组第一个元素的下标
  131.                         cout << endl << endl;
  132.                 }
  133.         }
  134. }


  135. //朴素查找
  136. int SqString::index(SqString p, int pos){
  137.         int i = pos - 1;//指向第pos个字符的下标
  138.         int j = 0;

  139.         while (i < length && j < p.length){
  140.                 if (ch[i] == p.ch[j]){
  141.                         i++;
  142.                         j++;
  143.                 }
  144.                 else{//下标的重置
  145.                         i = i - j + 1;
  146.                         j = 0;
  147.                 }

  148.         }
  149.         if (j == p.length){
  150.                 return i - p.length + 1;//找到了
  151.         }
  152.         else{
  153.                 return 0;//没找到
  154.         }
  155. }


  156. //KMP查找
  157. int SqString::index_KMP(SqString p, int pos){
  158.         int i = pos - 1;
  159.         int j = -1;//模式串当前字符,初始化为-1,就是没有指向

  160.         int *next;
  161.         next = new int[p.length];
  162.         assert(next != 0);

  163.         p.get_next(next, 0);//求模式串的next函数的数组

  164.         //从主串的第pos个字符开始,与模式串的对应字符逐一比较
  165.         while (i < length && j < p.length){
  166.                 if (j == -1 || ch[i] == p.ch[j]){
  167.                         i++;
  168.                         j++;
  169.                 }
  170.                 else{
  171.                         j = next[j];//重置,无回溯
  172.                 }
  173.         }
  174.         if (j == p.length){
  175.                 return i - p.length + 1;//找到了
  176.         }
  177.         else{
  178.                 return 0;//没找到
  179.         }
  180. }


  181. bool SqString::insert(int i, SqString t){
  182.         char *temp;
  183.         if (i<1 || i>length || t.isEmpty()){
  184.                 return false;

  185.         }
  186.         temp = new char[length + t.length];
  187.         assert(temp != 0);

  188.         //其实这里感觉用指针也是比较方便
  189.         int j;
  190.         for (j = 0; j < i - 1; j++){
  191.                 temp[j] = ch[j];
  192.         }
  193.         for (; j < i - 1 + t.length; j++){
  194.                 temp[j] = t.ch[j - i + 1];
  195.         }
  196.         for (; j < length + t.length; j++){
  197.                 temp[j] = ch[j - t.length];
  198.         }

  199.         delete[]ch;
  200.         ch = temp;
  201.         length = length + t.length;
  202.         return true;
  203. }

  204. bool SqString::isEmpty(){
  205.         return length ? false : true;
  206. }

  207. SqString SqString::operator=(char *s){
  208.         strAssign_aux(s);//赋值辅助函数
  209.         return *this;
  210. }

  211. SqString SqString::operator =(SqString right){
  212.         if (this != &right){
  213.                 clear();
  214.                 ch = new char[right.length];
  215.                 assert(ch != 0);

  216.                 length = right.length;
  217.                 for (int i = 0; i < right.length; i++){
  218.                         ch[i] = right.ch[i];
  219.                 }
  220.         }
  221.         return *this;
  222. }

  223. SqString SqString::operator +(char* s){
  224.         insert(length + 1, s);//调用insert函数
  225.         return *this;
  226. }

  227. SqString SqString::operator +(SqString right){
  228.         insert(length + 1, right);
  229.         return *this;
  230. }

  231. bool SqString::operator <(SqString right){
  232.         int i;
  233.         for (i = 0; i < length && i < right.length; i++){
  234.                 if (ch[i] < right.ch[i]){
  235.                         return true;
  236.                 }
  237.         }
  238.         if (i < right.length){
  239.                 return true;
  240.         }
  241.         else{
  242.                 return false;
  243.         }
  244. }

  245. int SqString::operator ==(char *s){
  246.         int s_length;//获取s的长度
  247.         for (int i = 0; s[i]; i++){
  248.                 s_length = i;
  249.         }
  250.         for (int i = 0; i < length&&i < s_length; i++){
  251.                 if (ch[i] != s[i]){
  252.                         return ch[i] - s[i];
  253.                 }
  254.         }
  255.         return length - s_length;
  256. }

  257. int SqString::operator ==(SqString right){
  258.         for (int i = 0; i < length&&i < right.length; i++){
  259.                 if (ch[i] != right.ch[i]){
  260.                         return ch[i] - right.ch[i];
  261.                 }
  262.         }
  263.         return length - right.length;
  264. }



  265. //赋值辅助函数
  266. void SqString::strAssign_aux(char *s){
  267.         clear();
  268.         length = 0;
  269.         for (int i = 0; s[i]; ++i){
  270.                 length++;
  271.         }
  272.         cout << length << endl;

  273.         ch = new char[length];
  274.         assert(ch != 0);
  275.         for (int i = 0; i < length; i++){
  276.                 ch[i] = s[i];
  277.         }
  278. }

  279. //删除第i个字符起长度为len的字符串
  280. bool SqString::strDelete(int i, int len){
  281.         char *temp;

  282.         if (i<1 || i>length + 1){
  283.                 return false;
  284.         }
  285.         temp = new char[length - len];

  286.         assert(temp != 0);
  287.         for (int j = 0; j < i - 1; j++){//前半段
  288.                 temp[j] = ch[j];
  289.         }
  290.         for (int j = i - 1 + len; j < length; j++){//后半段
  291.                 temp[j - len] = ch[j];
  292.         }
  293.         delete[]ch;
  294.         ch = temp;
  295.         length -= len;
  296.         return true;
  297. }


  298. //取子串
  299. bool SqString::subString(SqString &sub, int i, int len){
  300.         if (i<1 || i>length || len < 0 || len>length - i + 1){
  301.                 return false;
  302.         }
  303.         sub.clear();

  304.         sub.ch = new char[len];
  305.         assert(sub.ch != 0);
  306.         for (int j = 0; j < len; j++){
  307.                 sub.ch[j] = ch[i - 1 + j];
  308.         }
  309.         sub.length = len;
  310.         return true;
  311. }


  312. //构造函数
  313. SqString::SqString(){
  314.         ch = NULL;
  315.         length = 0;
  316. }

  317. SqString::~SqString(){
  318.         clear();
  319. }

  320. //拷贝构造函数char类型
  321. SqString::SqString(char *s){
  322.         ch = NULL;
  323.         strAssign_aux(s);
  324. }

  325. //拷贝构造函数
  326. SqString::SqString(SqString &other){
  327.         ch = new char[other.length];
  328.         assert(ch != 0);
  329.         length = other.length;
  330.         for (int i = 0; i < length; i++){
  331.                 ch[i] = other.ch[i];
  332.         }
  333. }



  334. ostream& operator<<(ostream& out, SqString s){
  335.         for (int i = 0; i < s.length; i++){
  336.                 out << s.ch[i] << "  ";
  337.         }
  338.         cout << endl;
  339.         return out;
  340. }

  341. int main(int argc, char* argv[]){
  342.         SqString s1("Hello World!");
  343.         cout << s1;
  344.         SqString s2("haha,welcome to the program world,Hello World!,enjoy it");
  345.         cout << s2;
  346.         cout << "回溯法查找:";
  347.         cout << s2.index(s1, 0) << endl;

  348.         cout << "KMP查找:";
  349.         cout << s2.index_KMP(s1, 0) << endl;
  350.         return 0;
  351. }
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-4-20 08:00

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表