前言
这是我的第一篇博客,内容便是最近所做的课程设计,之后也会每天和大家分享一下刷题笔记,以及AC后的代码,希望大家的批评指正,分享大家的一些观点和想法,希望和大家共同进步。
一、题目
1.数位之和
问题描述
给定一个十进制整数n,输出n的各位数字之和。
输入格式
输入一个整数n。
输出格式
输出一个整数,表示答案。
样例输入
20151220
样例输出
13
2.数字排序
问题描述
给定n个整数,请统计出每个整数出现的次数,按出现次数从多到少的顺序输出。
输入格式
输入的第一行包含一个整数n,表示给定数字的个数。
第二行包含n个整数,相邻的整数之间用一个空格分隔,表示所给定的整数。
(对于所有的n均满足0<=n<=1000)
输出格式
输出多行,每行包含两个整数,分别表示一个给定的整数和它出现的次数。按出现次数递减的顺序输出。如果两个整数出现的次数一样多,则先输出值较小的,然后输出值较大的。
样例输入
12
5 2 3 3 1 3 4 2 5 2 3 5
样例输出
3 4
2 3
5 3
1 1
4 1
3.字符串匹配
问题描述
给出一个字符串和多行文字,在这些文字中找到字符串出现的那些行。你的程序还需支持大小写敏感选项:当选项打开时,表示同一个字母的大写和小写看作不同的字符;当选项关闭时,表示同一个字母的大写和小写看作相同的字符。
输入格式
输入的第一行包含一个字符串S,由大小写英文字母组成。
第二行包含一个数字,表示大小写敏感的选项,当数字为0时表示大小写不敏感,当数字为1时表示大小写敏感。
第三行包含一个整数n,表示给出的文字的行数。
接下来n行,每行包含一个字符串,字符串由大小写英文字母组成,不含空格和其他字符。
输出格式
输出多行,每行包含一个字符串,按出现的顺序依次给出那些包含了字符串S的行。
样例输入
Hello
1
5
HelloWorld
HiHiHelloHiHi
GrepIsAGreatTool
HELLO
HELLOisNOTHello
样例输出
HelloWorld
HiHiHelloHiHi
HELLOisNOTHello
二、问题分析
1.数位之和
我们要解决这个问题,首先要得到各个数位上的数字,所以如果当输入的数字n为0时,直接输出0,即可,如果数字大于零,我们需要对它取模10获得最低位上的数字,然后把他累加进sum中,然后得把这个已经得到的数字“去掉”,也就是对数字n除10,并把n更新为该值,然后再对n取模10,把结果累加到sum中,直到n为0,循环结束,sum的值也就是数字n各数位数字之和。
2.数字排序
这个问题最让人头痛的是如何把出现次数记录下来后,还要根据它的出现次数多少来输出相应的数字和出现次数,如果仅仅输出出现次数最多的数字,大概大家很快便能想出办法:就是把每个数字的出现次数记录到一个数组中,然后找这个数组的最大值,然后根据找到的最大值对应数组元素的下标来找所对应的数字是多少。那我们这道题该怎么做?我们也可以先创建一个足够大的数组(本题数字均为0~1000的整数)来记录这些数字的出现次数, 初始化数组元素的值都是0,代表0~1000各个数字都出现了0次,然后每输入一个数,让该数组以这个数字为下标元素的值+1,代表该数字出现次数多了一次,直到用户输入所有数字为止,然后有的同学会想:直接把这个记录次数的数组排一下序,不就有了吗?但是排序之后这个数组最大值变成了第一个元素或者最后一个元素,而你并不知道这个元素对应的数字是多少(也就是说最大出现次数所对应的数你找不到了),所以我们可以每次找到一个最大出现次数的数,然后输出它和它对应的出现次数,然后(这一步比较关键)就是要把刚刚输出的这个数的出现次数更新为0,说明咱们已经输出过它了,在下一次寻找比他小的元素里面的最大值时就不会输出它了,然后我们依次地一个个输出最大、次大、等等直到输出最小的元素(这个方法可能有点笨,但这是鄙人能够想到的唯一方法了,如果大家有什么别的简便方法,欢迎大家在评论区讨论,我也希望能够学习到更高效的算法)。
3.字符串匹配
解决该问题的最主要问题是如何进行字符串的匹配,但是要解决该问题之前,得先让程序判断接下来的匹配操作是否大小写敏感,即设置一个条件判断语句,如果大小写敏感则直接可以进行字符串匹配,如果大小写不敏感则将目标字符串s和待匹配的字符串字母的大小写均统一,即将全部字母都转化为大写或都转化为小写,然后再进行字符串的匹配。字符匹配可以用目标字符串s的第一个字母和待匹配字符串第一个字母比较,若相等,则比较目标字符串第二个字母和待匹配字符串的第二个字母,依次类推,若发生“冲突”(即存在字母不相等),则将目标字符串首字母与待匹配字符串中字母的比较位置向右偏移一位,再进行逐个字母比较,直到比较位置偏移到(待匹配字符串长度-目标字符串长度+1)位置处为止,结束匹配。在匹配完成后,即可根据是否能成功匹配来输出符合条件的字符串,输出完毕,程序结束。
三、具体代码
1.数位之和
#include <iostream>
using namespace std;
int main()
{
int n;
int sum=0;
cin>>n;
while(n)
{ sum+=n%10;
n/=10;
}
cout<<sum;
return 0;
}
2.数字排序
#include <iostream>
using namespace std;
int main()
{ int n;
cin>>n;
int *a=new int[n];
int b[1001]={0}; //存放各个数字的出现次数
for(int i=0;i<n;i++)
{ cin>>a[i];
b[a[i]]++;
}
int max;//max代表当前数字中最大出现次数
int maxi;//maxi代表当前最大出现次数对应的数字
for(int i=0;i<n;i++)
{ max=b[0];
maxi=0;
for(int j=0;j<=1000;j++)
{ if(b[j]>max)
{max=b[j];
maxi=j;
}
}
if(max)//如果当前数字出现过,而且是目前所有数字中出现次数最多
cout<< maxi<<' '<<max<<endl;
b[maxi]=0;
}
return 0;
}
3.字符串匹配
#include <iostream>
#include <string>
using namespace std;
string lower(string x)//转为小写字母
{ for(int i=0;i<x.size();i++)
{if(x[i]>=65&&x[i]<=90)
x[i]+=32;
}
return x;
}
bool match(string y,string z)//字符串匹配
{
for(int i=0;i<z.size()-y.size()+1;i++)
{ int k=i;
int nn=0;//nn代表相等字母的个数
for(int j=0;j<y.size();j++)
{
if(y[j]==z[k++])
nn++;
}
if(nn==y.size())//如果都相等,则可匹配成功
return true;
}
return false;
}
int main()
{
string s;
cin>>s;
int num;
cin>>num;
int n;
cin>>n;
string *str=new string [n];
for(int i=0;i<n;i++)
cin>>str[i];
bool *flag=new bool[n];//记录各字符串是否可匹配成功
if(num)
{
for(int i=0;i<n;i++)
{ if(match(s,str[i]))
flag[i]=true;
else
flag[i]=false;
}
}
else
{for(int i=0;i<n;i++)
{ if(match(lower(s),lower(str[i])))
flag[i]=true;
else
flag[i]=false;
}
}
cout<<endl;
for(int i=0;i<n;i++)
if(flag[i])
cout<<str[i]<<endl;
return 0;
}
总结
由于还没有接触到过多的算法和数据结构的知识,以上三题均采用的是常规解法,即所说的暴力求解,在第三题的求解过程中,我了解到了KMP算法,但是由于本人并没有过多的去了解并使用,所以仍然使用常规法解决了第三题,而KMP算法的求解以及后续代码我将会在日后,学习并能独立写出KMP算法后来继续更新本题KMP算法的求解步骤,如果大家对上面这三道题,有别的一些好方法,也可以发出来,大家共同学习,共同进步。