暴风影音 笔试题

主要是几道编程题:


1. 输入字符串,可能包含',' 或者数字,将这个字符串转换为整数

例如:输入123,345

输出: 123345

输入:,

输出:-1(错误码)


输入: 123,

输出:-1(错误码)


// xunlei1.cpp : 定义控制台应用程序的入口点。
//

#include "stdio.h"
#include "stdlib.h"
#include "iostream"

using namespace std;
int convert(char * str);

int main(int argc, char* argv[])
{
	char str[20];
	scanf("%s", str);
	//printf("%s", str);

	int result = convert(str);
	printf("%d", result);

	system("pause");
	return 0;
}

int convert(char * str)
{
	char * p = str;
	char * pre;
	int number = 0;
	while(*p != '\0')
	{
		if(*p != ',')
		{
			int temp = *p - '0';
			number = number * 10 + temp;
		}
		pre = p;
		p++;

		
	}
	if(*pre == ',') // 最后为','
		return -1;
	return number;
}

2.  给定一个 n * n 的网格,假设从网格的左上方开始走,每次只能向下或者向右,走到最右下方停止,问一共有多少种走法。

假设:2*2的网格,一共有6种走法。

3*3的网格,一共有20种走法。


据说,有通项公式,相当于高中的排列组合的解法,但是我排列组合都忘了。。。还是用深度优先搜索吧。。。

因为只能向下走或者向右走,所以向下走或者向右走的最大的次数只能是n,中间搜过的过程中,可能需要进行简单的搜索剪枝。


// xunlei2.cpp : 定义控制台应用程序的入口点。
//
#include "stdio.h"
#include "stdlib.h"
#include "iostream"

using namespace std;

void DFS(int down, int right, int n, int & total);


int main(int argc, char * argv[])
{
	int n = 3;
	int total = 0;
	DFS(0,0,n,total);

	printf("%d\n", total);

	system("pause");
	return 0;
}

void DFS(int down, int right, int n, int & total)
{
	if(down == n && right == n)
	{
		// 搜索达到终点
		return;
	}
	if(down == n || right == n)
	{
		// 向下或者向右到达边界
		// 可以直接进行剪枝
		total++;
		return;
	}
	if(down < n)
	{
		// 因为没有修改本函数的变量,不需要进行恢复操作
		DFS(down + 1, right, n, total);
	}
	if(right < n)
	{
		DFS(down, right + 1, n, total);
	}
}


3.  给出一个二叉树的前序遍历结果和中序遍历结果,输出后续遍历结果


例如:

前序:ABDEHCFG

中序:DBEHAFCG

后续:DHEBFGCA


我在最初做题的时候,根据将中序遍历的结果进行二分查找构造了一颗二叉树,其实完全不需要,只需要访问到叶子节点或者递归返回的时候将当前层的节点保存以前,作为后续遍历的结果。


// xunlei3.cpp : 定义控制台应用程序的入口点。
//

#include "stdio.h"
#include "stdlib.h"
#include "iostream"
#include "vector"

using namespace std;

void Traverse(char * ps, char * pn, char * &p);

vector<char> post;


int main(int argc, char * argv[])
{
	char * preOrder = "ABDEHCFG";
	char * inOrder = "DBEHAFCG";

	char * ps = inOrder;
	char * pn;

	char * temp = inOrder;
	while(*temp != '\0')
	{
		pn = temp;
		temp++;
	}

	Traverse(ps, pn, preOrder);
	for(int i = 0; i < post.size(); i++)
		printf("%3c", post[i]);
	printf("\n");

	system("pause");
	return 0;
}


void Traverse(char * ps, char * pn, char * &p)
{
	if(pn < ps)
	{	
		// 没有左子树的情况
		return;
	}

	if(ps > pn)
	{
		// 没有右子树
		return;
	}

	char node = *p;
	if(ps == pn)
	{
		// 遍历到叶子节点,相当于左右子树都为空
		post.push_back(node);
		return;
	}

	char * pc = ps;
	while(*pc != *p)
	{
		pc++;
	}


	if(pc > ps)
	{
		// pc == ps的情况下,当前节点没有左子树,所以不用递归遍历
		p++;
		Traverse(ps, pc - 1, p);
	}

	if(pc < pn)
	{
		p++;
		Traverse(pc + 1, pn, p);
	}
	// 递归返回
	post.push_back(node);
}

上面代码测试了两个测试用例,应该没有问题。


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值