基础算法——字符串
/************************************************************************* > File Name: string.cpp > Author: xinyang > Mail: xuechen.xy@gmail.com > Created Time: Tue 06 Oct 2015 10:16:36 PM CST ************************************************************************/ #include <iostream> #include <string> #include <cstring> #include <algorithm> #include <stack> #include <queue> using namespace std; /* * 将字符串中所有的空格全部换成%20 */ void replace_blank(char str[], int len) { if (str == NULL) { cout << "null string" << endl; return; } int org_len = 0, blank_num = 0, new_len = 0; for (int i = 0; str[i] != '\0'; ++i) { if (str[i] == ' ') { ++blank_num; } ++org_len; } new_len = org_len + 2 * blank_num; if (new_len > len) { cout << "overflow" << endl; return; } int idx_org = org_len - 1, idx_new = new_len - 1; while (idx_org >= 0 && idx_new > idx_org) { if (str[idx_org] == ' ') { str[idx_new--] = '0'; str[idx_new--] = '2'; str[idx_new--] = '%'; } else { str[idx_new--] = str[idx_org]; } --idx_org; } } /* * 打印1到最大的n位数(n = 3,则输出1, 2, ..., 999) */ void print_number(char *number) { bool is_begin = false; for (int i = 0; number[i] != '\0'; ++i) { if (is_begin == false && number[i] != '0') { is_begin = true; } if (is_begin == true) { cout << number[i]; } } cout << '\t'; } bool increment(char *number) { bool is_overflow = false; int c = 0; int len = strlen(number); for (int i = len - 1; i >= 0; --i) { int sum = number[i] - '0' + c; if (i == len - 1) { ++sum; } if (sum >= 10) { if (i == 0) { is_overflow = true; } else { sum -= 10; c = 1; number[i] = sum + '0'; } } else { number[i] = sum + '0'; break; } } return is_overflow; } void print_max_n_digits(int n) { if (n <= 0) { return; } char *number = new char[n + 1]; memset(number, '0', n); number[n] = '\0'; while (!increment(number)) { print_number(number); } delete number; number = NULL; } /* * 字符串全排列 */ void permutation(char *string, char *begin) { if (*begin == '\0') { cout << string << endl; } else { for (char *ch = begin; *ch != '\0'; ++ch) { char tmp = *ch; *ch = *begin; *begin =tmp; permutation(string, begin + 1); tmp = *ch; *ch = *begin; *begin = tmp; } } } void permutation(char *string) { if (string == NULL) { return; } permutation(string, string); } /* * 只出现一次的字符 */ char first_not_repeate_char(char *string) { if (string == NULL) { return '\0'; } int *hash = new int[256]; for (int i = 0; i < 256; ++i) { hash[i] = 0; } for (int i = 0; string[i] != '\0'; ++i) { ++hash[string[i]]; } for (int i = 0; i < 256; ++i) { if (hash[i] == 1) { return i; } } } /* * 字符串转整数 */ int str_to_int_core(const char *digits, bool minus) { long long num = 0; while (*digits != '\0') { if (*digits >= '0' && *digits <= '9') { int flag = minus ? -1 : 1; num = num * 10 + flag * (*digits - '0'); if ((!minus && num > 0x7fffffff) || (minus && num <= (signed int)0x80000000)) { num = 0; break; } ++digits; } else { num = 0; break; } } return num; } int str_to_int(const char *string) { long long num = 0; if (string == NULL || *string == '\0') { return num; } bool minus = false; if (*string == '+') { ++string; } else if (*string == '-') { ++string; minus = true; } if (*string == '\0') { return num; } num = str_to_int_core(string, minus); return (int)num; } /* * 数值的整数次方 */ bool equal(double num1, double num2) { if ((num1 - num2 > -0.00000001) || (num1 - num2 <= 0.00000001)) { return true; } else { return false; } } double power_iter(double base, int exponent) { double result = 1.0; for (int i = 1; i <= exponent; ++i) { result *= base; } return result; } double power_recur(double base, int exponent) { if (exponent == 0) { return 1.0; } if (exponent == 1) { return base; } double result = power_recur(base, exponent >> 1); result *= result; if (exponent & 0x1 == 1) { result *= base; } return result; } double power(double base, int exponent) { if (equal(base, 0.0) && exponent < 0) { return 0.0; } unsigned int abs_exponent = (unsigned int)(exponent); if (exponent < 0) { abs_exponent = -exponent; } double result = power_iter(base, abs_exponent); if (exponent < 0) { return 1.0 / result; } return result; } /* * 翻转字符串 "I love you" -> "you love I" */ void reverse(char *pBegin, char *pEnd) { if (pBegin == NULL || pEnd == NULL) { return; } while (pBegin < pEnd) { char tmp = *pBegin; *pBegin = *pEnd; *pEnd = tmp; ++pBegin; --pEnd; } } char *reverse_sentence(char *string) { if (string == NULL) { return NULL; } char *pBegin = string; char *pEnd = string; while (*pEnd != '\0') { ++pEnd; } --pEnd; reverse(pBegin, pEnd); pBegin = pEnd = string; while (*pBegin != '\0') { if (*pBegin == ' ') { ++pBegin; ++pEnd; } else if (*pEnd == ' ' || *pEnd == '\0') { reverse(pBegin, --pEnd); pBegin = ++pEnd; } else { ++pEnd; } } return string; } /* * 字符串是否包含另外一个子字符串 */ bool contains1(const char *string, const char *substring) { if (string == NULL || substring == NULL) { return false; } int m = strlen(string); int n = strlen(substring); if (m < n) { return false; } for (int i = 0; i <= m - n; ++i) { int j = 0; for (; j < n; ++j) { if (string[i + j] != substring[j]) { break; } } if (j == n) { return true; } } return false; } /* * KMP */ void compute_prefix(int *next, char *p) { int i, n, k; n = strlen(p); next[1] = next[0] = 0; k = 0; /* 第i次迭代开始之前,k表示next[i-1]的值 */ for (i = 2; i <= n; i++) { for (; k != 0 && p[k] != p[i-1]; k = next[k]) { ; } if (p[k] == p[i-1]) { k++; } next[i] = k; } } void kmp_match(char *text, char *p, int *next) { int m, n, s, q; m = strlen(p); n = strlen(text); q = s = 0; /* q表示上一次迭代匹配了多少个字符, s表示这次迭代从text的哪个字符开始比较 */ while (s < n) { for (q = next[q]; q < m && p[q] == text[s]; q++, s++) { ; } if (q == 0) { s++; } else if (q == m) { cout << "pattern occurs with shift " << s-m << endl; } } } int main() { cout << "replace blank" << endl; char str1[] = "I love you. haha"; cout << "before: " << str1 << endl; replace_blank(str1, 100); cout << "after: " << str1 << endl; cout << "print max n digits" << endl; print_max_n_digits(3); cout << endl << endl; cout << "permutation" << endl; char str2[] = "abcd"; permutation(str2); cout << endl << endl; cout << "first not repeated character" << endl; char str3[] = "xaabbccd"; cout << first_not_repeate_char(str3) << endl << endl; cout << "string to integer" << endl; char str4[] = "1234"; cout << str_to_int(str4) << endl << endl; cout << "power" <<endl; cout << power(2, 30) << endl << endl; cout << "reverse a sentence" << endl; char str5[] = "I love you"; cout << reverse_sentence(str5) << endl << endl; if (true == contains1("I love you", "love")) { cout << "string contains substring" << endl << endl; } else { cout << "string not contains substring" << endl << endl; } cout << "KMP" << endl; int next[101]; char p[] = "ababacb"; char text[] = "abababaababacb"; compute_prefix(next, p); kmp_match(text, p, next); return 0; }