C语言OJ题—xjtu大计基作业第九周
应某位同学的要求,对一些繁琐又乱的代码,写了一些算法的思路和注释,有什么好的想法和改正,大家评论区交流;
/*编写一个函数来判断一个正整数是否为回文数,若是则返回1,否则返回0。
所谓回文数是指各位数字左右对称的数,例如1221、3553等。该函数的原型为:
int ispalindrome(int n);
其中参数n是待判断的正整数,该函数有返回结果。
编写主函数,对上述函数进行测试,并找出1000∽n (包括1000和n,1000 ≤ n <10000)之间的所有回文数,
按从小到大的次序在屏幕上显示输出,每个数之间用一个空格分隔,最后一个数后面没有空格。*/
#include<stdio.h>
int main()
{
int n;//待判断的正整数;
int a, b, c, d;//分别储存个位、十位、百位、千位数;
scanf_s("%d", &n);
int flag = 1;//利用flag实现输出要求,最后一个数后面没有空格;
for (int i = 1000; i <= n; i++)
{
a = i / 1000;
b = i / 100 - a * 10;
d = i % 10;
c = (i % 100 - d) / 10;
if (a == d && b == c)
{
if (flag)
{
flag = 0;
}
else
{
printf(" ");
}
printf("%d", i);
}
}
return 0;
}
/*输入一个可能带空格字符的字符串(长度不超过200),统计其中各个英文字母的出现次数,不区分大小写。
输出字母a~z的出现次数,数据间以英文逗号分隔。非英文字母不统计。
输入:可能带空格的字符串。
输出:26个整数,以英文逗号分隔。*/
//算法分析:第一步:输入一个长度200的字符,再用一个整型数组用来记录字母a~z的出现次数;
//第二步:将字符中的小写字母全部转换成大写字母,因为不分大小写来统计;
//第三步:统计字符中所有的字符并统计后显示,根据输出要求,单独列出最后一下,保证输出要求;
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main()
{
char sz[200] = {0};
int n[26] = {0};
gets(sz);
//printf("%s\n", sz);用来检查第一步;
int i = 0;
while (sz[i] != 0)
{
if (sz[i] >= 'a' && sz[i] <= 'z')
sz[i] = sz[i] - 'a' + 'A';
i = i + 1;
}
//printf("%s\n", sz);检查第二步;
for(int i=0;sz[i]!='\0';i++)
switch (sz[i])//直接暴力枚举法也不是很繁琐;
{
case 'A':n[0]++; break;
case 'B':n[1]++; break;
case 'C':n[2]++; break;
case 'D':n[3]++; break;
case 'E':n[4]++; break;
case 'F':n[5]++; break;
case 'G':n[6]++; break;
case 'H':n[7]++; break;
case 'I':n[8]++; break;
case 'J':n[9]++; break;
case 'K':n[10]++; break;
case 'L':n[11]++; break;
case 'M':n[12]++; break;
case 'N':n[13]++; break;
case 'O':n[14]++; break;
case 'P':n[15]++; break;
case 'Q':n[16]++; break;
case 'R':n[17]++; break;
case 'S':n[18]++; break;
case 'T':n[19]++; break;
case 'U':n[20]++; break;
case 'V':n[21]++; break;
case 'W':n[22]++; break;
case 'X':n[23]++; break;
case 'Y':n[24]++; break;
case 'Z':n[25]++; break;
}
for (int i = 0; i <= 24; i++)
{
printf("%d,",n[i]);
}
printf("%d", n[25]);
return 0;
}
/*编写程序,要求在一个字符串中查找连续出现次数最多的一个字符,并显示其所在的开始下标和次数。
(如果出现最多的字符不止一个,输出最靠前的字符)
输入:一个字符串(字符个数不超过100,无空格)
输出:出现最多的字符,次数,开始下标(这三个值之间用空格分隔,末尾无空格)*/
//分治法:第一步:分别用一个整型数组来记录字符串每个字符出现的次数;
//第二步:知道数组中最大的数,即重复次数最多的数,并记录该数第一次出现的位置;
//输出该字符以及其对应整型数组中的数;再循环一次找到第一次出现的位置;
#include<stdio.h>
int main()
{
int k = 0, sum[100], d = 0;
int a=0;
char str[100];
scanf("%s", str);
for (int i = 0; str[i] != '\0'; i++)//字符串的每一个字符与整个字符串比较
{
for (int j = 0; str[j] != '\0'; j++)
{
if (str[j] == str[i])//如果找到相同的字符,K自加1
k++;
}
sum[i] = k;//把K的值存入SUM数组
k = 0;//把K清零,便于下次循环的计数
}
for (int i = 0; str[i] != '\0'; i++)//查找SUM数组中的最大值
{
if (sum[0] < sum[i])
{
sum[0] = sum[i];
d = i;//把最大值的位置复制给d
}
}
printf("%c %d ", str[d], sum[d]);//输出出现次数最多的字符以及出现的次数.
for (int i = 0; str[i] != str[d]; i++)
{
a = i+1;
}
printf("%d", a);
return 0;
}
/*闰年计算。程序输入一个正整数Y,以及另一个正整数N,以一个空格分隔。
计算从Y年开始后的第N个闰年是哪一年(如果Y本身是闰年,则Y之后的第一个闰年是Y)。
输入格式:两个整数:Y和N。用空格分隔
输出个数:一个整数*/
#include<stdio.h>
int main()
{
int y, n;
scanf_s("%d%d", &y, &n);
for (y; n >0; y++)
{
if ((y % 4 == 0 && y % 100 != 0) || y % 400 == 0)
n--;
}
printf("%d", y-1);
//system ("pause");
return 0;
}
/*编写程序,按下列规则倒序输出子字符串。先输出最后的一个字符,再输出最后两个字符串,
在再出后面三个字符..., 最后输出整个字符串。输入的字符串长度不超过100。
输入:一个字符串(无空格,字符个数不超过100)
输出:空格隔开的子字符串,用一个空格间隔。
输入输出样例:
student
t nt ent dent udent tudent student*/
//解释:这里给出一种不太优化的方法;当时写主要是为了强化记忆,写了好几个不必要的字符串函数,走了很多弯路;
//思路:将字符串逆序,然后分别用俩层循环,将前n个字符输出即可;
#include<stdio.h>
#include<string.h>
int mystrlen(char string[])
{
int len = 0;
while (string[len] != '\0')
len = len + 1;
return len;
}
int main()
{
char sz[100] = { 0 };
gets(sz);
int len = 0;
len = mystrlen(sz);
char sz2[100] = { 0 };
strcpy(sz2, strrev(sz));
for (int i = 0; i <len-1; i++)
{
for (int j = i; j >=0; j--)
{
printf("%c", sz2[j]);
}
printf(" ");
}
char sz3[100] = { 0 };
strcpy(sz3, strrev(sz));
printf("%s",sz3);
return 0;
}
/*单词加密。输入一个字符串和一个非负整数k,对字符串中的每一个字母,用字母表中其后的第k个字母代替,
不够k个时再从字母a循环计数。例如k=3是,a用d代替,A用D代替,x用a代替,y用b代替,保持大小写不变。
字符串中的非字母字符不变。字符串的长度不超过100。
输入:一个字符串(无空格)和非负整数k,之间用空格分隔
输出:加密的字符串。*/
//这里利用<ctybe.h>里面的判断大小写字母的函数;也可以用ASCII码位置定义同作用的函数;
//为了防止超出26个字母表,用一个%26,防止溢出;
#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>
int main()
{
char sz[100];
int a;
scanf("%s%d",sz,&a);
int i = 0;
int temp;
while (sz[i]!= '\0')
{
if (isupper(sz[i]))
{
sz[i] = (sz[i] - 'A' + a) % 26 + 'A';
}
else if (islower(sz[i]))
{
sz[i] = (sz[i] - 'a' + a) % 26 + 'a';
}
i = i + 1;
}
printf("%s", sz);
return 0;
}
/*编写程序,去掉字符串末尾多余的星号。输入带星号(*)的字符串和n,使字符串尾部的*号不得多于n个;
若多于n个,则删除多余的*号;若少于或等于n个,则什么也不做,字符串中间和前面的*号不删除。
字符串的长度不超过200。字符串中的星号是英文星号。
输入:一个字符串(无空格,字符串长度不超过100)和一个非负整数,中间用空格隔开。
输出:去掉多余*号的字符串。
样例:
***street**music**** 2
***street**music***/
//直接暴力解法;将n和字符串末尾的*比较;多余n,直接删掉多余的*即可;
#include<stdio.h>
#include<string.h>
int main()
{
char a[200];
int d;
scanf("%s %d", a, &d);
int l = strlen(a), m = 0, n = 0;
for (int i = 0; a[i] == '*'; i++, m++);//统计a开始*的个数,此行可以省去;
for (int i = l - 1; a[i] == '*'; i--, n++);//统计a末尾*的个数
if (n > d)
{
for (int i = 0; i <= l - n - 1 + d; i++)
printf("%c", a[i]);
}
else
{
puts(a);
}
return 0;
}
/*查找一个字符在字符串中出现的第一个位置并输出这个位置。位置从0开始。
输入:待查找的字符串(字符个数不超过100)和需要查找的字符,字符串中可能含有空格。(输入时,待查找的字符串与所需查找的字符用*号隔开)如:“待查找字符串*需要查找的字符”
输出:字符的位置(如有多个相同的字符,只查找第一个,如果没有输出-1。)*/
//我在这里,直接将题目要求输出的*和查找字符一起当做字符串输入;
//从字符串\0前面一个字符即为所查找的字符;
//直接循环找到其位置即可,为了避免字符串没有该字符导致的错误输出,循环体到d-1之前即可,不与本身比较;
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main()
{
char sz[102] = { 0 };
char a;
char b;
gets(sz);
char sz2[102];
//strcpy(sz2, strrev(sz));
int d = strlen(sz);
int i = 0;
int flag = 0;
int c = -1;
for(i=0;i<d-1;i++)
{
if (sz[i]==sz[d-1])
{
printf("%d",i);
goto quit;
}
else
{
flag= 1;
}
}
if (flag)
{
printf("%d", c);
}
quit:return 0;
}
/*统计选票。三个候选人分别是Li、Zhang和Wang, Li 的代号是1;Zhang的代号是2; Wang的代号是3。
依次输入代表得票人代号的数字(即投票),直到输入-1则投票结束。然后统计每个人的得票数和废票数。
不是-1,1,2,3的数字为废票(第1个数为废票数)。
输入:若干整数,最后一个数是-1。(输入的每个数之间有空格)
输出:四个整数,以空格隔开,代表三个人的Li、Zhang、Wang的得票数以及废票数(第1个数为废票数)。
输出格式:"%d %d %d %d\n"*/
#include<stdio.h>
int main()
{
int a = 0, m = -1, n = 0, o = 0, p = 0, q = 0;
do
{
scanf("%d", &a);
if (a >= 1 && a <= 3)
{
switch (a)
{
case 1:
n++;
break;
case 2:
o++;
break;
case 3:
p++;
break;
}
}
else
{
m++;
}
} while (a != -1);
printf("%d %d %d %d\n", n, o, p, m);
return 0;
}
/*输入一个字符串(长度不超过200,不包含空格,至少有1个字符),除首尾字符外,
将其余的字符按ascii码降序排列,然后输出。*/
//用冒泡排序算法写的;
//定义的函数为冒泡算法从大到小进行排序,后来在主函数也写了相同功能的循环;
#include<stdlib.h>
void bubble_sort(int arr[], int len)
{
int i, j, temp;
for (i = 0; i < len - 1; i++)
for (j = 0; j < len - 1 - i; j++)
if (arr[j] < arr[j + 1])
{
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
int main() {
char sz[200];
gets(sz);
int len = strlen(sz);
// bubble_sort(sz, len);
int i, j,temp;
for(i=1;i<len-1;i++)
for(j=1;j<len-2;j++)
if (sz[j] < sz[j + 1])
{
temp = sz[j];
sz[j] = sz[j + 1];
sz[j + 1] = temp;
}
puts(sz);
return 0;
}