深圳有什么网站推广公司产品文案该怎么写

当前位置: 首页 > news >正文

深圳有什么网站,推广公司产品文案该怎么写,网站做301重定向,海外音乐类网站做的比较好的目录 字符串的基本概念
字符串的三要素 字符串的基本概念 串的编码 串的实现及基本运算 顺序串的实现 串的静态数组实现 串的动态数组的实现 顺序存储的四种方案 链式串的实现 基本运算 方案三 方案一 字符串的基本概念 数据结构千千万#xff0c…目录 字符串的基本概念         字符串的三要素 字符串的基本概念 串的编码 串的实现及基本运算 顺序串的实现 串的静态数组实现 串的动态数组的实现 顺序存储的四种方案 链式串的实现 基本运算 方案三 方案一 字符串的基本概念         数据结构千千万但距离我们最近的还是字符串。在这里我们定义有限个字符组成的序列为字符串。在大多数人看来字符串仅仅是一个char类型的数组但在作者看来数组也是一种特殊的线性表。回想顺序表、顺序栈、顺序队列这些都和数组有着千丝万缕的联系。但在我们这里要讲的字符串它的格式不仅仅是数组格式数组格式只是串格式的众多种类中的一种。 我们回顾数据结构的三要素逻辑结构、物理结构和基本运算。线性表是指元素之间的逻辑结构为线性的一系列的数据结构其特点是一对一。类似的字符串各个元素之间的逻辑结构也可以视为线性因此字符串是一种特殊的线性表。 字符串的三要素 逻辑结构线性结构物理结构顺序存储/链式存储基本运算 StrCopy(T,S)复制串将串S复制到串TStrEmpty(S)串判空判断串S是否为空串StrLength(S)求串长求串S的长度ClearStr(S)清空串清空串S使其成为空串DestroyStr(S)销毁串清空串并释放其内存空间ConcatStr(T,S1,S2)串连两个串在S1串后面链接上S2成为一个串TSubString(Sub,S,pos,len)求子串求串S以pos为起点长度为len的子串StrCompare(S,T)比较串比较串S与TST则返回值大于0;ST则返回值等于0;ST则返回值小于0Index(S,T)定位子串如果主串S中存在与T相同的子串则返回主串第一次出现子串的第一个位置 上述基本操作涉及到一些串的相关名词在这里作一下定义说明没有疑问的可跳过。 字符串的基本概念 字符串有限个字符组成的序列 串长有限字符的个数n空串有限字符个数为0空格串串内所有字符均为空格例如“   ”主串和子串这是一个相对概念一般来说把一个完整的字符串当成主串而子串是从主串中任意提出来的连续字符组成的序列。 例如: aqwer1314 bqwer c1314, dwer1,在这里b c d均是a的子串 注意空串和空格串空串里面没有一个字符而空格串是包含了字符只不过这个字符是空格。 串的编码 英文字符ASCII码等。中英文字符UTF8、UTF16、GB2312等。 我们知道计算机的存储是二进制的也就是说无论什么字符其存储的数据都是二进制那么如何将二进制数与符号相对应这就是我们的编码。编码是一种规则一个二进制数通过这个规则对应表示一个字符。抽象理解成一个yf(x)的函数自变量x为二进制数编码为映射规则f因变量为字符集y。满足函数一一对应的性质。编码有多种多样的例如BCD码格雷码等。 ASCII码是我们最常用的一种编码其存储空间一般为1B。它包含了我们常见的大部分英文字符例如26个大小写英文字母数字空格等。其具体的ASCII表在网上众多我就不一一赘述了。 UTF8、UTF16、GB2312都是包含了中英文字符的编码在需要使用中文的体系中常用但需要注意的是使用这几种的人数较多较杂不像英文字符大部分人都用ASCII这几种也很多人使用因此我们在打开其他人的文件时很容易出现乱码其主要原因就是你打开打编码方式与他写的编码方式不一致。因此当遇到乱码应当及时更正打开文件的编码方式。 串的实现及基本运算 顺序串的实现 顺序串即存储结构为连续顺序的字符串和顺序表类似其构建方法一般可以分为静态数组和动态数组两种。 串的静态数组实现 #define MaxSize 100;//定义最大分配空间为100个 typedef struct{char str[MaxSize];//定义静态字符数组int length;//定义串的实际长度 }SString; 静态数组在分配得到时候固定了大小空间 串的动态数组的实现 typedef struct{char *str;int length; }HString; 动态数组只分配了数组的基址大小可自己拓展。在应用过程中拓展需要用到malloc函数同时销毁元素时也要手动free空间。 顺序存储的四种方案 方案1是最常见的格式也是一般字符串的默认格式不包含表长元素以\0作为结尾符号 方案2是我们默认使用的格式前面是串的各个字符元素最后存放表长元素 方案3是舍弃数组的第一个元素使数组下标与字符的位序对其最后存放表长元素 方案4不单独设置表长元素将串的字符数组的第一个元素存放表长数据 同时也让数组下标与字符位序对齐但表长元素的数据类型是int字符数组的数据类型是char使用中有很多需要注意因此实用性不是很好。 四个方案相较而言方案3更具有优势但方案1的普遍性更强。 链式串的实现 链式串的物理结构类似于单链表每个结点存放一组数据并指向下一个结点结构示意图 其中S是头结点从1开始才是串的实际字符数据当然采用无头结点的串也是可以的只需要注意第一个结点特殊处理就行。 typedef struct StringNode{char str;//每个结点存储一个字符struct StringNode *next;//指向下一个结点 }StringNode,*String; 一般而言我们会采用一个结点储存一个字符但有些特殊情况下需要一个结点储存固定长度的字符同时也节省空间。 typedef struct StringNode{char str[4];//每个结点存储4个字符struct StringNode *next;//指向下一个结点 }StringNode,*String; 基本运算 在讲基本操作之前我们先确定一下其串的格式物理存储格式决定这基本运算的操作思路、步骤与顺序。从编程的逻辑性和简易性而言方案三是最合适的。 但又考虑到普遍的字符串存储格式是方案一 因此我们选择在方案三的基础上完成思路和源码的讲解同时展示完整的方案一源码在源码中简单讲解。 方案三 方案三字符串结构体创建 #define MaxSize 100;//定义最大分配空间为100个 typedef struct{char str[MaxSize];//定义静态字符数组int length;//定义串的实际长度 }SString; /初始化串/ void InitString(SString S){for(int i0;iMaxSize;i)//将所有值设定为字符串终止符也可以是别的没歧义的内容S.str[i]\0;S.length0;//初始化字符串长度为0 } 复制串将串S复制得到串T void StrCopy(SString T,SString S){T.lengthS.length;for(int i1;iT.length;i){T.str[i]S.str[i];} } 串判空判断串是否为空串是返回true不是返回false bool StrEmpty(SString S){if(S.length0)//字符串长度为0则为空字符串return true;else if(S.length0)return false; } 求串长在这个格式下有点多此一举但也还是说明一下吧 int StrLength(SString S){return S.length; } 清空串使其成为空串但其实在这里没办法真的成为空毕竟空间就在那一般操作方式是给每个字符空间赋值为特殊值例如0或者\0然后修改表长。对于char数据类型建议赋值为\0对于其他int或者float建议赋值为0 void ClearString(SString S){for(int i0;iS.length;i)S.str[i]\0;S.length0; } 销毁串因为这个结构采用的是静态数组静态数组不需要手动释放空间内存会在超出变量作用域时自动释放空间。 连接串串连两个串在S1串后面连接上S2成为一个串T bool ConcatString(SString T,SString S1,SSrting S2){T.lengthS1.lengthS2.length;//拼接后的长度if(T.length1MaxSize)//判断长度是否超限return false;//长度超限拼接失败for(int i1;iS1.length;i)//将S1的数据复制到TT.str[i]S1.str[i];for(int i1;iS2.length;i)//将S2的数据复制到S1后面T.str[S1.lengthi]S2.str[i];return true;//拼接成功 } 求子串求主串S第pos位开始的长len的子串 bool SubString(SString Sub,SString S,int pos,int len){if(poslen-1S.length)//判断子串是否越界return false;//子串越界获取子串失败Sub.lengthlen;//子串长度为lenfor(int i1;ilen1;i)//读取子串并复制给SubSub.str[i]S.str[ipos-1];Sub.str[i]\0;//给子串添加终止符return true;//获取子串成功 }StrCompare(S,T)比较串比较串S与TST则返回值大于0;ST则返回值等于0;ST则返回值小于0。 有人就说了字符串怎么能比较呢这也是作者刚开始疑惑的问题字符串比什么除了能比一不一样还能干嘛所以在比较字符串之前一定要有比较的标准制定比较标准时需要注意以下三个要点 要不要考虑字符的大小写字符串的长度对于特殊字符和不同编码如何处理 下面我们先制定字符串比较的规则 比较对字符大小写敏感直接按顺序比较字符在ASCLL的码值先出现更大字符的串更大考虑字符串长度长串前缀与短串字符一致时长串更大不考虑特殊字符默认均为ASCII码 int StrCompare(SString S,SString T){//遍历查找两个字符串每个位置的字符比较情况for(int i1;iS.length iT.length;i){if(S.str[i]!T.str[i])//字符不相同则相减并返回return S.str[i]-T.str.[i];}return S.length-T.length;// } 定位子串 如果主串S中存在与T相同的子串则返回主串第一次出现子串的第一个位置。 int IndexStr(SString S,SString T){int mS.length;int nt.length;int flag;SString Sub;for(int i1;in-m1;i){/取出字符串S中长度为n的子串/if(in-1S.length)//判断子串是否越界return 0;//子串越界获取子串失败Sub.lengthn;//子串长度为nfor(int j1;jn;j)//读取子串并复制给SubSub.str[j]S.str[ji-1];/比较T与S的子串Sub/for(int j1;jS.length jT.length;j){if(S.str[j]!Sub.str[j])flagT.str[j]-Sub.str[j];}flagS.length-T.length;/判断两串是否相等/if(flag0)return i;}return 0;//没有到与T相等的子串 } 上述代码中有求子串和比较子串的操作我们采用源码表示但也可以直接用函数 int IndexStr(SString S,SString T){int mS.length;int nt.length;bool flag;SString Sub;for(int i1;in-m1;i){/取出字符串S中长度为n的子串/flagSubString(Sub,S,i,n);if(flagfalse)return 0;//子串违法/判断两串是否相等/if(StrCompare(T,Sub)0)return i;}return 0;//没有到与T相等的子串 } 方案一 方案一是最常见的字符串类型例如 char str[]qwer1314; 这种方式不需要结构体同时也是我们在大多数场合输入字符串的默认格式因此在这里我们再次进行代码讲解 /将字符串S复制给T/ void StrCopy(char *S,char *T){int i0;while(S[i]!\0){T[i]S[i];i;}T[i]\0; } /判定字符串S是否为空/ bool StrEmpty(char *S){if(S[0]\0)return true;elsereturn false; } /求字符串S的长度/ int StrLength(char *S){int len0;while(S[len]!\0){len;}return len; } /清空字符串/ void ClearString(char *S){int i0;while(S[i]!\0){S[i]\0;i;} } /串联两个字符串/ char *ConcatStr(const char *str1, const char *str2) {// 检查输入是否为NULLif (str1 NULL || str2 NULL) {return NULL;}// 计算新字符串的长度int len1 StrLength(str1);int len2 StrLength(str2);int newLen len1 len2 1; // 分配内存char *result (char *)malloc(newLen * sizeof(char));if (result NULL) {// 内存分配失败return NULL;}// 复制第一个字符串到结果中int i 0;while (i len1) {result[i] str1[i];i;}// 连接第二个字符串到结果中int j 0;while (j len2) {result[i j] str2[j];j;}// 添加终止符result[i j] \0;return result; } /求子串/ char *SubString(char *str, int pos, int len) {int length StrLength(str);if (pos len length || pos 0 || len 0) {return NULL; // 检查边界条件}// 分配内存char *result (char *)malloc((len 1) * sizeof(char));if (result NULL) {return NULL; // 检查内存分配是否成功}for (int i 0; i len; i) {result[i] str[pos i];}result[len] \0; // 添加字符串结束符return result; } /比较字符串/ int Strcompare(char *str1,char *str2){int len1StrLength(str1),len2StrLebgth(str2);for(int i0;ilen1 ilen2;i){if(str1[i]!str2[i])return str1[i]-str2[i];}return len1-len2; } /定位字符串/ int Index(char *str1,char *str2){int mStrLength(str1);int nStrLength(str2);bool flag;char *Sub;for(int i1;in-m1;i){/取出字符串S中长度为n的子串/SubSubString(S,i,n);if(flagNULL)return 0;//子串违法/判断两串是否相等/if(StrCompare(S,Sub)0)return i;}return 0;//没有到与T相等的子串 } 常见字符串操作 将字符串转换成int //字符串转化为int int string_int(char *str) {if (str NULL || *str \0) {// 输入为空或空字符串return 0;}int num 0;int i 0;int flag 1;// 检查负号if (str[i] -) {flag -1;i;}// 转换数字部分while (str[i] 0 str[i] 9) {int digit str[i] - 0;// 检查是否会发生溢出if (num (INT_MAX - digit) / 10) {// 发生溢出返回0或其他错误值return 0;}num num * 10 digit;i;}return flag * num; } 将int转化为字符串 char *int_string(int num) {// 假设整数最多有11位包括负号char *str (char *)malloc(12 * sizeof(char)); // 分配内存用于存储转换后的字符串if (str NULL) {return NULL; // 如果内存分配失败返回NULL}int i 0; // 用于记录当前字符的位置int isNegative 0; // 标记是否为负数if (num 0) {isNegative 1; // 如果是负数设置标记并取绝对值num -num;}// 将数字转换为字符串do {stri 0; // 将最低位的数字转换为字符并存储num / 10; // 去掉已经处理的最低位} while (num 0);if (isNegative) {str[i] -; // 如果是负数添加负号}// 反转字符串for (int j 0; j i / 2; j) { // 注意这里需要声明j的类型为intchar temp str[j];str[j] str[i - j - 1];str[i - j - 1] temp;}// 添加字符串终止符str[i] \0;return str; // 返回转换后的字符串 }将字符串转换成float // 将字符串转换为浮点数的函数 float string_float(char *str) {// 如果输入为空或空字符串返回0.0fif (str NULL || *str \0) {return 0.0f;}// 初始化变量float num 0.0f; // 最终结果int i 0; // 当前字符索引int flag 1; // 符号标志1表示正数-1表示负数int fractional_part 0; // 是否处理小数部分的标志float fractional_divisor 1.0f; // 小数部分的除数// 检查负号if (str[i] -) {flag -1;i;}// 转换数字部分和小数部分while (str[i] ! \0) {if (str[i] 0 str[i] 9) {int digit str[i] - 0; // 将字符转换为数字if (fractional_part) {// 处理小数部分fractional_divisor * 10.0f;num digit / fractional_divisor;} else {// 处理整数部分if (num (FLT_MAX - digit) / 10.0f) {// 发生溢出返回0或其他错误值return 0.0f;}num num * 10.0f digit;}} else if (str[i] . !fractional_part) {// 遇到小数点开始处理小数部分fractional_part 1;} else {// 非法字符直接返回当前结果break;}i;}// 返回最终结果考虑符号return flag * num; }将float转换为字符串 // 将浮点数转换为字符串的函数 char *float_string(float num) {// 假设浮点数最多有38位包括负号、小数点和指数char *str (char *)malloc(40 * sizeof(char)); // 分配内存用于存储转换后的字符串if (str NULL) {return NULL; // 如果内存分配失败返回NULL}int i 0; // 用于记录当前字符的位置int isNegative 0; // 标记是否为负数if (num 0) {isNegative 1; // 如果是负数设置标记并取绝对值num -num;}// 处理整数部分int integerPart (int)num; // 获取整数部分do {stri 0; // 将整数部分逐位转换为字符并存储integerPart / 10; // 去掉已经处理的最低位} while (integerPart 0);if (isNegative) {str[i] -; // 如果是负数添加负号}// 反转整数部分使其按正确顺序排列for (int j 0; j i / 2; j) {char temp str[j];str[j] str[i - j - 1];str[i - j - 1] temp;}// 添加小数点str[i] .;// 处理小数部分float fractionalPart num - (int)num; // 获取小数部分int precision 6; // 设置精度为6位小数for (int k 0; k precision; k) {fractionalPart * 10; // 将小数部分放大10倍int digit (int)fractionalPart; // 获取当前最高位的小数str[i] digit 0; // 将小数转换为字符并存储fractionalPart - digit; // 去掉已经处理的最高位小数}// 添加字符串终止符str[i] \0;return str; // 返回转换后的字符串 }