总结一些相关的算法,并进行了分类。如有错误或更好的解决方法,望能留言指出。
一、字符串
1.全排列算法
思路一:
(1)n个元素的全排列=(n-1个元素的全排列)+(另一个元素作为前缀);
(2)出口:如果只有一个元素的全排列,则说明已经排完,则输出数组;
(3)不断将每个元素放作第一个元素,然后将这个元素作为前缀,并将其余元素继续全排列,等到出口,出口出去后还需要还原数组;
思路二:全排列就是从第一个数字起每个数分别与它后面的数字交换。
思路三:
下面是具体的代码实现:
//全排列的递归实现 #include <stdio.h> #include <string.h> void Swap(char *a, char *b) { char t = *a; *a = *b; *b = t; } //k表示当前选取到第几个数,m为最后一个数的索引. void AllRange(char *pszStr, int k, int m) { if (k == m) { static int s_i = 1; printf(" 第%3d个排列 %s ", s_i++, pszStr); } else { for (int i = k; i <= m; i++) //第i个数分别与它后面的数字交换就能得到新的排列 { Swap(pszStr + k, pszStr + i); AllRange(pszStr, k + 1, m); Swap(pszStr + k, pszStr + i); } } } void Foo(char *pszStr) { AllRange(pszStr, 0, strlen(pszStr) - 1); } int main() { printf(" 全排列的递归实现 "); char szTextStr[] = "123"; printf("%s的全排列如下: ", szTextStr); Foo(szTextStr); return 0; }
但是,我们会发现,这样写以后,如果字符串中有重复的元素,则全排列也会有重复的,所以我们需要加个去重的处理:(AllRange方法中)
交换之前判断是否相同,相同则不作交换。
完善后的代码:
//去重全排列的递归实现 #include <stdio.h> #include <string.h> void Swap(char *a, char *b) { char t = *a; *a = *b; *b = t; } //在pszStr数组中,[nBegin,nEnd)中是否有数字与下标为nEnd的数字相等 bool IsSwap(char *pszStr, int nBegin, int nEnd) { for (int i = nBegin; i < nEnd; i++) if (pszStr[i] == pszStr[nEnd]) return false; return true; } //k表示当前选取到第几个数,m为最后一个数的作引 void AllRange(char *pszStr, int k, int m) { if (k == m) { static int s_i = 1; printf(" 第%3d个排列 %s ", s_i++, pszStr); } else { for (int i = k; i <= m; i++) //第i个数分别与它后面的数字交换就能得到新的排列 { if (IsSwap(pszStr, k, i)) { Swap(pszStr + k, pszStr + i); AllRange(pszStr, k + 1, m); Swap(pszStr + k, pszStr + i); } } } } void Foo(char *pszStr) { AllRange(pszStr, 0, strlen(pszStr) - 1); } int main() { printf(" 去重全排列的递归实现 "); char szTextStr[] = "122"; printf("%s的全排列如下: ", szTextStr); Foo(szTextStr); return 0; }
2.字符串转int
整数的溢出问题,MAX表示的是最大值2147483647的16进制表示,MIN表示的是最小负值-2147483648的16进制表示 #define kIntMAX ((int)0x7FFFFFFF) #define kIntMIN ((int)0x80000000) //字符串转int /* 通过试系统的atoi函数,总结了下规则: 1.开头只能为数字、正负号、空格(tab制表符、换行、回车) 2.正负号之后必须为数字,否则退出 3.数字开始之后必须为数字,出现其他字符则退出。 错误处理: 1.NULL或空字符串(""),返回0 2.溢出则返回-1 */ int myatoi(const char * str) { bool negative=false;//是否为负数 unsigned long result=0; const char *pCurrent = str; //判空处理 if ((pCurrent == NULL) || (*pCurrent == '