【华为机试在线训练】Day 7
题目描述
请实现如下接口
/* 功能:四则运算
* 输入:strExpression:字符串格式的算术表达式,如: "3+2*{1+2*[-4/(8-6)+7]}"
* 返回:算术表达式的计算结果
*/
public static int calculate(String strExpression)
{
/* 请实现*/
return 0;
}
约束:
-
pucExpression字符串中的有效字符包括[‘0’-‘9’],‘+’,‘-’, ‘*’,‘/’ ,‘(’, ‘)’,‘[’, ‘]’,‘{’ ,‘}’。
-
pucExpression算术表达式的有效性由调用者保证;
输入描述:
输入一个算术表达式
输出描述:
得到计算结果
//先中缀转后缀再计算后缀表达式的值,需要注意的是对于‘-’为一元运算符的处理和数字//的位数做一个记录。当看到python只有一行代码时,吐了一口老血。。。
#include<iostream>
#include<string>
#include<vector>
#include<stack>
using namespace std;
int main() {
string s;
while (cin >> s) {
stack<char> opera;
vector<int> numcnt;//用来保存每个数字的位数,以保证计算后缀表达式时的正确性
string s1;//后缀表达式
//中缀表达式转后缀表达式
for (int i = 0;i<s.size();i++) {
if (s[i] >= '0'&&s[i] <= '9') {
int tmp = 0;
while (s[i] >= '0'&&s[i] <= '9') {
tmp++;
s1 += s[i];
i++;
}
i--;
numcnt.push_back(tmp);
}
else if (s[i] == '-' || s[i] == '+') {
if (s[i] == '-' && (s[i - 1] == '(' || s[i - 1] == '[' || s[i - 1] == '{'))
s1 += '0';
while (!opera.empty()&&(opera.top() == '*' || opera.top() == '/' || opera.top() == '+' || opera.top() == '-')) {
s1 += opera.top();
opera.pop();
}
opera.push(s[i]);
}
else if (s[i] == '*' || s[i] == '/') {
while (!opera.empty()&&(opera.top() == '*' || opera.top() == '/')) {
s1 += opera.top();
opera.pop();
}
opera.push(s[i]);
}
else if (s[i] == '(' || s[i] == '[' || s[i] == '{')
opera.push(s[i]);
else if (s[i] == ')') {
while (opera.top() != '(') {
s1 += opera.top();
opera.pop();
}
opera.pop();
}
else if (s[i] == ']') {
while (opera.top() != '[') {
s1 += opera.top();
opera.pop();
}
opera.pop();
}
else if (s[i] == '}') {
while (opera.top() != '{') {
s1 += opera.top();
opera.pop();
}
opera.pop();
}
else
cout << "Invalid input!" << endl;
}
while (!opera.empty()) {
s1 += opera.top();
opera.pop();
}
//计算后缀表达式的值
stack<int> nums;
int ind = 0;
for (int i = 0;i<s1.size();i++) {
if (s1[i] >= '0'&&s1[i] <= '9') {
int total = 0;
while (numcnt[ind]--)
total = 10 * total + (s1[i++] - '0');
i--;
nums.push(total);
ind++;
}
else {
int tmp1 = nums.top();
nums.pop();
int tmp2 = nums.top();
nums.pop();
if (s1[i] == '+')
nums.push(tmp2 + tmp1);
else if (s1[i] == '-')
nums.push(tmp2 - tmp1);
else if (s1[i] == '*')
nums.push(tmp2*tmp1);
else
nums.push(tmp2 / tmp1);
}
}
cout << nums.top() << endl;
}
}
参考:https://blog.csdn.net/shizheng163/article/details/50988023
题目描述
Levenshtein 距离,又称编辑距离,指的是两个字符串之间,由一个转换成另一个所需的最少编辑操作次数。许可的编辑操作包括将一个字符替换成另一个字符,插入一个字符,删除一个字符。编辑距离的算法是首先由俄国科学家Levenshtein提出的,故又叫Levenshtein Distance。
Ex:
字符串A:abcdefg
字符串B: abcdef
通过增加或是删掉字符”g”的方式达到目的。这两种方案都需要一次操作。把这个操作所需要的次数定义为两个字符串的距离。
要求:
给定任意两个字符串,写出一个算法计算它们的编辑距离。
请实现如下接口
/* 功能:计算两个字符串的距离
* 输入: 字符串A和字符串B
* 输出:无
* 返回:如果成功计算出字符串的距离,否则返回-1
*/
public static int calStringDistance (String charA, String charB)
{
return 0;
}
输入描述:
输入两个字符串
输出描述:
得到计算结果
//典型的动态规划优化编辑器问题
//参考博客 http://blog.csdn.net/shizheng163/article/details/50988023
#include<iostream>
#include <string>
#include <vector>
using namespace std;
int calStringDistance(string a,string b){
int n = (int)a.size(),m = (int)b.size();
vector<vector<int>>dp(n+1,vector<int>(m+1,0));
dp[0][0] = 0;//dp[x][y]代表将a字符串前x个字符修改成b字符串前y个字符
for (int i=1; i<=m; ++i) dp[0][i] = i;
for (int i=1; i<=n; ++i) dp[i][0] = i;
for (int i=1; i<=n; ++i) {
for (int j=1; j<=m; ++j) {
int one = dp[i-1][j] +1,two = dp[i][j-1]+1,three = dp[i-1][j-1];
if(a[i-1]!=b[j-1]) three+=1;
dp[i][j] = min(min(one,two),three);
}
}
return dp[n][m];
}
int main(){
string a,b;
while(cin>>a>>b)
cout<<calStringDistance(a, b)<<endl;
return 0;
}
题目描述
题目描述
把M个同样的苹果放在N个同样的盘子里,允许有的盘子空着不放,问共有多少种不同的分法?(用K表示)5,1,1和1,5,1 是同一种分法。
输入
每个用例包含二个整数M和N。0<=m<=10,1<=n<=10。
样例输入
7 3
样例输出
8
/**
* 计算放苹果方法数目
* 输入值非法时返回-1
* 1 <= m,n <= 10
* @param m 苹果数目
* @param n 盘子数目数
* @return 放置方法总数
*
*/
public static int count(int m, int n)
输入描述:
输入两个int整数
输出描述:
输出结果,int型
#include<iostream>
#include<cstdlib>
using namespace std;
int count1(int m,int n)
{
if(m==0 || n==1)
{
return 1;
}
if(m<n)
{
return count1(m,m);
}
else
{
return (count1(m,n-1)+count1(m-n,n));
}
}
int main()
{
int m;
int n;
while(cin>>m>>n)
{
cout<<count1(m,n)<<endl;
}
return 0;
}
/* 解题分析:
设f(m,n) 为m个苹果,n个盘子的放法数目,则先对n作讨论,
当n>m:必定有n-m个盘子永远空着,去掉它们对摆放苹果方法数目不产生影响。即if(n>m) f(m,n) = f(m,m)
当n<=m:不同的放法可以分成两类:
1、有至少一个盘子空着,即相当于f(m,n) = f(m,n-1);
2、所有盘子都有苹果,相当于可以从每个盘子中拿掉一个苹果,不影响不同放法的数目,即f(m,n) = f(m-n,n).
而总的放苹果的放法数目等于两者的和,即 f(m,n) =f(m,n-1)+f(m-n,n)
递归出口条件说明:
当n=1时,所有苹果都必须放在一个盘子里,所以返回1;
当没有苹果可放时,定义为1种放法;
递归的两条路,第一条n会逐渐减少,终会到达出口n==1;
第二条m会逐渐减少,因为n>m时,我们会return f(m,m) 所以终会到达出口m==0.
*/