1. 字符串转化为整型
int charToInt(const char* str)
{
if (str == NULL) return 0;
int flag = 1;
if ( *str == '+' )
{
++str;
} else if (*str == '-')
{
flag = -1;
++str;
}
int n = 0;
while ( *str != '\0' )
{
if ( *str < '0' || *str > '9' )
return -9999; //非法字符,提示错误码
n = n*10 + (*str - '0');
++str;
}
return n*flag;
}
2. 整型转化为字符串
方法一: (自己实现的)
char* IntToChar(int num, char* str)
{
int m = num;
int count = 0;
if (num < 0)
{
m = -num;
++count; //负数,多一个'-'号
}
int n = m;
while (m != 0)
{
m = m/10;
++count;
}
*(str+count) = 0;
int start = 0;
if (num < 0)
{
*str = '-';
start = 1;
}
while(count > start)
{
*(str + (--count)) = '0' + n%10;
n /= 10;
}
return str;
}
方法二:(用snprintf实现,可跨平台)
char* myitoa(int num, char* str)
{
if (str == NULL)
return NULL;
int ret = 0;
ret = _snprintf(str, 10, "%d", num);
str[ret] = 0;
return str;
}
注:windows和linux上snprintf有一点差异
3. 十进制转化为十六进制
void Dec2Hex(int dec, char* hex)
{
int n = dec;
char tmp[16] = {0};
int i = 0;
for (; n != 0; i++)
{
int remain = n%16;
if (remain < 10)
{
tmp[i] = '0' + remain;
}
else
{
tmp[i] = 'a' + (remain - 10);
}
n = n/16;
}
int k = 0;
for (int j = i - 1; j >= 0; j--, k++)
{
hex[k] = tmp[j];
}
hex[k+1] = 0;
}
4. 十六进制转化为十进制
void Hex2Dec(const char* hex, int &dec)
{
dec = 0;
int len = strlen(hex);
for (int i = 0, j = len - 1; j >= 0; i++,j--)
{
int value = 0;
if (hex[j] >= '0' || hex[j] <= '9')
{
value = hex[j] - '0';
}
else if (hex[j] >= 'A' || hex[j] <= 'F')
{
value = hex[j] - 'A';
}
else if (hex[j] >= 'a' || hex[j] <= 'f')
{
value = hex[j] - 'a';
}
dec += value*pow(16.0, i);
}
}
5.字符串操作函数
char* strcpy(char* des, const char* src)
{
assert(des != NULL && src != NULL);
char* tmp = des;
while ( (*tmp++ = *src++) != '\0' ) ;
return des;
}
int strcmp(const char* str1, const char* str2)
{
int ret = 0;
while( !( ret = *(unsigned char*)str1 - *(unsigned char*)str2) && *str2)
++str1, ++str2;
if (ret > 0)
return 1;
else if(ret < 0)
return -1;
return ret;
}
char* strcat(char* dest, const char* src)
{
if (src == NULL)
return dest;
char* tmp = dest;
while( *tmp++ != '\0' )
;
tmp--;
while ( (*tmp++ = *src++) != '\0')
;
return dest;
}
char* mystrstr(const char* str, const char* strSearch)
{
if (NULL == str || NULL == strSearch)
return NULL;
int findIndex = -1;
for (int i = 0; i < strlen(str); i++)
{
if ( *(str+i) == *strSearch )
{
int k = i+1;
bool bIsStringSame = true;
for (int j = 1; j < strlen(strSearch); j++, k++)
{
if ( *(str+k) != *(strSearch+j) )
{
bIsStringSame = false;
break;
}
}
if (bIsStringSame)
{
findIndex = i;
break;
}
}
}
if (findIndex == -1)
{
return NULL;
}
else
{
return const_cast<char*>(&str[findIndex]);
}
}
bool strsubstr(char *s, char *sub) /* 字符串子串查找,如果子串sub在s中存在,则返回1,否则返回0 */
{
bool result = 0;
/* 代码在这里实现 */
if ( s == NULL || sub == NULL)
return result;
char start = *sub;
while (*s != '\0')
{
if (*s == start)
{
s++;
sub++;
while ( *sub != '\0' && *s != '\0' && *s == *sub )
{
s++;
sub++;
}
if (*sub == '\0')
{
result = 1;
break;
}
}
s++;
}
return result;
}
6.求1~100以内素数 (简单算法)
bool IsPrimeNumber(int n)
{
if(n < 2) return false;
int i = 2;
for ( ;i < sqrt((float)n); i++)
{
if (n%i == 0)
break;
}
if (i > sqrt((float)n))
return true;
return false;
}
for (int i = 1; i <= 100; i += 2)
{
if (IsPrimeNumber(i)) printf("%d ", i);
}
7.求两个数的最大公约数
辗转相除法:循环相除,用较大数除以较小数,余数如果不为0,则余数作为下一次的除数,除数作为下一次的被除数,直到余数为0。那么最后一次预算的除数就是最大公约数。
int GetMaxCommonDivisor(int a, int b)
{
//先找出较大数和较小数
int bigger = a > b ? a:b;
int smaller = a < b ? a:b;
a = bigger;
b = smaller;
int tmp = 0;
while (b != 0)
{
tmp = b;
b = a%b;
a = tmp;
}
return tmp;
}
递归求法:
int GetMaxDivisor(int a, int b)
{
int bigger = a > b ? a:b;
int smaller = a < b ? a:b;
if (bigger%smaller == 0)
return smaller;
else
return GetMaxDivisor(smaller, bigger%smaller);
}
8.求两个数的最小公倍数
求法:先求这两个数的最大公约数,最小公倍数 = 两数的乘积 / 最大公约数
int GetMinMultiple(int a, int b)
{
int maxDivisor = GetMaxCommonDivisor(a,b);
return a*b/maxDivisor;
}
9.二叉树的遍历与深度
二叉树的遍历
struct BTNode
{
int data;
BTNode *lchild;
BTNode *rchild;
};
//前序遍历
void Before_Traversal(BTNode* root)
{
if (root == NULL)
return ;
printf("%d ", root->data);
Before_Traversal(root->lchild);
Before_Traversal(root->rchild);
}
//中序遍历
void Middle_Traversal(BTNode* root)
{
if (root == NULL)
return ;
Middle_Traversal(root->lchild);
printf("%d ", root->data);
Middle_Traversal(root->rchild);
}
//后序遍历
void After_traversal(BTNode* root)
{
if (root == NULL)
return ;
After_traversal(root->lchild);
After_traversal(root->rchild);
printf("%d ", root->data);
}
求二叉树的深度
int GetBTreeDeep(BTNode* root)
{
if (root == NULL)
return 0;
int a = GetBTreeDeep(root->lchild);
int b = GetBTreeDeep(root->rchild);
return (a>b)?(a+1):(b+1);
}
10. 将两个顺序排列的数组a,b合并为一个数组,合并后依然有序
void MyLinkFunc(int* a,int n,int* b,int m,int* c) //n,m为数组a,b的长度
{
int i = 0;
int j = 0;
for (; i < n && j < m ;)
{
*c++ = (a[i] < b[j]) ? a[i++] : b[j++];
}
while (i < n)
{
*c++ = a[i++];
}
while (j < m)
{
*c++ = b[j++];
}
}
类似的算法:两个有序链表a,b。将他们俩合并为一个链表,合并之后链表还是有序的
struct Node
{
int data;
Node* next;
};
Node* Merge2OneSeqList(Node* list1, Node* list2)
{
if (list1 == NULL) return list2;
if (list2 == NULL) return list1;
Node* head = NULL;
Node* p1 = list1;
Node* p2 = list2;
if (p1->data < p2->data)
{
head = list1;
p1 = p1->next;
p2 = p2;
}
else
{
head = list2;
p1 = p1;
p2 = p2->next;
}
Node* pCur = head;
while (p1 != NULL && p2 != NULL)
{
if (p1->data < p2->data)
{
pCur->next = p1;
pCur = p1;
p1 = p1->next;
}
else
{
pCur->next = p2;
pCur = p2;
p2 = p2->next;
}
}
if ( p1 != NULL )
pCur->next = p1;
if ( p2 != NULL )
pCur->next = p2;
return head;
}
另一种解法:(递归)
Node* Merge2OneSeqList(Node* list1, Node* list2)
{
if (list1 == NULL) return list2;
if (list2 == NULL) return list1;
Node* head = NULL;
if (list1->data < list2->data)
{
head = list1;
head->next = Merge2OneSeqList(list1->next, list2);
}
else
{
head = list2;
head->next = Merge2OneSeqList(list1, list2->next);
}
return head;
}
10. 将两个顺序排列的数组a,b合并为一个数组,合并后依然有序
//冒泡排序
void BubbleSort(int arr[], int n)
{
int tmp;
for (int i = 0; i < n - 1; i++)
{
for (int j = i + 1; j < n; j++)
{
if (arr[j] < arr[j-1])
{
tmp = arr[j];
arr[j] = arr[j-1];
arr[j-1]= tmp;
}
}
}
}
//快速排序
int Partition(int arr[], int low, int high);
void QuickSort(int arr[], int low, int high)
{
int temp;
if (low < high)
{
temp = Partition(arr, low, high);
QuickSort(arr, low, temp-1);
QuickSort(arr, temp+1, high);
}
}
int Partition( int arr[], int low, int high )
{
int pivot = arr[low];
int temp;
while (low < high)
{
while(low < high && arr[high] > pivot)
{
--high;
}
temp = arr[high];
arr[high] = arr[low];
arr[low] = temp;
while(low < high && arr[low] < pivot)
{
++low;
}
temp = arr[high];
arr[high] = arr[low];
arr[low] = temp;
}
return low;
}
11.一天的24小时之中,时钟的时针、分针和秒针完全重合在一起的时候有几次,怎么计算
int _tmain(int argc, _TCHAR* argv[])
{
int nSecPos = 0;
int nMinPos = 0;
int nHourPos = 0;
int count = 0;
int nSec = 0;
int nMin = 0;
int nHour = 0;
for (int i = 1; i <= SECONDS_ONE_DAY; i++ )
{
nSecPos = i%60;
nMinPos = i/60;
//先求hour
nHourPos = nMinPos/12;
if (nHourPos >= 60)
{
nHourPos = nHourPos%60;
}
if (nMinPos >= 60)
{
nMinPos = nMinPos%60;
}
if (nSecPos == nMinPos && nMinPos == nHourPos)
{
nSec = i%60;
nMin = (i/60)%60;
nHour = (i/60)/60;
printf("%d:%d:%d--%d--Hour=%d,Min=%d,Sec=%d\n",nHour,nMin,nSec, i, nHourPos, nMinPos, nSecPos);
count++;
}
}
printf("count=%d\n", count); //总共有多少次
return 0;
}
11. 约瑟夫问题
(1).利用数组解法
//输入: num 表示数组元素个数
// start 表示报数起始位置
// dis 表示报数间隔数
void Josephus(int A[], int num, int start, int dis)
{
if (dis == 0)
{
printf("dis==0 is invalid.\n");
return;
}
int i,j,k;
int tmp = 0;
//初始化数组
for (i = 0; i < num; i++)
{
A[i] = i+1;
}
i = start-1; //报数起始下标
for (k = num; k > 1; k--)
{
if (i==k) i = 0; //如果报数下标还留在尾部+1位置,则回到数组0位置
i = (i + dis - 1)%k; //寻找出句位置
if (i != k - 1) //如果出局数不在末尾,则把其移动到最后,其他元素向前移动一位。如果在末尾则不用动。
{
tmp = A[i];
for ( j = i; j < k - 1; j++) A[j] = A[j+1];
A[j] = tmp;
}
}
for (k = 0; k < num/2; k++)
{
tmp = A[k];
A[k] = A[num-k-1];
A[num-k-1] = tmp;
}
}
(2).利用循环链表解法
typedef struct Node
{
int data;
struct Node *next;
} Node;
/**
* @功能约瑟夫环
* @参数 total:总人数
* @参数 from: 第一个报数的人
* @参数 count:出列者喊到的数
*/
void JOSEPHUS(int total, int from, int count)
{
// pcur为当前结点,pre为辅助结点,指向pcur的前驱结点,head为头节点
Node *pcur, *pre, *head;
head = NULL;
int i;
// 建立循环链表
for(i = 1; i <= total; i++)
{
pcur = (Node *)malloc(sizeof(Node));
pcur->data = i;
if(NULL ==head)
{
head = pcur;
}
else
{
pre->next = pcur;
}
pre = pcur;
}
pcur->next = head; // 尾节点连到头结点,使整个链表循环起来
pcur = head; // 使pcur指向头节点
// 把当前指针移动到第一个报数的人,即第k位的下一位
for(i = 1; i < from; i++)
{
pre = pcur;
pcur = pcur->next;
}
// 循环地删除队列结点,每隔m-1个结点删一个
while(pcur->next != pcur)
{
for(i = 1; i < count; i++)
{
pre = pcur;
pcur = pcur->next;
}
pre->next = pcur->next;
printf("delete number: %d\n", pcur->data);
free(pcur);
pcur = pre->next;
}
printf("The last number: %d\n", pcur->data);
}
(3).利用数学公式解法
设f(m,k,i)为m个人的环,报数为k,第i个人出环的编号,则f(10,3,10)是我们要的结果
当i=1时, f(m,k,i) = (m+k-1)%m(这里减1是因为从0开始计数)
当i!=1时, f(m,k,i)= ( f(m-1,k,i-1)+k )%m
int fun(int m,int k,int i)
{
if(1 == i)
{
return (m + k - 1) % m;
}
else
{
return (fun(m - 1, k, i - 1) + k) % m;
}
}
int main(int argc, char* argv[])
{
for(int i = 1; i <= 13; i++)
{
printf("第%d次出环:%d\n", i, fun(13, 3, i));
}
return 0;
}