字符串算法
- 字符串翻转
- 字符串旋转
- 数字转字符串
- 字符串转数字
- 回文字符串判断
- 字符串包含
- 字符串删除
- 字符串哈希
字符串翻转
第一种方法:
#include#include <string.h> char * reverse(char *s ,int len, char *str) { int i=0; for(;i ) { str[i] = s[len-1-i]; } return str; } int main () { char str[12] = "Hello"; int len; len = strlen(str); printf("初始字符串:%s\n",str); char str1[len]; reverse(str,len,str1); printf("翻转后的字符串:%s",str1); return 0; }
第二种方法:
#include#include <string.h> char *reverse(char *s) { char t, *p = s,*q = (s + (strlen(s) - 1)); while (p < q) { t = *p; *p++ = *q; *q-- = t; } return(s); } int main() { char str[] = "abcdefw"; printf("初始字符串:'%s'\n",str); printf("翻转后的字符串:'%s'\n", reverse(str)); return 0; }
字符串旋转
旋转分为左移和右移。
#include#include <string.h> void left(char *s ,int len) { char t = s[0]; int i; for (i = 1;i ) { s[i-1] = s[i]; } s[len-1] = t; } void right(char *s ,int len) { char t = s[len-1]; int i; for (i = len - 1;i>0;i--) { s[i] = s[i-1]; } s[0] = t; } int main () { char str1[12] = "Hello"; char str2[12] = "world"; int len1,len2 ; len1 = strlen(str1); len2 = strlen(str2); //开始左移位字符串 printf("初始字符串:%s\n",str1); int i = 0; for(;i ) { left(str1,len1); printf("第%d次移位字符串的结果:%s\n",i+1,str1); } //开始右移位字符串 printf("初始字符串:%s\n",str2); i = 0; for(;i ) { right(str2,len2); printf("第%d次移位字符串的结果:%s\n",i+1,str2); } return 0; }
数字转字符串
#include#include <string.h> //数字转换为字符串 char* hitoa(char *a,int num, int len) { int temp; int ti = num; int i = 0, j = 0; while (ti) { a[i] = ti%10 + '0'; //取最后一个数,并转换成ASCII编码值保存到字符数组中 i++; //向后移动一位,保存下一个字符 ti /= 10; //取得已经去掉几位的整数 } a[i] = '\0'; //这里一定要记住最后的'\0' i -= 1; //这里i也要注意是到最后一个非'\0'字符进行反转 for (; j < i;) { //把得到的字符串反转一下 temp= a[i]; a[i--] = a[j]; a[j++] = temp; } return a; } //计算数字位数 int Count(n){ int total = 0; while(n) { n /= 10; ++total; } return total; } int main() { int n = 2324332; int count = Count(n); printf("%d为:%d位数\n",n,count); char str[count]; hitoa(str,n,count); printf("转换后的字符串:%s\n", str); return 0; }
字符串转数字
#include#include <string.h> #define MaxValue 2147483647 #define MinValue -2147483648 int StringToint32(char s[]) { //检测字符串是否为空 if (strlen(s) == 0) { return 0; } int value = 0; //存储最后的数字 int i = 0; //字符串下标 //检测正负标记 int sign = 1; //sign为数字正负标记,sign>0为正,反之为负,默认为正。 if (s[0] == '+' || s[0] == '-') { if (s[0] == '-') sign = -1; i++; //当存在标记,则从下标为1的位置开始 } while (i < strlen(s)) { int c = s[i] - '0'; //当前的数字 //当发生正溢出时,返回最大值,int类型最大值为2147483647 if (sign > 0 && (value > MaxValue / 10 || (value == MaxValue / 10 && c >= MaxValue % 10))) { value = MaxValue; break; } //当发生负溢出时,返回最小值,int类型最小值为-2147483648 else if (sign < 0 && (value > -(MinValue / 10) || (value == -(MinValue / 10) && c >= -(MinValue % 10)))) { value = MinValue; break; } //转换字符串 value = value * 10 + c; i++; } return sign > 0? value: value == MinValue ? value : -value; } int main () { char str1[] = "-4242342"; printf("%d\n",StringToint32(str1)); char str2[] = "3234"; printf("%d\n",StringToint32(str2)); return 0; }
回文字符串判断
#include#include <string.h> int reverse(char *s) { if(strlen(s) == 1 || strlen(s) == 0){ return 3; } char t, *p = s,*q = (s + (strlen(s) - 1)); while (p < q) { if(*p++ == *q--) { continue; } else { return 0; } } return 1; } int main() { char str[] = "ma3d3ma"; int bool = reverse(str); printf("%d",bool); return 0; }
字符串包含
给定两个分别由字母组成的字符串 s1 和字符串 s2,如何最快地判断字符串 s2 中所有字母是否都在字符串 s1 里?
#include#include <string.h> int IsContainAllChars(char a[], char b[]) { int hash = 0; int lena = strlen(a),lenb = strlen(b); for (int i = 0; i < lena; ++i) { hash |= (1 << (a[i] - 'A')); } for (int i = 0; i < lenb; ++i) { if ((hash & (1 << (b[i] - 'A'))) == 0) { return 0; } } return 1; } int main () { char a[] = "aadwada"; char b[] = "dw"; int sign = IsContainAllChars(a,b); printf("%d",sign); return 0; }
字符串删除
在s1字符串中删除掉s2字符串中出现的每一个元素。
#include#include <string.h> void del_sub(char *str, char *sub) { char *p; int i, j; int asc[128] = {0}; //假设都是ACSII字符 for (p = sub; *p != '\0'; p++) { //先给要删除的字符设置位1 asc[*p] = 1; } for (i = 0, j = 0; i < strlen(str); i++) { //遍历母串,把不删的字符复制给母串, if (!asc[str[i]]) { //不需要临时空间。 str[j] = str[i]; //注意遍历时,是strlen而不用减1了,细心点。 j++; } } str[j] = '\0'; //这里要记住 } int main () { char str1[] = "abc123"; char str2[] = "c3"; del_sub(str1,str2); printf("%s",str1); return 0; }
字符串哈希
原文网址
常用的字符串Hash函数还有ELFHash,APHash等等,都是十分简单有效的方法。这些函数使用位运算使得每一个字符都对最后的函数值产生影响。另外还有以MD5和SHA1为代表的杂凑函数,这些函数几乎不可能找到碰撞。常用字符串哈希函数有BKDRHash,APHash,DJBHash,JSHash,RSHash,SDBMHash,PJWHash,ELFHash等等。
//SDBMHash unsigned int SDBMHash(char *str) { unsigned int hash = 0; while (*str) { // equivalent to: hash = 65599*hash + (*str++); hash = (*str++) + (hash << 6) + (hash << 16) - hash; } return (hash & 0x7FFFFFFF); } // RS Hash Function unsigned int RSHash(char *str) { unsigned int b = 378551; unsigned int a = 63689; unsigned int hash = 0; while (*str) { hash = hash * a + (*str++); a *= b; } return (hash & 0x7FFFFFFF); } // JS Hash Function unsigned int JSHash(char *str) { unsigned int hash = 1315423911; while (*str) { hash ^= ((hash << 5) + (*str++) + (hash >> 2)); } return (hash & 0x7FFFFFFF); } // P. J. Weinberger Hash Function unsigned int PJWHash(char *str) { unsigned int BitsInUnignedInt = (unsigned int)(sizeof(unsigned int) * 8); unsigned int ThreeQuarters = (unsigned int)((BitsInUnignedInt * 3) / 4); unsigned int OneEighth = (unsigned int)(BitsInUnignedInt / 8); unsigned int HighBits = (unsigned int)(0xFFFFFFFF) << (BitsInUnignedInt - OneEighth); unsigned int hash = 0; unsigned int test = 0; while (*str) { hash = (hash << OneEighth) + (*str++); if ((test = hash & HighBits) != 0) { hash = ((hash ^ (test >> ThreeQuarters)) & (~HighBits)); } } return (hash & 0x7FFFFFFF); } // ELF Hash Function unsigned int ELFHash(char *str) { unsigned int hash = 0; unsigned int x = 0; while (*str) { hash = (hash << 4) + (*str++); if ((x = hash & 0xF0000000L) != 0) { hash ^= (x >> 24); hash &= ~x; } } return (hash & 0x7FFFFFFF); } // BKDR Hash Function unsigned int BKDRHash(char *str) { unsigned int seed = 131; // 31 131 1313 13131 131313 etc.. unsigned int hash = 0; while (*str) { hash = hash * seed + (*str++); } return (hash & 0x7FFFFFFF); } // DJB Hash Function unsigned int DJBHash(char *str) { unsigned int hash = 5381; while (*str) { hash += (hash << 5) + (*str++); } return (hash & 0x7FFFFFFF); } // AP Hash Function unsigned int APHash(char *str) { unsigned int hash = 0; int i; for (i=0; *str; i++) { if ((i & 1) == 0) { hash ^= ((hash << 7) ^ (*str++) ^ (hash >> 3)); } else { hash ^= (~((hash << 11) ^ (*str++) ^ (hash >> 5))); } } return (hash & 0x7FFFFFFF); }