学习贺利坚老师算法库
数据结构例程——串的顺序存储应用_使用顺序串存储身份证号-CSDN博客
本人详细解析博客
串的顺序存储的应用实例二_串的顺序存储应用-CSDN博客
版本更新日志
V1.0: 在原有的基础上, 进行优化名字, 并且有了相应的算法库作为支撑, 我使用了for循环来代替老师的 while循环, 可以不用频繁的控制遍历计数器, 在流程清晰后, 还要注意一些细节, 这个是我在调试时候发现的, 要记得初始化, 要清晰的知道我们遍历对比的是哪两个字符串, 什么时候赋的值,
代码流程:
主体流程:
功能函数流程:
注意事项:
涉及到对比的细节, 看下图, 我们一切按照数字计数器走, 计数器是遍历的, 本节点和下一个节点是否相同, 如果本节点和下一个节点相同的话, 我们会对串长度加一, 此时我们串长度, 包含的是本节点及其之前加上 刚才我们判断的下一个相同的节点 的长度, 所以我们计数器遍历到相同节点的时候, 此时计数器位序所指的节点,就是本节点 和其下一个相同节点的长度.
计数器总会遍历到, 此节点和下一个节点不相同的情况, 此时 串的长度, 是上一个节点及其前面串长度 加上 本遍历到的节点, 意思就是, 我们不必担心, 上一个节点已经把我们本节点算进去了, 不用累加 length了. 此时计数器在数组中的位置是, 不同字符串位置的前一个位置, 所以我们在记录下一串字符串的时候, 记得 在计数器基础上 + 1, 这是一个细节.
所以, 我们最好用图纸把相关赋值过程标记清楚, 这样更有助于我们理解.
初始时候
在没探索前, 一切都是未知
合法性判断
if(Exploration_string.length == 0){//错误:探索字符串无元素printf("\nError: The exploration string has no elements.\n");return;}
如果串是空的, 就谈不上探索元素了, 直接返回错误, 我们起码需要一个元素
遍历节点
开始利用计数器,
分成两种情况, 一种是本节点与下一个节点相等
相等的情况下,我们计数的是, 长度是, 本串包含下一个节点的长度(我们都已经遍历了, 就直接加上) , 这样我们也就默认了, 当计数器到下一个节点的时候, length就默认已经计算好了.
一种是本节点与下一个节点不等
因为计数器到本节点的时候, length长度已经计算好了, 此时我们只需要进行判断与最大串数据大小 , 交接就可以了, 需要注意的是, 此时 计数器指向的是, 下一个不同串的前一个位置, 所以要记录下一个串开始位置, 需要对计数器加一.
直到跳出
小细节就是最后一个节点是 '\0' , 这并不会影响字符串的对比查找, 但就是恰恰是'\0', 可以让我们数组有结束标志, 方便遍历输出 , 并且, 如果是一长串 a a a 的话, 最后也会遇见 '\0', 从而进行赋值Max长度和起点后退出.
函数功能:
/**************************************************
函数名: Find_longest_string
功 能: 寻找字符串中,字符串最长的,并且记录其位置和长度
参 数: (1)Sequential_string Exploration_string:要进行探索的字符串(2)int &max_begin:最大字符串的数组坐标(3)int &max_length:最大字符串的长度
思 路: 主要是设计到,最大字符串的交替(1)计数和计数位置初始化(2)判断数组中是否有数(3) 记录所遍历节点之前及其后一个节点的长度<1>:当遍历节点和其后一个节点长度相等时, 则记录此长度,<2>:当遍历节点和其后一个节点长度不相等时,则此时visit_length就是包含本字符串的长度<3>: <2>-><3>此时把此长度和最长字符串长度对比,如果大,则交换,否则继续遍历<4>: 注意: 如果交换,此时,遍历节点仍然是,两个不同节点的前一个节点,所以记录下一串开始位置时,需要visit_counter+1返回值: 无
**************************************************/
void Find_longest_string(Sequential_string Exploration_string,int &max_begin,int &max_length)
{int visit_counter = 0; //遍历计数器int visit_start = 0; //当前遍历串,初始位置int visit_length = 0; //当前遍历串的长度//初始化max_begin = 0;max_length = 0;if(Exploration_string.length == 0){//错误:探索字符串无元素printf("\nError: The exploration string has no elements.\n");return;}//至少有一个元素(本节点及其之前的相同节点个数)visit_length = 1;for(visit_counter = 0; visit_counter < Exploration_string.length; visit_counter++){
// printf("\nvisit_counter:%d,%c \n",visit_counter,Exploration_string.Sequential_string_data[visit_counter]);//如果下一个节点和本节点相同,则把判断完的本串长度更新,即带上下一个节点长度if(Exploration_string.Sequential_string_data[visit_counter] == Exploration_string.Sequential_string_data[visit_counter+1]){
// printf("\nvisit_counter=:%d,%c \n",visit_counter,Exploration_string.Sequential_string_data[visit_counter]);visit_length++;//跳到下一个元素,}else //对比当前字符串长度与最长元素长度,取大者赋值{
// printf("\nvisit_counterX:%d,%c \n",visit_counter,Exploration_string.Sequential_string_data[visit_counter]);if(visit_length > max_length){max_length = visit_length;max_begin = visit_start;}//记录下一个节点开始位置, 此时visit_counter为最大平台的最后一个字符串位置visit_start = visit_counter+1;visit_length = 1;}}
}
main函数调用
int main()
{Sequential_string test1;int counter;//计数器char test1_array[] = {'0','1','1','2','3','3','3','3','4','4','\0'};int begin_location,max_length;Assignment_Sequential_string(test1,test1_array);printf("\ntest1:\n");Display_Sequential_String(test1);Find_longest_string(test1,begin_location,max_length);printf("\n最长平台:从第%d个字符开始的%d个字符\n",begin_location+1,max_length);for(counter = begin_location; counter < begin_location+max_length; counter++){printf("%c ",test1.Sequential_string_data[counter]);}printf("\n\n");return 0;
}
调用的算法库
头函数
Sequential_string.h
#ifndef _SEQUENTIAL_STRING_H_INCLUDE
#define _SEQUENTIAL_STRING_H_INCLUDE#include <stdio.h>
#define MaxSize 100 //最多字符个数//顺序串数据结构
typedef struct
{char Sequential_string_data[MaxSize];//数组串数据int length; //实际串长
}Sequential_string;//(1)将一个字符串数组赋值给顺序串
void Assignment_Sequential_string(Sequential_string &New_String, char Assign_array[]);
//(2) 复制一个串,到另一个串
void Copy_Sequential_String(Sequential_string &accept_string, Sequential_string copy_string);
//(3)判断两个串是否相等
bool Equal_Sequential_String(Sequential_string judge_string1, Sequential_string judge_string2);
//(4)求顺序串串长
int Length_Sequential_String(Sequential_string measure_string);
//(5)串连接
Sequential_string Connect_Sequential_String(Sequential_string link1, Sequential_string link2);
//(6)求子串(从begin_loation开始的number个字符)
Sequential_string Get_Sequential_Substring(Sequential_string substring, int begin_loation, int number);
//(7)插入串(从从begin_loation开始插入字符串,然后组合成新的串)
Sequential_string Insert_Sequential_String(Sequential_string old_string, int begin_loation,Sequential_string insert_string);
//(8)删除串(从begin 开始的number个字符)
Sequential_string Delete_Sequential_String(Sequential_string old_string, int begin_loation,int number);
//(9)串替换(从begin 开始的number个字符)
Sequential_string Replace_Sequential_String(Sequential_string old_string, int begin_loation,int number,Sequential_string new_string);
//(10)输出展示串
void Display_Sequential_String(Sequential_string show_String);
#endif
库函数
Sequential_string.cpp
#include "Sequential_string.h"/**************************************************
(1)函数名: Assignment_Sequential_string
功 能: 将一个字符串数组赋值给顺序串
参 数: (1)Sequential_string &New_String:创建的新串(2)char Assign_array[]: 原始字符串数组
注 意: 顺序数组,结尾加入'\0'
返回值: 无
**************************************************/
void Assignment_Sequential_string(Sequential_string &New_String, char Assign_array[])
{int counter;for(counter = 0; Assign_array[counter] != '\0'; counter++){New_String.Sequential_string_data[counter] = Assign_array[counter];}New_String.Sequential_string_data[counter] = '\0';New_String.length = counter; //更新串最大位序
}/**************************************************
(2)函数名: Copy_Sequential_String
功 能: 复制一个串,到另一个串
参 数: (1)Sequential_string &accept_string: 复制成的串(2)Sequential_string copy_string:要复制的串
注 意: 复制成的串,传回的是地址,所以不用传回参数
返回值: 无
**************************************************/
void Copy_Sequential_String(Sequential_string &accept_string, Sequential_string copy_string)
{int counter;for(counter = 0; counter < copy_string.length;counter++){accept_string.Sequential_string_data[counter] = copy_string.Sequential_string_data[counter];}accept_string.Sequential_string_data[counter] = '\0';accept_string.length = copy_string.length;
}
/**************************************************
(3)函数名: Equal_Sequential_String
功 能: 判断两个串是否相等
参 数: (1)Sequential_string judge_string1:第一个串(2)Sequential_string judge_string2:第二个串
返回值: bool?是否相等,true:false
**************************************************/
bool Equal_Sequential_String(Sequential_string judge_string1, Sequential_string judge_string2)
{bool same = true;int counter;if(judge_string1.length != judge_string2.length){same = false;}else{for(counter = 0; counter < judge_string1.length;counter++){if(judge_string1.Sequential_string_data[counter] != judge_string2.Sequential_string_data[counter]){same = false;break;}}}return same;}/**************************************************
(4)函数名: Length_Sequential_String
功 能: 求顺序串串长
参 数: Sequential_string measure_string:要进行测量的串
返回值: int:顺序串长度信息
**************************************************/
int Length_Sequential_String(Sequential_string measure_string)
{return measure_string.length;
}/**************************************************
(5)函数名: Connect_Sequential_String
功 能: 把两个串连接成一个串
参 数: Sequential_string link1, Sequential_string link2:两个要链接的串
返回值: 返回Sequential_string Connection_string: 链接成的串
**************************************************/
Sequential_string Connect_Sequential_String(Sequential_string link1, Sequential_string link2)
{Sequential_string Connection_string;int counter;Connection_string.length = link1.length + link2.length;//将第一个串加入链接的串for(counter = 0; counter < link1.length; counter++){Connection_string.Sequential_string_data[counter] = link1.Sequential_string_data[counter];}//将第二个串加入链接的串for(counter = 0; counter < link2.length; counter++){Connection_string.Sequential_string_data[link1.length+counter] = link2.Sequential_string_data[counter];}Connection_string.Sequential_string_data[link1.length+counter] = '\0';return Connection_string;
}/**************************************************
(6)函数名: Get_Sequential_Substring
功 能: 求子串(从begin_loation开始的number个字符)
参 数: (1)Sequential_string mother_String:母串(2)int begin_loation:开始分割子串的位置(3)int number:子串的数量
返回值: Sequential_string son_String:得到的子串
**************************************************/
Sequential_string Get_Sequential_Substring(Sequential_string mother_String, int begin_loation, int number)
{Sequential_string son_String;int counter;son_String.length = 0;if(begin_loation <= 0 || begin_loation > mother_String.length || number < 0 || begin_loation+number-1>mother_String.length){//错误:分割的子字符串的位置错误。printf("\nError<6>:The position of the divided substring is wrong.\n");return son_String; // 参数不正确返回空串}for(counter = begin_loation-1; counter < begin_loation+number-1; counter++){son_String.Sequential_string_data[counter-begin_loation+1] = mother_String.Sequential_string_data[counter];}son_String.Sequential_string_data[counter-begin_loation+1] = '\0';son_String.length = number;return son_String;
}/**************************************************
(7)函数名: Insert_Sequential_String
功 能: 插入串(从从begin_loation开始插入字符串,然后组合成新的串)
参 数: (1)Sequential_string old_string:在原始串的基础上插入(2)int begin_loation: 插入的位置(3)Sequential_string insert_string:插入的新串
思 路: 在原有串的基础上,割开一个口子,放上新串,然后组合成新串
返回值: Sequential_string form_string:组合成的新串
**************************************************/
Sequential_string Insert_Sequential_String(Sequential_string old_string, int begin_loation,Sequential_string insert_string)
{int counter;Sequential_string form_string;form_string.length = 0;//参数不正确, 返回空串if(begin_loation <= 0 || begin_loation > old_string.length+1){//错误:插入位置错误printf("\nError<7>: wrong insertion position.\n");return form_string;}for(counter = 0; counter < begin_loation-1;counter++){form_string.Sequential_string_data[counter] = old_string.Sequential_string_data[counter];}for(counter = 0; counter < insert_string.length;counter++){form_string.Sequential_string_data[begin_loation-1+counter] = insert_string.Sequential_string_data[counter];}for(counter = begin_loation-1; counter<old_string.length;counter++){form_string.Sequential_string_data[insert_string.length+counter] = old_string.Sequential_string_data[counter];}form_string.Sequential_string_data[insert_string.length+counter] = '\0';form_string.length = old_string.length + insert_string.length;return form_string;}
/**************************************************
(8)函数名: Delete_Sequential_String
功 能: 删除串(从begin 开始的number个字符)
参 数: (1)Sequential_string old_string:在原有串的基础上删除(2)int begin_loation: 开始删除的位置(从逻辑1开始)(3)int number:删除的数量
注 意: 要判断删除的位置和数量是否正确
返回值:Sequential_string new_string:删除完后的新串
**************************************************/
Sequential_string Delete_Sequential_String(Sequential_string old_string, int begin_loation,int number)
{int counter;//定义计数器Sequential_string new_string;new_string.length = 0;//合法性判断(begin_loation理应从1开始到leng长度)if(begin_loation <= 0 || begin_loation > old_string.length || (begin_loation+number-1) > old_string.length){//错误:删除的位置或数量错误。printf("Error<8>: Wrong location or quantity of deletion.");return new_string;//返回空串}//择出删除位置之前的串for(counter = 0; counter < begin_loation-1;counter++){new_string.Sequential_string_data[counter] = old_string.Sequential_string_data[counter];}//择出删除位置之后的串for(counter = begin_loation+number-1; counter < old_string.length; counter++){new_string.Sequential_string_data[counter-number] = old_string.Sequential_string_data[counter];}new_string.Sequential_string_data[counter-number] = '\0';new_string.length = old_string.length - number;return new_string;
}/**************************************************
(9)函数名: Replace_Sequential_String
功 能: 串替换(从begin 开始的number个字符)
参 数: (1)Sequential_string old_string:原始串(2)int begin_loation:开始替换的位置(3)int number:替换的字符个数(4)Sequential_string replace_string:要替换成的字符串
思 路: 锁定old_string从begin_loation开始的number个字符,然后开始剪切建立新串,①把begin_loation之前的字符加入新串,②要替换成的串加入,③锁定后的字符加入④组合成新串,返回传出
注 意: 最后加'\0'
返回值: Sequential_string new_string:替换后,产生的新串
**************************************************/
Sequential_string Replace_Sequential_String(Sequential_string old_string, int begin_loation,int number,Sequential_string replace_string)
{int counter;Sequential_string new_string;new_string.length = 0;//合法性判断if(begin_loation <= 0 || begin_loation > old_string.length || begin_loation+number-1>old_string.length){//错误:要替换位置出现错误printf("\nError<9>: There is an error in the position to be replaced.\n");return new_string;//返回空串}//开始复制剪切for(counter = 0; counter < begin_loation-1; counter++){new_string.Sequential_string_data[counter] = old_string.Sequential_string_data[counter];}//加入要替换的串for(counter = 0; counter < replace_string.length; counter++){new_string.Sequential_string_data[begin_loation-1+counter] = replace_string.Sequential_string_data[counter];}//被替换位置,后面剩余的串for(counter = begin_loation+number-1; counter < old_string.length; counter++){new_string.Sequential_string_data[counter-number+replace_string.length] = old_string.Sequential_string_data[counter];}new_string.Sequential_string_data[counter-number+replace_string.length] = '\0';new_string.length = old_string.length - number + replace_string.length;return new_string;
}/**************************************************
(10)函数名: Display_Sequential_String
功 能: 输出展示串
参 数: Sequential_string show_String:要输出展示的串
注 意: 字符串后续可以换成自定义类型
返回值: 无
**************************************************/
void Display_Sequential_String(Sequential_string show_String)
{int counter;if(show_String.length > 0){for(counter = 0; counter < show_String.length; counter++){printf("%c", show_String.Sequential_string_data[counter]);}printf("\n");}
}
main.cpp主函数(包含功能函数)
/**************************************************
函数名: Find_longest_string
功 能: 寻找字符串中,字符串最长的,并且记录其位置和长度
参 数: (1)Sequential_string Exploration_string:要进行探索的字符串(2)int &max_begin:最大字符串的数组坐标(3)int &max_length:最大字符串的长度
思 路: 主要是设计到,最大字符串的交替(1)计数和计数位置初始化(2)判断数组中是否有数(3) 记录所遍历节点之前及其后一个节点的长度<1>:当遍历节点和其后一个节点长度相等时, 则记录此长度,<2>:当遍历节点和其后一个节点长度不相等时,则此时visit_length就是包含本字符串的长度<3>: <2>-><3>此时把此长度和最长字符串长度对比,如果大,则交换,否则继续遍历<4>: 注意: 如果交换,此时,遍历节点仍然是,两个不同节点的前一个节点,所以记录下一串开始位置时,需要visit_counter+1返回值: 无
**************************************************/
void Find_longest_string(Sequential_string Exploration_string,int &max_begin,int &max_length)
{int visit_counter = 0; //遍历计数器int visit_start = 0; //当前遍历串,初始位置int visit_length = 0; //当前遍历串的长度//初始化max_begin = 0;max_length = 0;if(Exploration_string.length == 0){//错误:探索字符串无元素printf("\nError: The exploration string has no elements.\n");return;}//至少有一个元素(本节点及其之前的相同节点个数)visit_length = 1;for(visit_counter = 0; visit_counter < Exploration_string.length; visit_counter++){
// printf("\nvisit_counter:%d,%c \n",visit_counter,Exploration_string.Sequential_string_data[visit_counter]);//如果下一个节点和本节点相同,则把判断完的本串长度更新,即带上下一个节点长度if(Exploration_string.Sequential_string_data[visit_counter] == Exploration_string.Sequential_string_data[visit_counter+1]){
// printf("\nvisit_counter=:%d,%c \n",visit_counter,Exploration_string.Sequential_string_data[visit_counter]);visit_length++;//跳到下一个元素,}else //对比当前字符串长度与最长元素长度,取大者赋值{
// printf("\nvisit_counterX:%d,%c \n",visit_counter,Exploration_string.Sequential_string_data[visit_counter]);if(visit_length > max_length){max_length = visit_length;max_begin = visit_start;}//记录下一个节点开始位置, 此时visit_counter为最大平台的最后一个字符串位置visit_start = visit_counter+1;visit_length = 1;}}
}