常见算法锦集

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;
}


1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值