注:字符串反转第二种做法以及括号匹配使用栈来解决均参考自该篇博客
第一题:求乘积
题目描述:
求积
给定n组数,每组两个整数,输出这两个整数的乘积
输入样例:
2
1 1
2 3
输出样例:
1
6
思想:建立n个数组,n为输入的值,每组输入两个数;再建立一个用以保存每次计算结果的数组,初始大小自定义;满足题目格式要求,先输入数字,再输出计算结果。单行输入容易实现,用一个循环或者递归即可;多行输入再多行输出,用数组保存结果,再遍历输出。
#include<iostream>
using namespace std;
int main()
{
int n; //可以认为是n个数组;
cin >> n;
int a,b,i; //a,b分别为每组输入的整数;
int num[10]; //该数组用以保存结果;
cout << "please input:";
for (i = 0; i < n; i++)
{
cin >> a >> b;
num[i] = a * b;
}
for (i = 0; i < n; i++)
{
cout << num[i]<<endl;
}
return 0;
}
第二题:求阶乘:
题目描述:给定n组数,每组一个整数,输出该组数的阶乘
思想:建立一个递归函数,该函数作用为求一个数字的阶乘,用递归来实现。
#include<iostream>
using namespace std;
int result = 1; //阶乘结果
void compute(int a) // 该子函数功能为计算一个数的阶乘;
{
if (a <= 0)
{
cout << result<<endl;
result = 1;
return;
}
result *= a;
a--;
compute(a);
}
int main()
{
int n,num;
cout << "input:";
cin >> n; //n控制循环,代表共有n组数据需要计算
if (n == 0)
{
cout << 0 << endl;
return 0;
}
for (int i = 0; i < n ; i++) //循环
{
cin >> num;
compute(num);
}
return 0;
}
本题看着不难,没想到一个小小的循环卡了半天。最后经过断点调试才找出问题,成功运行。唉,还是太菜。
第三题:全排列组合问题
求C(n,m),求出n个数中任取m个数的不同取法个数
注:C(n,m) = n!/(m! * (n - m)!)
通过所给提示可以看出,数的阶乘除以数的阶乘,表达式上下可约分化简,不同取法个数只能是整数值。直接暴力法,逐步计算表达式,该方法易实现,缺点是测试数据过大时,阶乘值可能过大,超出定义数据的范围。
#include<iostream>
using namespace std;
int result = 1;
int compute(int n) //该函数用以计算一个数的阶乘
{
int result2; //保存一个数的阶乘结果用以输出;
if (n == 0)
{
result2 = result;
result = 1; //对之前计算结果清1,不影响下次计算;
return result2;
}
result *= n;
n--;
compute(n);
}
int main()
{
int m, n;
cin >> n >> m;
int num1, num2, num3;
num1 = compute(n);
num2 = compute(m);
num3 = compute(n - m);
int result;
result = num1 / (num2 * num3);
cout << result << endl;
return 0;
}
第四题:排序
题目描述:
给定n组数,每组数有m个,对每一组数从小到大排序输出
使用快排来对数组进行递增排序;也可以直接调用sort()函数来实现一组数据的递增排序,单行输入,单行输出;额外再建立一个数组或直接建立二维数组可以实现多行输入多行输出。
关于变量定义数组大小,DEV-C++使用的编译器是GCC,它允许使用变量作为数组的长度定义数组;VC的编译器不是GCC,它不允许你这样做。
#include<iostream>
#include<vector>
using namespace std;
void quickSort(int array[], int start, int end) //快排,实现对一组数据进行排序;
{
if (start >= end) //start end分别代表数组的第一个和最后一个位置
return;
int i,j,b;
i = start;
j = end;
b = array[start];
while (i < j)
{
while (i < j && array[j] >= b)
j--;
if (i < j)
{
array[i] = array[j];
i++;
}// 从右向左找比基准数小的数
while (i < j && array[i] <= b)
i++;
if (i < j)
{
array[j] = array[i];
j--;
}// 从左向右找比基准数大的数
}//一趟快排结束
array[i] = b; //基准数放入适当位置
quickSort(array, start,j - 1); //递归调用
quickSort(array, i + 1, end);
}
int main()
{
int n,m;
cin >> n >> m;
if (n <= 0 || m <= 0)
return 0;
//vector<int> a(m);
int a[20]; //每组数据最大20个
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
cin >> a[j];
}
quickSort(a, 0, m - 1); //排序
for (int j = 0; j < m; j++)
cout << a[j]<<" ";
cout << endl; //格式化输出
}
return 0;
}
第五题:字符串反转
题目描述:
字符串反转
给定n组字符串,每组字符串不超过20
输出每组字符串的反串
输入样例:
3
nwpu
china
xi an
输出样例:
upwn
anihc
na ix
思想:1、建立一个字符数组,前后元素逐次交换即可。
#include<iostream>
using namespace std;
void exchange(char c[],int start,int end) //逐次交换字符数组前后元素
{
int i, j;
char temp;
i = start;
j = end;
while (i < j)
{
temp = c[i];
c[i] = c[j];
c[j] = temp;
i++, j--;
}
for (i = start; i <= end; i++) //方便起见,数组从开始计数
cout << c[i];
cout << endl;
}
int main()
{
int n,m,i = 1;
cout << "Please input the lines:";
cin >> n;
if (n <= 0)
{
return 0;
}
char c[20];
while (i <= n) //单行输入,单行输出
{
cin >> m;
for (int j = 1; j <= m; j++)
cin >> c[j];
exchange(c, 1, m);
i++;
}
return 0;
}
2、利用栈来实现多行输入多行输出,栈的一个很明显的特点就是先进后出;
#include <iostream>
using namespace std;
int main()
{
int n,top=0; //设置行数,栈顶指针
cout<<"please input the number of group:"<<endl;
cin>>n;
if(n<=0)
return 0;
char s[n][20]; //变量定义数组大小,vs2013中不可用;二维数组可实现多行输入多行输出;
for(int i=0;i<n;i++)
cin>>s[i];
char st[20];
for(int i=0,j=0;i<n;i++){
while(s[i][j]!='\0') //不为结束符,就循环
st[top++]=s[i][j++];//入栈
while(top>=0)
cout<<st[--top]; //出栈
cout<<endl;
top=0,j=0;//清空一行字符,便于下行字符数组操作
}
return 0;
}
第六题:判断回文数
题目描述:判断是否”回文“:
给定n组数,对每组字符串判断是否回文(从左往右看,从右往左看都一样,包括空格、英文、数字、符号)
若是输出Yes,否则输出No
输入样例:
4
nwpu
madam
1001
xi ix
输出样例:
No
Yes
Yes
Yes
思想:做法类似于字符串匹配问题,看前后对应字符是否相同,若相同则为回文数;否则便不是回文数。
具体实现:定义了一个判断是否为回文数的函数,主函数中用cin.getline()函数读入键盘输入的字符串;因为刚开始不懂cin.getline()函数,导致程序出错,在cin.getline()函数前写一句输入字符串函数,便解决问题。但还是出错,通过debug发现,第一组数据可以正确判断,但从第二组开始,第一个字符无法读取,导致程序出错。
scanf("%c", &c);
cin.getline(c,20); //获取当前输入字符串
m = strlen(c); //m为输入字符串长度
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<string>
using namespace std;
bool judge(char c[],int start,int end) //依次对比字符数组前后元素
{
int i = start, j = end, flag = 0; //
while (i <= j) //数组默认从第0位开始;
{
if (c[i] != c[j])
{
flag = 0;
return false;
}
else
flag = 1;;
i++, j--;
}
if (flag == 1)
return true;
}
int main()
{
int n,m;
cout << "Please input the lines:";
cin >> n;
char c[20] = {};
if (n <= 0)
{
return 0;
}
for(int i = 0;i < n;i++) //单行输入,单行输出
{
//scanf("%c", &c);
//getchar();
cin.sync();
cin.getline(c,20); //获取当前输入字符串;
m = strlen(c); //m为输入字符串长度
if (judge(c, 0, m - 1))
{
cout << "Yes" << endl;
}
else
cout << "No" << endl;
}
return 0;
}
第七题:括号匹配问题
题目描述:判断括号是否匹配:
给定n组数,每组为一个字符串,测试3种符号:{}、[]、(),且顺序只能是前左括号,后右括号,括号间可以嵌套。
若匹配则输出Yes,否则输出No
如:{@}a、{[()]}都是匹配的
{[[]}、{}{ 都不是匹配的
输入样例:
2
{a}b
{[(]}
输出样例:
Yes
No
思想:从键盘读入一个字符串进行判断,判断的方法为前后各设置一个指针,先从前扫描,若发现括号,则从后向前扫描到第一个与之匹配的括号;若找不见,则代表不匹配。(这是括号嵌套的情况,若括号不嵌套,而是并列的,则会导致判断错误)
//#include<iostream>
//#include<string>
//using namespace std;
//bool judge(char c[], int start, int end)//判断是否匹配
//{
// int i = start,j = end, temp = end;
// while (i < j) //保证在字符数组的范围内,前后指针相遇或相邻即退出循环,代表判断完毕
// {
// if (c[i] == '{') //大括号
// {
// for (j = temp; j > i; j--) //j代表从后向前查找,temp保存当前j的位置
// {
// if (c[j] == '}') //匹配成功
// {
// temp = j; //记录当前找到的位置,下次从此处开始向前寻找;
// i++; //从前向后递增一位
// break; //跳出本层循环,开始判断下次
// }
// else
// continue;
// }
// return false; // 循环结束,匹配不成功,直接终止子函数,返回结果
// }
// else if (c[i] == '[') //中括号
// {
// for (j = temp; j > i; j--)
// {
// if (c[j] == ']')
// {
// temp = j;
// i++;
// break;
// }
// }
// return false; //匹配不成功,直接终止子函数,返回结果
// }
// else if (c[i] == '(') //小括号
// {
// for (j = temp; j > i; j--)
// {
// if (c[j] == ')')
// {
// temp = j;
// i++;
// break;
// }
// }
// return false; //匹配不成功,直接终止子函数,返回结果
// }
// else
// i++;
// }
// return true;
//}
//int main()
//{
// int n,m;
// cout << "Please input the lines:";
// cin >> n;
// if (n <= 0) //行数为大于0的整数
// return 0;
// char c[20] = {};
// for (int i = 0; i < n; i++)
// {
// cin.sync();
// cin.clear();
// cin.getline(c, 20);
// m = strlen(c);
// if (judge(c, 0, m - 1))
// cout << "Yes" << endl;
// else
// cout << "No" << endl;
// }
// return 0;
//}
正确的方法:括号匹配问题用栈解决相对比较简单,可参考该篇博客
思想:利用栈的先进后出的思想,只将三种类型的括号入栈即可。
#include <iostream>
#include <string>
using namespace std;
int main()
{
int n;
cout << "please input the number of group:" << endl;
cin >> n;
if (n <= 0)
return 0;
char s[20][20]; //最多20行,每行最多20个字符,二维数组容易实现多行输入多行输出;
for (int i = 0; i <= n; i++)
cin.getline(s[i], 20);//获取键盘输入
for (int i = 1; i <= n; i++)
{
bool flag = true; //标志初始为true;
int len = strlen(s[i]);//每行数组的字符个数;
char st[20]; //建造栈;
int top = 0;
for (int j = 0; j < len; j++)
{
switch (s[i][j])
{
case '{':
case '[':
case '(':st[top++] = s[i][j];
break;//三种类型的括号进栈,其余字符不进栈;
case '}':
if (st[--top] != '{') //要进栈的和当前栈顶元素不匹配;
flag = false;
break;
case ']':
if (st[--top] != '[')
flag = false;
break;
case ')':
if (st[--top] != '(')
flag = false;
break;
}
}
if ((flag == true) && top == 0) //栈空且flag为true
cout << "yes" << endl;
else
cout << "no" << endl;
}
return 0;
}